[
  {
    "path": ".idea/SimpletourDevops.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"PYTHON_MODULE\" version=\"4\">\n  <component name=\"NewModuleRootManager\">\n    <content url=\"file://$MODULE_DIR$\" />\n    <orderEntry type=\"jdk\" jdkName=\"Python 2.7.6 (C:\\Python27\\python.exe)\" jdkType=\"Python SDK\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n    <orderEntry type=\"module\" module-name=\"docker_module\" />\n    <orderEntry type=\"module\" module-name=\"zxpython\" />\n  </component>\n</module>"
  },
  {
    "path": ".idea/inspectionProfiles/Project_Default.xml",
    "content": "<component name=\"InspectionProjectProfileManager\">\n  <profile version=\"1.0\">\n    <option name=\"myName\" value=\"Project Default\" />\n    <inspection_tool class=\"PyPackageRequirementsInspection\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n      <option name=\"ignoredPackages\">\n        <value>\n          <list size=\"9\">\n            <item index=\"0\" class=\"java.lang.String\" itemvalue=\"django\" />\n            <item index=\"1\" class=\"java.lang.String\" itemvalue=\"django-celery-email\" />\n            <item index=\"2\" class=\"java.lang.String\" itemvalue=\"django-suit\" />\n            <item index=\"3\" class=\"java.lang.String\" itemvalue=\"django-import-export\" />\n            <item index=\"4\" class=\"java.lang.String\" itemvalue=\"itsdangerous\" />\n            <item index=\"5\" class=\"java.lang.String\" itemvalue=\"v2-vertical\" />\n            <item index=\"6\" class=\"java.lang.String\" itemvalue=\"uwsgi\" />\n            <item index=\"7\" class=\"java.lang.String\" itemvalue=\"supervisor\" />\n            <item index=\"8\" class=\"java.lang.String\" itemvalue=\"eventlet\" />\n          </list>\n        </value>\n      </option>\n    </inspection_tool>\n  </profile>\n</component>"
  },
  {
    "path": ".idea/inspectionProfiles/profiles_settings.xml",
    "content": "<component name=\"InspectionProjectProfileManager\">\n  <settings>\n    <option name=\"PROJECT_PROFILE\" value=\"Project Default\" />\n    <option name=\"USE_PROJECT_PROFILE\" value=\"true\" />\n    <version value=\"1.0\" />\n  </settings>\n</component>"
  },
  {
    "path": ".idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectLevelVcsManager\" settingsEditedManually=\"false\">\n    <OptionsSetting value=\"true\" id=\"Add\" />\n    <OptionsSetting value=\"true\" id=\"Remove\" />\n    <OptionsSetting value=\"true\" id=\"Checkout\" />\n    <OptionsSetting value=\"true\" id=\"Update\" />\n    <OptionsSetting value=\"true\" id=\"Status\" />\n    <OptionsSetting value=\"true\" id=\"Edit\" />\n    <ConfirmationsSetting value=\"0\" id=\"Add\" />\n    <ConfirmationsSetting value=\"0\" id=\"Remove\" />\n  </component>\n  <component name=\"ProjectRootManager\" version=\"2\" project-jdk-name=\"Python 2.7.6 (C:\\Python27\\python.exe)\" project-jdk-type=\"Python SDK\" />\n  <component name=\"masterDetails\">\n    <states>\n      <state key=\"ScopeChooserConfigurable.UI\">\n        <settings>\n          <splitter-proportions>\n            <option name=\"proportions\">\n              <list>\n                <option value=\"0.2\" />\n              </list>\n            </option>\n          </splitter-proportions>\n        </settings>\n      </state>\n    </states>\n  </component>\n</project>"
  },
  {
    "path": ".idea/modules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n      <module fileurl=\"file://$PROJECT_DIR$/.idea/SimpletourDevops.iml\" filepath=\"$PROJECT_DIR$/.idea/SimpletourDevops.iml\" />\n      <module fileurl=\"file://D:/简途运维平台/docker_module/.idea/docker_module.iml\" filepath=\"D:/简途运维平台/docker_module/.idea/docker_module.iml\" />\n      <module fileurl=\"file://D:/zxpython/.idea/zxpython.iml\" filepath=\"D:/zxpython/.idea/zxpython.iml\" />\n    </modules>\n  </component>\n</project>"
  },
  {
    "path": ".idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"\" vcs=\"Git\" />\n    <mapping directory=\"$PROJECT_DIR$\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "Publicapi/__init__.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\n"
  },
  {
    "path": "Publicapi/dnspod/__init__.py",
    "content": ""
  },
  {
    "path": "Publicapi/dnspod/apicn.py",
    "content": "#!/usr/bin/env python\n#-*- coding:utf-8 -*-\n\nimport httplib, urllib\ntry: import json\nexcept: import simplejson as json\nimport socket\nimport re\n\n\nclass ApiCn:\n    def __init__(self, email, password, **kw):\n        self.base_url = \"dnsapi.cn\"\n        \n        self.params = dict(\n            login_email=email,\n            login_password=password,\n            format=\"json\",\n        )\n        self.params.update(kw)\n        self.path = None\n    \n    def request(self, **kw):\n        self.params.update(kw)\n        if not self.path:\n            \"\"\"Class UserInfo will auto request path /User.Info.\"\"\"\n            name = re.sub(r'([A-Z])', r'.\\1', self.__class__.__name__)\n            self.path = \"/\" + name[1:]\n        conn = httplib.HTTPSConnection(self.base_url)\n        headers = {\"Content-type\": \"application/x-www-form-urlencoded\", \"Accept\": \"text/json\", \"User-Agent\": \"dnspod-python/0.01 (im@chuangbo.li; DNSPod.CN API v2.8)\"}\n        conn.request(\"POST\", self.path, urllib.urlencode(self.params), headers)\n        \n        response = conn.getresponse()\n        data = response.read()\n        conn.close()\n        ret = json.loads(data)\n        if ret.get(\"status\", {}).get(\"code\") == \"1\":\n            return ret\n        else:\n            raise Exception(ret)\n    \n    __call__ = request\n    \nclass InfoVersion(ApiCn):\n    pass\n\nclass UserDetail(ApiCn):\n    pass\n\nclass UserInfo(ApiCn):\n    pass\n\nclass UserLog(ApiCn):\n    pass\n\nclass DomainCreate(ApiCn):\n    def __init__(self, domain, **kw):\n        kw.update(dict(domain=domain))\n        ApiCn.__init__(self, **kw)\n\nclass DomainId(ApiCn):\n    def __init__(self, domain, **kw):\n        kw.update(dict(domain=domain))\n        ApiCn.__init__(self, **kw)\n\nclass DomainList(ApiCn):\n    pass\n\nclass _DomainApiBase(ApiCn):\n    def __init__(self, domain_id, **kw):\n        kw.update(dict(domain_id=domain_id))\n        ApiCn.__init__(self, **kw)\n\nclass DomainRemove(_DomainApiBase):\n    pass\n        \nclass DomainStatus(_DomainApiBase):\n    def __init__(self, status, **kw):\n        kw.update(dict(status=status))\n        _DomainApiBase.__init__(self, **kw)\n        \nclass DomainInfo(_DomainApiBase):\n    pass\n        \nclass DomainLog(_DomainApiBase):\n    pass\n\nclass RecordType(ApiCn):\n    def __init__(self, domain_grade, **kw):\n        kw.update(dict(domain_grade=domain_grade))\n        ApiCn.__init__(self, **kw)\n        \nclass RecordLine(ApiCn):\n    def __init__(self, domain_grade, **kw):\n        kw.update(dict(domain_grade=domain_grade))\n        ApiCn.__init__(self, **kw)\n\nclass RecordCreate(_DomainApiBase):\n    def __init__(self, sub_domain, record_type, record_line, value, ttl, mx=None, **kw):\n        kw.update(dict(\n            sub_domain=sub_domain,\n            record_type=record_type,\n            record_line=record_line,\n            value=value,\n            ttl=ttl,\n        ))\n        if mx:\n            kw.update(dict(mx=mx))\n        _DomainApiBase.__init__(self, **kw)\n\nclass RecordModify(RecordCreate):\n    def __init__(self, record_id, **kw):\n        kw.update(dict(record_id=record_id))\n        RecordCreate.__init__(self, **kw)\n \nclass RecordList(_DomainApiBase):\n    pass\n\nclass _RecordBase(_DomainApiBase):\n    def __init__(self, record_id, **kw):\n        kw.update(dict(record_id=record_id))\n        _DomainApiBase.__init__(self, **kw)\n\nclass RecordRemove(_RecordBase):\n    pass\n\nclass RecordDdns(_DomainApiBase):\n    def __init__(self, record_id, sub_domain, record_line, **kw):\n        kw.update(dict(\n            record_id=record_id,\n            sub_domain=sub_domain,\n            record_type=record_type,\n            record_line=record_line,\n        ))\n        _DomainApiBase.__init__(self, **kw)\n\nclass RecordStatus(_RecordBase):\n    def __init__(self, status, **kw):\n        kw.update(dict(status=status))\n        _RecordBase.__init__(self, **kw)\n\nclass RecordInfo(_RecordBase):\n    pass"
  },
  {
    "path": "Publicapi/dockerapi/Manager.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\n\nimport docker\n\n\n'''\nDocker 容器API公共模块，可进行容器及镜像管理\n'''\n\nclass Dockerapi(object):\n    def __init__(self, host, port):\n        self.dockerConnect = docker.Client(base_url='tcp://%s:%s' %(host,port), timeout=60, version='1.22')\n\n    def GetallContainers(self):\n        Containers = self.dockerConnect.containers(all=1)\n        return Containers\n\n    def SearchContainers(self, Searchparameter):\n        SearchContainer = self.dockerConnect.containers(all=1,filters={'name':[Searchparameter]})\n        return SearchContainer\n\n    def ContainerStatus(self, Status):\n        StatusContainer = self.dockerConnect.containers(all=1,filters={'status':[Status]})\n        return StatusContainer\n\n    def InspectContainer(self,name):\n        inspect = self.dockerConnect.inspect_container(container=name)\n        return inspect\n\n\n    def Dockerversion(self):\n        Version = self.dockerConnect.version()\n        return Version\n\n    def StartContainer(self, name):\n        StartContainer = self.dockerConnect.start(container=name)\n        return StartContainer\n\n    def StopContainer(self, name):\n        StopContainer = self.dockerConnect.stop(container=name)\n        return StopContainer\n\n    def DelayedstopContainer(self, name, timeout):\n        delayedstop = self.dockerConnect.stop(container=name, timeout=timeout)\n        return delayedstop\n\n    def Dockerinfo(self):\n        dockerinfo = self.dockerConnect.info()\n        return dockerinfo\n\n    def RestartContainer(self, name):\n        restart = self.dockerConnect.restart(container=name)\n        return restart\n\n    def DelayedRestart(self, name, timeout):\n        delayedrestart = self.dockerConnect.restart(container=name, timeout=timeout)\n        return delayedrestart\n\n    def RenameDocker(self, name, newname):\n        rename = self.dockerConnect.rename(container=name, name=newname)\n        return rename\n\n    def TopContainer(self, name):\n        topinfo = self.dockerConnect.top(container=name, ps_args=aux)\n        return topinfo\n\n    def killContainer(self, name):\n        kill = self.dockerConnect.kill(container=name)\n        return kill\n\n    def PauseContainer(self, name):\n        pause = self.dockerConnect.pause(container=name)\n        return pause\n\n    def UnpauseContainer(self, name):\n        unpause = self.dockerConnect.unpause(container=name)\n        return unpause\n\n    def removeContainer(self, name, v=False, link=False, force=False):\n        remove = self.dockerConnect.remove_container(container=name, v=v, link=link, force=force)\n        return remove\n\n    def LogContainer(self,name,timestamps=False,tail=all):\n\n        logs = self.dockerConnect.logs(container=name,stdout=True,stderr=True,timestamps=timestamps,tail=tail)\n\n        return logs\n\n\n    def AllImages(self):\n        images=self.dockerConnect.images(all=1)\n        return images\n\n    def DeleteImages(self,imagename):\n\n        data=self.dockerConnect.remove_image(image=imagename,force=False)\n\n        return u\"删除镜像成功!!\"\n\n\n\nif __name__ == '__main__':\n    test=Dockerapi('192.168.2.232','2375')\n    #a=test.DeleteImages('docker.io/centos/v1:latest')\n    #print a\n\n    # search=test.SearchContainers('simpletou')\n    # status=test.ContainerStatus('exited')\n    # version=test.Dockerversion()\n    # stop=test.StopContainer('nostalgic_albattani')\n    #tart=test.StartContainer('nostalgic_albattani')\n    #stopd=test.DelayedstopContainer('nostalgic_albattani',10)\n    #print stopd\n    #rename=test.RenameDocker('nostalgic_albattani','aaa')\n    #inspect = test.InspectContainer('aaa')\n    #print all\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Publicapi/dockerapi/__init__.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\n"
  },
  {
    "path": "Publicapi/saltstackapi/Assets_Module.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\n\nclass ServerBaseInfo(object):\n    def __init__(self,data,minion):\n        self.ServerHardInfo = {}\n        self.serverbaseinfo={}\n        self.data = data\n        self.minion = minion\n        self.serverbaseinfo['sn'] = self.data[self.minion]['serialnumber']\n        self.serverbaseinfo['hostname'] = self.data[self.minion]['nodename']\n        self.serverbaseinfo['cpu_count'] = self.data[self.minion]['CPU_COUNT']\n        self.serverbaseinfo['cpu_core_count'] = self.data[self.minion]['CPU_Info']['cpu processor']\n        self.serverbaseinfo['saltid'] = self.data[self.minion]['id']\n        self.serverbaseinfo['mem'] = self.data[self.minion]['Mem_Total']\n        self.serverbaseinfo['swap'] = self.data[self.minion]['Swap_Total']\n        self.serverbaseinfo['platform'] = self.data[self.minion]['osarch']\n        self.serverbaseinfo['system'] = self.data[self.minion]['oscodename']\n        self.serverbaseinfo['version'] = self.data[self.minion]['osrelease']\n        self.ServerHardInfo['Serverbaseinfo']=self.serverbaseinfo\nclass ServerCPUInfo(ServerBaseInfo):\n    def __init__(self,data,minion):\n        super(ServerCPUInfo,self).__init__(data,minion)\n\n    def ServerCPU(self):\n        servercpuinfo ={}\n        servercpuinfo['uuid'] = self.data[self.minion]['cpu_uuid']\n        servercpuinfo['parent_sn'] = self.data[self.minion]['serialnumber']\n        servercpuinfo['architecture'] = self.data[self.minion]['cpuarch']\n        servercpuinfo['model'] = self.data[self.minion]['cpu_model']\n        servercpuinfo['cpu_mhz'] = self.data[self.minion]['cpu MHz']\n        servercpuinfo['L1cache'] = self.data[self.minion]['CPU_Info']['L1 cache']\n        servercpuinfo['L2cache'] = self.data[self.minion]['CPU_Info']['L2 cache']\n        servercpuinfo['L3cache'] = self.data[self.minion]['CPU_Info']['L3 cache']\n        servercpuinfo['thread'] = self.data[self.minion]['CPU_Info']['cpu processor']\n        self.ServerHardInfo['servercpuinfo'] =  servercpuinfo\n        return self.ServerHardInfo\n\nclass ServerNICInfo(ServerBaseInfo):\n    def __init__(self,data,minion):\n        super(ServerNICInfo,self).__init__(data,minion)\n\n    def ServerNIC(self):\n        servernicinfo={}\n        servernicinfo['nicinfo'] = self.data[self.minion]['nicinfo']\n        self.ServerHardInfo['servernicinfo'] = servernicinfo\n        return self.ServerHardInfo\nclass ServerDiskInfo(ServerBaseInfo):\n    def __init__(self,data,minion):\n        super(ServerDiskInfo,self).__init__(data,minion)\n\n    def ServerDISK(self):\n        serverdiskinfo={}\n        serverdiskinfo['diskinfo'] = self.data[self.minion]['disk']\n        self.ServerHardInfo['serverdiskinfo'] = serverdiskinfo\n        return self.ServerHardInfo\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Publicapi/saltstackapi/SaltConApi.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\nimport urllib,urllib2\nimport json\nimport requests\nimport yaml\nfrom Assets_Module import ServerBaseInfo,ServerCPUInfo,ServerNICInfo,ServerDiskInfo\n\n\nclass SaltApi(object):\n    __token = ''\n    def __init__(self,url,user,password):\n\n        self.__url = url.rstrip('/')\n        self.__user= user\n        self.__pass = password\n        params = {'eauth': 'pam','username':self.__user,'password': self.__pass}\n        req = requests.post(url+'/login', data=params,allow_redirects=False)\n        try:\n            self.__token = req.headers['x-auth-token']\n        except KeyError:\n            raise KeyError\n\n    def PostRequest(self,obj,parurl='/'):\n        url = self.__url + parurl\n        headers = {'X-Auth-Token': self.__token,'Accept': 'application/json'}\n        req = requests.post(url, data=obj, headers=headers,verify=False)\n        content = req.json()\n        return content\n\n\n    def grains(self,tgt,args):\n        params={'client':'local','tgt': tgt, 'fun': 'grains.item','arg': args}\n        content = self.PostRequest(params)\n        ret = content['return'][0]\n        return ret\n\n    def grainsall(self,tgt):\n        params={'client':'local','tgt': tgt, 'fun': 'grains.items'}\n        content = self.PostRequest(params)\n        ret = content['return'][0]\n        return ret\n\n    def pillarall(self,tgt):\n        params = {'client': 'local', 'tgt': tgt, 'fun': 'pillar.items'}\n        content = self.PostRequest(params)\n        ret = content['return'][0]\n        return ret\n\n\n    def List_all_keys(self):\n        params={'client':'wheel', 'fun':'key.list_all'}\n        content=self.PostRequest(params)\n        minions = content['return'][0]['data']['return']['minions']\n        minions_pre = content['return'][0]['data']['return']['minions_pre']\n        minions_rej = content['return'][0]['data']['return']['minions_rejected']\n        minions_deny = content['return'][0]['data']['return']['minions_denied']\n        return minions, minions_pre, minions_rej, minions_deny\n\n\n    def shell_remote_execution(self,tgt,arg):\n        ''' Shell command execution with parameters '''\n        params = {'client': 'local_async', 'tgt': tgt, 'fun': 'cmd.run', 'arg': arg, 'expr_form': 'list'}\n        content = self.PostRequest(params)\n        jid = content['return'][0]['jid']\n        return jid\n\n\n    def Softwarete_deploy(self,tgt,arg):\n        '''执行salt.sls 远程部署程序'''\n\n        params = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls','arg':arg, 'expr_form': 'list'}\n        content = self.PostRequest(params)\n        jid = content['return'][0]['jid']\n        return jid\n\n\n\n    '''saltstack key管理 action需要进行传入，方法有,accept,delete,reject'''\n    def actionKeys(self,keystrings,action):\n        func = 'key.' + action\n        params = {'client': 'wheel', 'fun': func, 'match': keystrings}\n        content = self.PostRequest(params)\n        ret = content['return'][0]['data']['success']\n        return ret\n\n\n    '''saltstack key 批量管理传入值必须为一个字典'''\n\n    def dictActionKeys(self,keydict,action):\n        func = 'key.' + action + '_dict'\n        params = {'client':'wheel','fun':func,'match':keydict}\n        content = self.PostRequest(params)\n        return content['return'][0]\n\n    def cpFiletoMinions(self,tgt):\n        params={'client':'local','tgt': tgt, 'fun': 'cp.get'}\n        content = self.PostRequest(params)\n        ret = content['return'][0]\n        return ret\n\n    #获取JOB ID的详细执行结果\n    def runner(self,arg):\n        ''' Return minion status '''\n        params = {'client': 'runner', 'fun': arg }\n        content = self.PostRequest(params)\n        jid = content['return'][0]\n        return jid\n\n    def salt_runner(self, jid):\n        '''\n        通过jid获取执行结果\n        '''\n\n        params = {'client': 'runner', 'fun': 'jobs.lookup_jid', 'jid': jid}\n        print params\n        content = self.PostRequest(params)\n        print content\n        return content['return'][0]\n\n\n    #获取events\n    def SaltEvents(self):\n        parurl = '/events'\n        res = self.PostRequest(None,parurl)\n        return res\n\n    #接受KEY\n    def AcceptKey(self, key_id):\n        params = {'client': 'wheel', 'fun': 'key.accept', 'match': key_id, 'include_rejected': True, 'include_denied': True}\n        content = self.PostRequest(params)\n        ret = content['return'][0]['data']['success']\n        return ret\n\n    #删除KEY\n    def DeleteKey(self, key_id):\n        params = {'client': 'wheel', 'fun': 'key.delete', 'match': key_id}\n        content = self.PostRequest(params)\n        ret = content['return'][0]['data']['success']\n        return ret\n\n    # 拒绝KEY\n    def RejectKey(self, key_id):\n        params = {'client': 'wheel', 'fun': 'key.reject', 'match': key_id,  'include_accepted': True, 'include_denied': True}\n        content = self.PostRequest(params)\n        ret = content['return'][0]['data']['success']\n        return ret\n\n    def Saltalive(self,tgt):\n        '''\n        salt主机存活检测\n        '''\n\n        params = {'client': 'local', 'tgt': tgt, 'fun': 'test.ping'}\n        content = self.PostRequest(params)\n        return content['return'][0]\n\n\n\ndef format(data):\n    print data\n\n\nif __name__ == '__main__':\n    salt=SaltApi('http://192.168.2.150:8000','roddy','roudy_123456')\n    #a=salt.Softwarete_deploy('192.168.2.147,',arg=['saltenv=\"prod\"','nginx.install,zabbix-client.install','test=True'])\n\n    #a=salt.Softwarete_deploy('192.168.2.147',kwarg={'mods':'redis.install,nginx.install','test':True,'saltenv':'prod'})\n    #print a\n    #a = salt.SaltRun('192.168.2.147','state.sls','nginx.install,redis.install',saltenv='prod','test=True')\n    #data=salt.Saltalive('192.168.2.147')\n    #print data\n    #host='192.168.2.147,192.168.2.148,'\n    #data=salt.shell_remote_execution(host, 'df -i')\n    #print data\n    data = salt.salt_runner(20161215192828817118)\n    print data\n    format(data)\n\n\n    #print salt.SaltRun(client='runner', fun='fileserver.envs')\n    #a=sorted(salt.SaltRun(client='runner',fun='fileserver.envs')['return'][0])\n    #print a\n    #jids = salt.runner(\"jobs.list_jobs\")\n    #print jids\n    #for i,v in jids.items:\n    #    print i,v\n    #a,b,c,d =salt.List_all_keys()\n    #print a,b,c,d\n    #salt.shell_remote_execution\n\n    #funs = ['doc.runner', 'doc.wheel', 'doc.execution']\n    #for fun in funs:\n    #    result = salt.SaltRun(fun=fun, client='runner')\n    #    cs = result['return'][0]\n    #    for c in cs:\n    #        print fun.split('.')[1], c.split('.')[0]\n\n    #server=ServerDiskInfo(data, u'192.168.2.147')\n    #server=ServerCPUInfo(data,u'192.168.2.147')\n    #print server.ServerCPU()\n\n    #data=salt.grainsall('192.168.2.147')\n    #print data\n     #clientkey=salt.List_all_keys()['minions']\n#    Servers={}\n#    for i in clientkey:\n#        data=salt.grainsall(i)\n#        server=ServerNICInfo(data,i)\n#        serverinfo=server.ServerNIC()\n#        print serverinfo\n\n\n\n\n\n\n"
  },
  {
    "path": "Publicapi/saltstackapi/__init__.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\n"
  },
  {
    "path": "README.md",
    "content": "# SimpletourDevops\ndjango+python+celery+saltstack+docker实现的运维管理后台\n\n作者QQ：923401910\n\nv1.0：完成资产信息录入及使用saltstack自动采集更新\n      完成单机版docker主机的基本管理，日志实时刷新\n##部署步骤\n* 安装环境\n```\npip install requirements.txt\n```\n\n* 安装nginx\n  ```\n     yum install nginx -y\n  ```\n\n* 安装saltstack\n  ```\n     yum install salt-master -y\n     yum install salt-minion -y\n  ```\n* 配置docker\n  ```\n     [root@localhost ~]# vim /etc/sysconfig/docker\n\n     # /etc/sysconfig/docker\n\n     # Modify these options if you want to change the way the docker daemon runs\n     OPTIONS='--selinux-enabled -H 0.0.0.0:2375 -H unix:///var/run/docker.sock '\n     DOCKER_CERT_PATH=/etc/docker\n  ```\n* 部署流程\n以下为部署流程\n 修改 settings.py中db连接\n ```\n DATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.mysql',\n        'NAME': 'SimpletourDevops',\n        'HOST': '192.168.2.232',\n        'USER': 'root',\n        'PORT': 3306,\n        'PASSWORD': 'redhat',\n        'OPTIONS': {\n            'init_command': 'SET storage_engine=INNODB',\n        },\n    }\n}\n ```\n\n\n 部署程序到/data\n\n  ```\n    [root@localhost ~]# mv /root/SimpletourDevops /data/\n    [root@localhost ~]# cd /data/SimpletourDevops\n    [root@localhost SimpletourDevops]#python manage.py  makemigrations\n    [root@localhost SimpletourDevops]#python manage.py  migrate\n  ```\n 复制supervisor配置\n   ```\n     [root@localhost SimpletourDevops]# cp supervisord.conf  /etc/\n     [root@localhost supervisord.d]# supervisord -c /etc/supervisord.conf     <--启动supervisor,如果启动用户非www，请自行修改\n  ```\n 修改配置文件\n  ```\n    在settings.py中添加STATIC_ROOT\n    STATIC_ROOT = '/data/SimpletourDevops/static/suit'\n\n  ```\n\n  ```\n  python manage.py collectstatic  <--生成静态文件\n  ```\n 配置nginx\n ```\n  server {\n      listen       80;\n      server_name  localhost;\n      access_log  /var/log/nginx/devops.simpletour.com.access.log  main;\n      error_log  /var/log/nginx/devops.simpletour.com.error.log error;\n\n      location / {\n              include  uwsgi_params;\n              uwsgi_pass  127.0.0.1:8098;\n              uwsgi_read_timeout 600;\n              uwsgi_connect_timeout 60;\n              uwsgi_send_timeout 600;\n              client_max_body_size 35m;\n              proxy_http_version 1.1;\n              proxy_set_header Upgrade $http_upgrade;\n              proxy_set_header Connection \"upgrade\";\n              uwsgi_ignore_client_abort on;\n          }\n          location ^~ /docker/getSocket{\n              proxy_pass http://127.0.0.1:8099;\n              proxy_http_version 1.1;\n              proxy_set_header Upgrade $http_upgrade;\n              proxy_set_header Connection \"upgrade\";\n              proxy_set_header Host $host;\n              uwsgi_ignore_client_abort on;\n          }\n\n          location /static {\n              alias /data/SimpletourDevops/static/suit;\n          }\n\n  }\n  \n  \n\n```\n  \n\n\n\n启动访问\n\n### 首页及docker\n      \n![image](https://github.com/roddyofchina/SimpletourDevops/blob/master/images/login.png)\n![image](https://github.com/roddyofchina/SimpletourDevops/blob/master/images/system_admin.png)\n![image](https://github.com/roddyofchina/SimpletourDevops/blob/master/images/server.png)\n![image](https://github.com/roddyofchina/SimpletourDevops/blob/master/images/docker.png)\n![image](https://github.com/roddyofchina/SimpletourDevops/blob/master/images/docker_server.png)\n![image](https://github.com/roddyofchina/SimpletourDevops/blob/master/images/log.png)\n![image](https://github.com/roddyofchina/SimpletourDevops/blob/master/images/container_ssh.png)\n\n\n### saltstack\n![image](https://github.com/roddyofchina/SimpletourDevops/blob/master/images/keys.png)\n\n![image](https://github.com/roddyofchina/SimpletourDevops/blob/master/images/job.png)\n\n![image](https://github.com/roddyofchina/SimpletourDevops/blob/master/images/cmd.png)\n\n![image](https://github.com/roddyofchina/SimpletourDevops/blob/master/images/soft.png)\n\n\n### 后台\n\n![image](https://github.com/roddyofchina/SimpletourDevops/blob/master/images/protal.png)\n"
  },
  {
    "path": "SimpletourDevops/__init__.py",
    "content": "#coding:utf-8\nfrom django.core import signals\nfrom django.db import close_old_connections\n\n# 取消信号关联，实现数据库长连接\nsignals.request_finished.disconnect(close_old_connections)"
  },
  {
    "path": "SimpletourDevops/apps.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\n\nfrom suit.apps import DjangoSuitConfig\nfrom suit.menu import ParentItem, ChildItem\n\nclass SuitConfig(DjangoSuitConfig):\n    layout = 'vertical'\n\n    menu = (\n        ParentItem(u'资产组件', children=[\n            ChildItem(model='servermanager.server'),\n            ChildItem(model='servermanager.assets'),\n            ChildItem(model='servermanager.idc'),\n            ChildItem(model='servermanager.cpu'),\n            ChildItem(model='servermanager.nic'),\n            ChildItem(model='servermanager.disk'),\n            ChildItem(model='servermanager.software'),\n            ChildItem(model='servermanager.business'),\n            ChildItem(model='servermanager.devicetype'),\n            ChildItem(model='servermanager.provider'),\n        ], icon='fa fa-leaf'),\n\n        ParentItem(u'容器管理', children=[\n            ChildItem(model='dockermanager.dockerhost'),\n            ChildItem(model='dockermanager.dockercontainer'),\n            ChildItem(model='dockermanager.dockerimage'),\n        ], icon='fa fa-magnet'),\n\n        ParentItem(u'Salt管理', children=[\n            ChildItem(model='saltadmin.saltjobs'),\n            ChildItem(model='saltadmin.cmdrunlog'),\n            ChildItem(model='saltadmin.miniongroup'),\n            ChildItem(model='saltadmin.modules'),\n        ], icon='fa fa-magnet'),\n\n        ParentItem(u'用户管理', children=[\n            ChildItem(u'用  户','webapp.suser'),\n            ChildItem(u'用户组', 'auth.group'),\n        ], icon='fa fa-users'),\n\n\n\n    )\n"
  },
  {
    "path": "SimpletourDevops/settings.py",
    "content": "#coding:utf8\n\"\"\"\nDjango settings for SimpletourDevops project.\n\nGenerated by 'django-admin startproject' using Django 1.9.9.\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\n\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 = '7yk*v@pp1dxi+9fdg-=_3_&!hh4=4tiukajl1^-m$(_2q=gw=9'\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = True\nALLOWED_HOSTS = []\n\n\n\n\n\n# Application definition\n\nINSTALLED_APPS = [\n    #'suit',\n    'SimpletourDevops.apps.SuitConfig',\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    'webapp',\n    'servermanager',\n    'dockermanager',\n    'saltadmin',\n    #'domainmanager',\n    'import_export',\n]\n\nMIDDLEWARE_CLASSES = [\n    'django.middleware.security.SecurityMiddleware',\n    'django.contrib.sessions.middleware.SessionMiddleware',\n    'django.middleware.common.CommonMiddleware',\n    'django.middleware.locale.LocaleMiddleware',\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]\n\nROOT_URLCONF = 'SimpletourDevops.urls'\n\nTEMPLATES = [\n    {\n        'BACKEND': 'django.template.backends.django.DjangoTemplates',\n        'DIRS': [\"%s/%s\" %(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 = 'SimpletourDevops.wsgi.application'\n\n\n# Database\n# https://docs.djangoproject.com/en/1.9/ref/settings/#databases\nDATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.mysql',\n        'NAME': 'SimpletourDevops',\n        'HOST': '192.168.2.232',\n        'USER': 'root',\n        'PORT': 3306,\n        'PASSWORD': 'redhat',\n        'OPTIONS': {\n            'init_command': 'SET storage_engine=INNODB',\n        },\n    }\n}\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\nAUTH_USER_MODEL = 'webapp.Suser'\n\nLOGIN_URL='/web/login/'\n\n# Internationalization\n# https://docs.djangoproject.com/en/1.9/topics/i18n/\n\nLANGUAGE_CODE = 'zh-Hans'\n\nTIME_ZONE = 'Asia/Shanghai'\n\nUSE_I18N = True\n\nUSE_L10N = False\n\nUSE_TZ = False\n\n\n# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/1.9/howto/static-files/\n\nSTATIC_URL = '/static/'\n\n\nSTATICFILES_DIRS = (\n    os.path.join(BASE_DIR,'static'),\n)\n\n\nEMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'\nEMAIL_USE_TLS = True\nEMAIL_HOST = 'smtp.qq.com'\nEMAIL_PORT = 25\nEMAIL_HOST_USER = '923401910@qq.com'\nEMAIL_HOST_PASSWORD = 'utzvxwccfxhkbcdc'\nDEFAULT_FROM_EMAIL = '923401910@qq.com'\nSESSION_COOKIE_AGE = 60*180\n"
  },
  {
    "path": "SimpletourDevops/urls.py",
    "content": "\"\"\"SimpletourDevops 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.conf.urls import url,include\nfrom django.contrib import admin\nfrom webapp.views import index\nfrom django.conf import settings\n\n\nurlpatterns = [\n    url(r'^admin/', admin.site.urls),\n    url(r'^$', index, name='index'),\n    url(r'^web/', include('webapp.urls')),\n    url(r'^docker/',include('dockermanager.urls')),\n    url(r'^server/',include('servermanager.urls')),\n   # url(r'^domain/', include('domainmanager.urls')),\n    url(r'^salt/',include('saltadmin.urls')),\n]\n"
  },
  {
    "path": "SimpletourDevops/wsgi.py",
    "content": "\"\"\"\nWSGI config for SimpletourDevops 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\", \"SimpletourDevops.settings\")\n\napplication = get_wsgi_application()\n"
  },
  {
    "path": "dockermanager/Docker_Controller.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\nimport os\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"SimpletourDevops.settings\")\nimport django\ndjango.setup()\nfrom dockermanager.models import DockerHost,Dockerimage,DockerContainer\nfrom Publicapi.dockerapi.Manager import Dockerapi\nimport time\n\n\n\n'''获取数据'''\ndef GetDockerServerinfo():\n    DockerServerList = DockerHost.objects.filter(enabled=1)\n    for server in DockerServerList:\n        try:\n            docker=Dockerapi(server.hostip,server.port)\n            Dockerdata=docker.GetallContainers()\n            for container in Dockerdata:\n                '''获取容器最新状态进行修改'''\n                if DockerContainer.objects.filter(containerID=container['Id']):\n                    status=container['Status']\n                    if 'Up' in status:\n                        status= 'running'\n                    else:\n                        status = 'Exited'\n                    OldContainer = DockerContainer.objects.get(containerID=container['Id'])\n                    OldContainer.Name=container['Names'][0].lstrip('/')\n                    OldContainer.command=container['Command']\n                    OldContainer.status=status\n                    OldContainer.image=container['Image']\n                    OldContainer.hostip=server.hostip\n                    OldContainer.Created=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(container['Created']))\n                    OldContainer.save()\n                else:\n                    '''如果没有容器就添加'''\n                    status = container['Status']\n                    if 'Up' in status:\n                        status = 'running'\n                    else:\n                        status = 'Exited'\n                    NewContainer=DockerContainer(containerID=container['Id'],\n                                    Name=container['Names'][0].lstrip('/'),\n                                    command=container['Command'],\n                                    status=status,\n\n                                    image=container['Image'],\n                                    hostip=server.hostip,\n                                    Created=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(container['Created'])))\n                    NewContainer.save()\n        except:\n            print \"sssssss\"\n            return u\"Connect Docker host is Error!!!\"\n    return u\"OK\"\n\n\ndef GetDockerImages():\n    DockerServerList = DockerHost.objects.filter(enabled=1)\n    for server in DockerServerList:\n        try:\n            docker=Dockerapi(server.hostip,server.port)\n            DockerImagesdata=docker.AllImages()\n        except:\n            return u\"Connect Docker host is Error!!!\"\n        else:\n            for image in DockerImagesdata:\n\n                if image['RepoTags'][0] == '<none>:<none>':\n                    continue\n                imageid=image['Id'].split(':')[-1]\n                for repo in image['RepoTags']:\n                    if Dockerimage.objects.filter(repository=repo):\n                        Oldimage = Dockerimage.objects.get(repository=repo)\n                        Oldimage.repository = repo\n                        Oldimage.imagesId=imageid\n                        Oldimage.tag = repo.split(':')[-1]\n                        Oldimage.imagehost = server.hostip\n                        Oldimage.size = image['Size']\n                        Oldimage.save()\n                    else:\n                        Newimage=Dockerimage(imagesId=imageid,\n                                    repository=repo,\n                                    tag = repo.split(':')[-1],\n                                    imagehost = server.hostip,\n                                    size=image['Size'],\n                                    )\n                        Newimage.save()\n\n    return \"Get all imgeas is oK!!\"\n\n\nif __name__ == '__main__':\n    GetDockerImages()\n\n\n\n\n\n\n\n"
  },
  {
    "path": "dockermanager/__init__.py",
    "content": ""
  },
  {
    "path": "dockermanager/admin.py",
    "content": "#coding:utf8\nfrom django.contrib import admin\nfrom dockermanager.models import *\nclass DockerHostModels(admin.ModelAdmin):\n    list_display = ('host','containers','images','port','enabled')\nclass DockerContainerModels(admin.ModelAdmin):\n    list_display = ('Name','status','ip','host','uptime')\nadmin.site.register(DockerHost,DockerHostModels)\nadmin.site.register(DockerContainer)\nadmin.site.register(Dockerimage)\n\n\n"
  },
  {
    "path": "dockermanager/apps.py",
    "content": "from __future__ import unicode_literals\n\nfrom django.apps import AppConfig\n\n\nclass DockermanagerConfig(AppConfig):\n    name = 'dockermanager'\n"
  },
  {
    "path": "dockermanager/forms.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\n\nfrom django import forms\nfrom servermanager.models import Server\nfrom dockermanager.models import DockerHost\nfrom django.forms import ModelForm\n\n\n\n\n\n\n\n\n\nclass DockerServerAdd(forms.Form):\n    DockerServer=forms.ModelChoiceField(required=True,\n                                        error_messages={'required': u'选择主机'},\n                                        queryset=Server.objects.all(),widget=forms.Select(attrs={'class':'form-control'}))\n\n    ServerStatus = forms.ChoiceField(choices=[(0,u'禁用'),(1,u'启用')],widget=forms.Select(attrs={'class':'form-control'}))\n\n    dockerip = forms.GenericIPAddressField(required=True,\n                                           error_messages={'required': u'请输入dockerhost ip', 'invalid':u'ip地址错误'},\n                                           widget=forms.TextInput(attrs={'class': 'form-control','placeholder': '宿主机IP',\n                                                               }),)\n    dockerport = forms.IntegerField(required=True,\n                                    error_messages={'required': u'请输入dockerhost port', 'invalid':u'port输入错误'},\n                                    widget=forms.TextInput(attrs={'class': 'form-control','placeholder': '宿主机端口',\n                                    }),)\n\nclass DockerServerEdit(ModelForm):\n    class Meta:\n        model = DockerHost\n        fields = ('host', 'hostip','port','enabled')\n"
  },
  {
    "path": "dockermanager/migrations/__init__.py",
    "content": ""
  },
  {
    "path": "dockermanager/models.py",
    "content": "#coding:utf8\nfrom __future__ import unicode_literals\n\nfrom django.db import models\n\nfrom servermanager.models import Server\n\n\nclass Dockerimage(models.Model):\n    imagesId = models.CharField(u'镜像ID', max_length=64)\n    repository = models.CharField(u'仓库', max_length=64,blank=True)\n    tag = models.CharField(u'Tag', max_length=32,blank=True)\n    imagehost = models.GenericIPAddressField(u'主机IP')\n    size = models.CharField(u'大小', max_length=32,blank=True)\n\n    update_at = models.DateTimeField(blank=True, auto_now=True,null=True)\n\n    def __unicode__(self):\n        return self.imagesId\n\n    class Meta:\n        verbose_name = u'Docker镜像'\n        verbose_name_plural = u\"Docker镜像\"\n\n\nclass DockerHost(models.Model):\n    host = models.OneToOneField(Server,verbose_name=u'主机')\n    hostip = models.GenericIPAddressField(max_length=128,null=False,default='',verbose_name=u'docker IP地址')\n    containers = models.IntegerField(u'容器数',blank=True,null=True)\n    images = models.IntegerField(verbose_name=u'镜像数',blank=True,null=True)\n    port = models.IntegerField(u'端口',blank=True)\n    enabled = models.IntegerField(u'状态',blank=True)\n    serverversion = models.CharField(u'docker版本', max_length=32,blank=True)\n    datatotal = models.CharField(u'总共空间', max_length=32,blank=True)\n    datause = models.CharField(u'已使用空间', max_length=32,blank=True)\n    dataAvailable = models.CharField(u'剩余空间', max_length=32,blank=True)\n    storageDriver = models.CharField(u'存储驱动', max_length=32,blank=True)\n    create_at = models.DateTimeField(blank=True, auto_now_add=True)\n    update_at = models.DateTimeField(blank=True, auto_now=True)\n    def __unicode__(self):\n        return self.hostip\n\n    class Meta:\n        verbose_name = u'Docker主机'\n        verbose_name_plural = u\"Docker主机\"\n\n\nclass DockerContainer(models.Model):\n    hostip = models.GenericIPAddressField(u'宿主机IP地址',max_length=128,blank=True,null=True)\n    containerID = models.CharField(u'容器ID', max_length=64)\n    Name = models.CharField(u'容器名', max_length=255,blank=True)\n    command = models.CharField(u'执行命令', max_length=255,blank=True)\n    status = models.CharField(u'状态', max_length=32,blank=True)\n    image= models.CharField(verbose_name=u'镜像', blank=True,max_length=64)\n    Created = models.DateTimeField(u'创建时间',blank=True,)\n    update_at = models.DateTimeField(blank=True, auto_now=True,null=True)\n\n    def __unicode__(self):\n        return self.Name\n\n    class Meta:\n        verbose_name = u'Docker容器'\n        verbose_name_plural = u\"Docker容器\"\n        permissions = (\n            (\"docker_index_view\", \"Can view %s\" % verbose_name),\n        )\n\n\nclass DockerContainerInfo(models.Model):\n    containerid = models.CharField(u'容器ID', max_length=48)   #与上表进行关联\n    State = models.CharField(u'状态', max_length=48)\n    Driver = models.CharField(u'磁盘设备', max_length=48,blank=True,null=True)\n    net = models.CharField(u'网络模式', max_length=48,blank=True)\n    cpu = models.CharField(u'CPU', max_length=32,blank=True)\n    mem =models.CharField(u'内存', max_length=32,blank=True)\n    ip = models.GenericIPAddressField(u'IP')\n    dns = models.CharField(u'DNS', max_length=32,blank=True)\n    host = models.CharField(u'主机', max_length=32,blank=True)\n    MacAddress = models.CharField(u'网卡mac地址', max_length=64)\n    uptime = models.CharField(u'运行时间', max_length=32,blank=True)\n    gateway = models.GenericIPAddressField(u'网关')\n\nclass ContainerPorts(models.Model):\n    containerid = models.CharField(u'容器ID', max_length=48)   #与上表进行关联\n    container_port = models.IntegerField(u'容器端口',blank=True)\n    protocol = models.CharField(u'协议',max_length=32,blank=True)\n    hostip = models.GenericIPAddressField(u'映射IP')\n    hostport = models.CharField(u'主机端口',max_length=32,blank=True)\n\n    def __unicode__(self):\n        return self.containerid\n\n    class Meta:\n        verbose_name = u'端口管理'\n        verbose_name_plural = u\"端口管理\"\n"
  },
  {
    "path": "dockermanager/tests.py",
    "content": "from django.test import TestCase\n\n# Create your tests here.\n"
  },
  {
    "path": "dockermanager/urls.py",
    "content": "from django.conf.urls import url\n\nfrom dockermanager.views import (Dockercontainerlist,DockerHosts,DockerImages,DockercontainerSearch,\n                                 DockerHostAdd,DockerHostDel,DockerHostEdit,DockerContainerDel,\n                                 DockerContainerStop,DockerContainerStart,DockerContainerRestart,\n                                 DockerImageDelete,DockerLogOutput,StartCeleryStatus,StopCeleryStatus,\n                                 RestartCeleryStatus,DeleteCeleryStatus,webSocket,getsocket)\n\nurlpatterns = [\n    url(r'container/list/(\\d+)$', Dockercontainerlist, name='Dockercontainerlist'),\n    url(r'container/search/(?P<page>\\d+)$',DockercontainerSearch,name='DockercontainerSearch'),\n    url(r'container/restart/(\\w+)$',DockerContainerRestart,name='DockerContainerRestart'),\n    url(r'container/stop/(\\w+)$', DockerContainerStop,name='DockerContainerStop'),\n    url(r'container/start/(\\w+)$', DockerContainerStart, name='DockerContainerStart'),\n    url(r'container/logs/(\\w+)$',DockerLogOutput,name='DockerLogOutput'),\n    url(r'container/delete/(\\w+)$',DockerContainerDel,name='DockerContainerDel'),\n    url(r'container/start/task/(\\w+\\-\\w+\\-\\w+\\-\\w+\\-\\w+)$',StartCeleryStatus,name='StartCeleryStatus'),\n    url(r'container/restart/task/(\\w+\\-\\w+\\-\\w+\\-\\w+\\-\\w+)$',RestartCeleryStatus,name='RestartCeleryStatus'),\n    url(r'container/stop/task/(\\w+\\-\\w+\\-\\w+\\-\\w+\\-\\w+)$',StopCeleryStatus,name='StopCeleryStatus'),\n    url(r'container/delete/task/(\\w+\\-\\w+\\-\\w+\\-\\w+\\-\\w+)$',DeleteCeleryStatus,name='DeleteCeleryStatus'),\n    url(r'server/list/$', DockerHosts, name='DockerHosts'),\n    url(r'images/list/(\\d+)$',DockerImages, name='DockerImages'),\n    url(r'images/del/(\\d+)$', DockerImageDelete, name='DockerImageDelete'),\n    url(r'server/add/$', DockerHostAdd, name='DockerHostAdd'),\n    url(r'server/del/(\\d+)$',DockerHostDel,name='DockerHostDel'),\n    url(r'server/edit/(\\d+)$',DockerHostEdit,name='DockerHostEdit'),\n    url(r'webSocket/(\\w+)$',webSocket,name='webSocket'),\n    url(r'getSocket/(\\w+)$',getsocket,name='getsocket'),\n]\n"
  },
  {
    "path": "dockermanager/views.py",
    "content": "#coding:utf8\nfrom django.shortcuts import render,render_to_response\nfrom django.http import HttpResponse,HttpResponseRedirect\nfrom django.http import StreamingHttpResponse\nfrom dwebsocket import accept_websocket,require_websocket\nimport threading\nfrom django.http import HttpResponse\nfrom django.db.models import Q\n\nfrom django.contrib.auth.decorators import login_required\nfrom dockermanager.models import DockerHost,Dockerimage,DockerContainer\nfrom django.contrib.auth.decorators import permission_required\n\n# Create your views here.\nfrom webapp.Extends import PageList\nfrom servermanager.models import Server\nfrom dockermanager import forms\nfrom Publicapi.dockerapi.Manager import Dockerapi\nfrom webapp.tasks import StopContainer,StartContainer,RestartContainer,DeleteContainer\nimport  json\nimport docker\nfrom webapp.models import *\n\n@login_required()\n@permission_required('dockermanger.docker_index_view',raise_exception=True)\ndef Dockercontainerlist(request,page):\n    usersession=request.session.get('user_id')\n    if request.method == 'POST':\n        searchdata = request.POST.get('search')\n        #分页代码\n        (page,start,end,per_item)=PageList.PageCount(page)\n        count = DockerContainer.objects.filter(Q(containerID__contains=searchdata) | Q(Name__contains=searchdata)).count()\n        result = DockerContainer.objects.filter(Q(containerID__contains=searchdata) | Q(Name__contains=searchdata)).order_by('-id')[start:end]\n        url = \"/docker/container/list\"\n        if count%per_item == 0:\n            all_pages_count = count/per_item\n        else:\n            all_pages_count = count/per_item+1\n        page=PageList.Page(page, url, all_pages_count)\n\n        ret = {'Containerdata': result,\n               'count': count,\n               'page': page,\n               'usersession':usersession}\n        return render(request,'dockermanager/containers_list.html',ret)\n\n    else:\n\n        DockerHostData= DockerHost.objects.all()\n        #分页代码\n        (page,start,end,per_item)=PageList.PageCount(page)\n        count = DockerContainer.objects.all().count()\n        result = DockerContainer.objects.all().order_by('-id')[start:end]\n        url = \"/docker/container/list\"\n        if count%per_item == 0:\n            all_pages_count = count/per_item\n        else:\n            all_pages_count = count/per_item+1\n        page=PageList.Page(page, url, all_pages_count)\n\n        ret = {'Containerdata': result,\n               'count': count,\n               'DockerHostData':DockerHostData,\n               'page': page,\n               'usersession':usersession}\n        return render(request,'dockermanager/containers_list.html',ret)\n\n\n@login_required()\ndef DockercontainerSearch(request,page):\n    usersession=request.session.get('user_id')\n    if request.method == 'GET':\n        searchdata = request.GET.get('search')\n\n        ipData = request.GET.get('ipList')\n        status = request.GET.get('status')\n\n        DockerHostData = DockerHost.objects.all()\n        #分页代码\n        (page,start,end,per_item)=PageList.PageCount(page)\n\n\n        count=DockerContainer.objects.filter(Q(hostip__contains=ipData) & Q(status__contains=status),\n                                       Q(containerID__contains=searchdata) | Q(Name__contains=searchdata)).count()\n\n        result=DockerContainer.objects.filter(Q(hostip__contains=ipData) & Q(status__contains=status),\n                                                  Q(containerID__contains=searchdata) | Q(Name__contains=searchdata)).order_by('-id')[start:end]\n\n        #count = DockerContainer.objects.filter(Q(containerID__contains=searchdata) | Q(Name__contains=searchdata)).count()\n        #result = DockerContainer.objects.filter(Q(containerID__contains=searchdata) | Q(Name__contains=searchdata)).order_by('-id')[start:end]\n        url = \"/docker/container/search\"\n        print url\n        search=u\"?search=%s&status=%s&ipList=%s\" %(searchdata,status,ipData)\n        if count%per_item == 0:\n            all_pages_count = count/per_item\n        else:\n            all_pages_count = count/per_item+1\n        page=PageList.Page(page, url, all_pages_count,search)\n\n        ret = {'Containerdata': result,\n               'count': count,\n               'DockerHostData': DockerHostData,\n               'page': page,\n               'usersession':usersession}\n        return render(request,'dockermanager/containers_list.html',ret)\n\n\n@login_required()\ndef DockerHosts(request):\n    usersession=request.session.get('user_id')\n    if request.method == 'POST':\n        id = request.POST['id']\n        status= request.POST['checkboxValue']\n        if status == 'true':\n            status=1\n        else:\n            status=0\n        dockerhostdata = DockerHost.objects.get(id=id)\n        dockerhostdata.enabled = status\n        dockerhostdata.save()\n        msg={'msginfo':u'主机状态修改成功!!!!!!'}\n        return HttpResponse(json.dumps(msg))\n    else:\n        Hostadata=DockerHost.objects.all()\n        ret={'usersession':usersession,'Hostadata':Hostadata}\n        return  render(request,'dockermanager/dockerhosts_list.html',ret)\n\n\n@login_required()\n@permission_required('dockermanger.add_dockerhost',raise_exception=True)\ndef DockerHostAdd(request):\n\n    username = request.session.get('user_name')\n    restdata = {'data':'','regerror':'','usersession': request.session.get('user_id')}\n    registerobj=forms.DockerServerAdd()\n    restdata['data'] = registerobj\n\n    listdata=[]\n    [listdata.append(int(i.host.id)) for i in DockerHost.objects.all()]\n    ServerData=Server.objects.exclude(id__in=listdata)\n    restdata['ServerData']=ServerData\n\n    if request.method == 'POST':\n        form = forms.DockerServerAdd(request.POST)\n        if form.is_valid():\n            ServerData = request.POST['DockerServer']\n            ServerData = Server.objects.get(id=ServerData)\n            dockerip = request.POST['dockerip']\n            dockerport = request.POST['dockerport']\n            ServerStatus = int(request.POST['ServerStatus'])\n\n            NewDockerHost=DockerHost(host=ServerData,hostip=dockerip,port=dockerport,enabled=ServerStatus)\n            NewDockerHost.save()\n            Operation.objects.create(Opuser=username,Opaction=u'添加Docker宿主机')\n            return HttpResponseRedirect('/docker/server/list/')\n        else:\n            restdata['data'] = form\n    return render(request,'dockermanager/dockerhosts_add.html', restdata)\n\n\n@login_required()\ndef DockerImages(request,page):\n    usersession=request.session.get('user_id')\n    if request.method == 'POST':\n        pass\n    else:\n         #分页代码\n        (page,start,end,per_item)=PageList.PageCount(page)\n        count = Dockerimage.objects.all().count()\n        result = Dockerimage.objects.all().order_by('-id')[start:end]\n        url = \"/docker/images/list\"\n        if count%per_item == 0:\n            all_pages_count = count/per_item\n        else:\n            all_pages_count = count/per_item+1\n        page=PageList.Page(page, url, all_pages_count)\n\n        ret = {'Imagedata': result,\n               'count': count,\n               'page': page,\n               'usersession':usersession}\n        return render(request,'dockermanager/images_list.html',ret)\n\n@login_required()\n@permission_required('dockermanger.delete_dockerimage',raise_exception=True)\ndef DockerImageDelete(request, imageid):\n    username = request.session.get('user_name')\n    if request.method == 'GET':\n        Image=Dockerimage.objects.get(id=imageid)\n        if Image:\n            repo=Image.repository\n            #查询DOCKER主机IP及端口\n            ip = Image.imagehost\n            port = DockerHost.objects.get(hostip=ip).port\n            dockerapi = Dockerapi(ip,port)\n            a=dockerapi.DeleteImages(repo)\n            Image.delete()\n            Operation.objects.create(Opuser=username,Opaction=u'删除Docker镜像 %s' %repo)\n            return HttpResponse(a)\n        else:\n            return HttpResponse(u\"没有该镜像!!\")\n\n@login_required()\n@permission_required('dockermanger.delete_dockerhost',raise_exception=True)\ndef DockerHostDel(request,hostid):\n    username = request.session.get('user_name')\n    if request.method == 'GET':\n       DockerHost.objects.get(id=hostid).delete()\n       Operation.objects.create(Opuser=username,Opaction=u'删除Docker宿主机%s' %hostid)\n       msg={'msginfo':u'DockerHost 删除成功!!!'}\n       return HttpResponse(json.dumps(msg))\n\n@login_required()\n@permission_required('dockermanger.change_dockerhost',raise_exception=True)\ndef DockerHostEdit(request,hostid):\n    usersession=request.session.get('user_id')\n    username = request.session.get('user_name')\n    HostData=DockerHost.objects.get(id=hostid)\n    if request.method == 'POST':\n        pass\n        Operation.objects.create(Opuser=username,Opaction=u'修改Docker宿主机%s' %hostid)\n    else:\n        listdata=[]\n        [listdata.append(int(i.host.id)) for i in DockerHost.objects.all()]\n        hostid=HostData.host.id\n        listdata.remove(hostid)\n        ServerData=Server.objects.exclude(id__in=listdata)\n\n        ret={'usersession':usersession,'HostData':HostData,'hostid':hostid,'ServerData':ServerData}\n        return render(request,'dockermanager/dockerhosts_edit.html', ret)\n\n@login_required()\ndef DockerContainerStop(request,containerid):\n    username = request.session.get('user_name')\n    if request.method == 'GET':\n        IP=DockerContainer.objects.get(containerID=containerid).hostip\n        port = DockerHost.objects.get(hostip=IP).port\n        a=StopContainer.delay(dict(host=IP,port=port,container=containerid))\n        Operation.objects.create(Opuser=username,Opaction=u'停止容器%s' %containerid[0:12])\n        msg={'celeryId':a.id}\n        return HttpResponse(json.dumps(msg))\n\n@login_required()\ndef DockerContainerRestart(request,containerId):\n    username = request.session.get('user_name')\n    if request.method == 'GET':\n        IP=DockerContainer.objects.get(containerID=containerId).hostip\n        port = DockerHost.objects.get(hostip=IP).port\n        a=RestartContainer.apply_async((IP, port, containerId))\n        Operation.objects.create(Opuser=username,Opaction=u'重启容器%s' %containerId[0:12])\n        msg={'celeryId':a.id}\n        return HttpResponse(json.dumps(msg))\n\n@login_required()\n@permission_required('dockermanger.delete_dockercontainerinfo',raise_exception=True)\ndef DockerContainerDel(request,containerId):\n    username = request.session.get('user_name')\n    if request.method == 'GET':\n        print \"sdsdsds\"\n        IP=DockerContainer.objects.get(containerID=containerId).hostip\n        port = DockerHost.objects.get(hostip=IP).port\n        print \"ssssssss\"\n        print IP,port,containerId\n        a=DeleteContainer.apply_async((IP, port, containerId))\n        Operation.objects.create(Opuser=username,Opaction=u'删除容器%s' %containerId[0:12])\n        msg={'celeryId': a.id}\n        return HttpResponse(json.dumps(msg))\n\n@login_required()\ndef DockerContainerStart(request, containerId):\n    username = request.session.get('user_name')\n    if request.method == 'GET':\n        IP=DockerContainer.objects.get(containerID=containerId).hostip\n        port = DockerHost.objects.get(hostip=IP).port\n        a=StartContainer.apply_async((IP, port, containerId))\n        Operation.objects.create(Opuser=username,Opaction=u'启动容器%s' %containerId[0:12])\n        msg={'celeryId': a.id}\n        return HttpResponse(json.dumps(msg))\n\n\n@login_required()\ndef DockerLogOutput(request,containerid):\n    usersession=request.session.get('user_id')\n    if request.method == 'GET':\n        IP=DockerContainer.objects.get(containerID=containerid).hostip\n        port = DockerHost.objects.get(hostip=IP).port\n        try:\n            dockerserver = Dockerapi(IP,port)\n            data=dockerserver.LogContainer(containerid,tail=30)\n            data=data.split('\\n')\n        except docker.errors.NotFound:\n            return HttpResponse('没有该容器')\n        ret = {'usersession': usersession,'dockerlogsdata':data,'containerid':containerid}\n        return render(request,'dockermanager/dockerhosts_logs.html',ret)\n    else:\n        IP=DockerContainer.objects.get(containerID=containerid).hostip\n        port = DockerHost.objects.get(hostip=IP).port\n        try:\n            dockerserver = Dockerapi(IP,port)\n            data=dockerserver.LogContainer(containerid,tail=30)\n            data=data.split('\\n')\n        except docker.errors.NotFound:\n            return HttpResponse('没有该容器')\n        ret={'dockerlogsdata':data}\n        return HttpResponse(json.dumps(ret))\n\n@login_required()\ndef StartCeleryStatus(request,celeryid):\n    if request.method == 'GET':\n        task=StartContainer.AsyncResult(str(celeryid))\n        if task.state == 'PENDING':\n            response = {\n                'state': task.state,\n                'status': 'Pending...'\n            }\n        elif task.state != 'FAILURE':\n            response = {\n                'state': task.state,\n                'status': task.status,\n            }\n            if 'result' in task.info:\n                response['result'] = task.info['result']\n\n        else:\n            response = {\n                'state': task.state,\n                'current': 1,\n                'total': 1,\n                'status': str(task.info),  # this is the exception raised\n            }\n        return HttpResponse(json.dumps(response))\n\n@login_required()\ndef StopCeleryStatus(request,celeryid):\n    if request.method == 'GET':\n\n        task=StopContainer.AsyncResult(str(celeryid))\n        if task.state == 'PENDING':\n            response = {\n                'state': task.state,\n                'status': 'Pending...'\n            }\n        elif task.state != 'FAILURE':\n            response = {\n                'state': task.state,\n                'status': task.status,\n            }\n            if 'result' in task.info:\n                response['result'] = task.info['result']\n        else:\n            response = {\n                'state': task.state,\n                'current': 1,\n                'total': 1,\n                'status': str(task.info),  # this is the exception raised\n            }\n        return HttpResponse(json.dumps(response))\n\n@login_required()\ndef RestartCeleryStatus(request,celeryid):\n    if request.method == 'GET':\n\n        task=RestartContainer.AsyncResult(str(celeryid))\n        if task.state == 'PENDING':\n            response = {\n                'state': task.state,\n                'status': 'Pending...'\n            }\n        elif task.state != 'FAILURE':\n            response = {\n                'state': task.state,\n                'status': task.status,\n            }\n            if 'result' in task.info:\n                response['result'] = task.info['result']\n        else:\n            response = {\n                'state': task.state,\n                'status': str(task.info),  # this is the exception raised\n            }\n        return HttpResponse(json.dumps(response))\n\n@login_required()\ndef DeleteCeleryStatus(request,celeryid):\n    if request.method == 'GET':\n        task=DeleteContainer.AsyncResult(str(celeryid))\n        containerID=request.GET['containerid']\n        if task.state == 'PENDING':\n            response = {\n                'state': task.state,\n                'status': 'Pending...'\n            }\n        elif task.state != 'FAILURE':\n            DockerContainer.objects.filter(containerID=containerID).delete()\n            response = {\n                'state': task.state,\n                'status': task.status,\n            }\n            if 'result' in task.info:\n                response['result'] = task.info['result']\n        else:\n            response = {\n                'state': task.state,\n                'status': str(task.info),  # this is the exception raised\n            }\n        return HttpResponse(json.dumps(response))\n\n@login_required()\ndef webSocket(request,containerId):\n    usersession = request.session.get('user_id')\n    IP = DockerContainer.objects.get(containerID=containerId).hostip\n    PORT = DockerHost.objects.get(hostip=IP).port\n    containerId = containerId\n    return render(request,'dockermanager/websocket.html',locals())\n\n\n\n@accept_websocket\ndef getsocket(request,containerId):\n    if request.is_websocket:\n        request.websocket.send('Welcome to Simpletour DevOps!!')\n        IP = DockerContainer.objects.get(containerID=containerId).hostip\n        PORT = DockerHost.objects.get(hostip=IP).port\n\n        docker_api = Dockerapi(IP, PORT)\n        try:\n            container = docker_api.dockerConnect.exec_create(container=containerId, cmd=\"/bin/bash\", user='root',\n                                                                       tty=True,stdout=True,stderr=True,stdin=True,)\n            a = docker_api.dockerConnect.exec_start(container['Id'], stream=True, tty=True, detach=False,socket=True)\n            docker_api.dockerConnect.exec_resize(container['Id'], height=40, width=80)\n            for message in request.websocket:\n                if not message:\n                    break\n                a.send(message.encode('utf-8'))\n                request.websocket.send(a.recv(65535))\n        except:\n            request.websocket.send('主机无法连接!!')\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "domainmanager/urls.py",
    "content": "from django.conf.urls import url\n\n\nfrom domainmanager.views import (SimpletourDomainLists,SimpletourGetdomainApi,Simpletourrecord,SimpletourGetRecords)\n\nurlpatterns = [\n    url(r'list/$', SimpletourDomainLists, name='SimpletourDomainLists'),\n    url(r'dnspodapi/$',SimpletourGetdomainApi,name='SimpletourGetdomainApi'),\n    url(r'records/$',SimpletourGetRecords,name='SimpletourGetRecords'),\n    url(r'record/search/(?P<id>\\d+)$',Simpletourrecord,name='Simpletourrecord'),\n]\n"
  },
  {
    "path": "manage.py",
    "content": "#!/usr/bin/env python\nimport os\nimport sys\n\nif __name__ == \"__main__\":\n    os.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"SimpletourDevops.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": "django==1.9.9\ndjango-import-export==0.5.1\nitsdangerous==0.24\ncelery\nhttps://github.com/darklow/django-suit/tarball/v2\nMySQL-python\ndocker-py\nsupervisor\nuwsgi\nredis\ndwebsocket\neventlet==0.19.0\npyyaml\n\n"
  },
  {
    "path": "run_eventlet.py",
    "content": "from eventlet import wsgi, patcher\npatcher.monkey_patch()\n\nimport sys\nimport getopt\nimport eventlet\nfrom SimpletourDevops.wsgi import application\n\n\naddr, port = '127.0.0.1', 8099\nopts, _ = getopt.getopt(sys.argv[1:], \"b:\")\nfor opt, value in opts:\n    if opt == '-b':\n        addr, port = value.split(\":\")\n\nwsgi.server(eventlet.listen((addr, int(port))), application)\n"
  },
  {
    "path": "saltadmin/Minions_Controller.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\n\nimport os\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"SimpletourDevops.settings\")\nimport django\ndjango.setup()\nimport datetime\nfrom saltadmin.models import *\nfrom Publicapi.saltstackapi.SaltConApi import SaltApi\nimport threading\nimport json\n\n\ndef GetALLkeys():\n    saltmaster = SaltServer.objects.all()\n\n    for server in saltmaster:\n        salt=SaltApi(server.url,server.username,server.password)\n        minions,minions_pre,minions_rej,minions_deny =salt.List_all_keys()\n        for i in minions:\n            try:\n                Minions.objects.create(minion=i, saltserver=server, status=\"Accepted\")\n            except:\n                minion = Minions.objects.get(minion=i)\n                minion.status = 'Accepted'\n                minion.save()\n        for pre in minions_pre:\n            try:\n                Minions.objects.create(minion=pre, saltserver=server, status=\"Unaccepted\")\n            except:\n                minion = Minions.objects.get(minion=pre)\n                minion.status = 'Unaccepted'\n                minion.save()\n\n\n        for rej in minions_rej:\n            try:\n                Minions.objects.create(minion=rej, saltserver=server, status=\"Rejected\")\n            except:\n                minion = Minions.objects.get(minion=rej)\n                minion.status = 'Rejected'\n                minion.save()\n\n\n        for deny in minions_deny:\n            try:\n                Minions.objects.create(minion=deny, saltserver=server, status=\"Denied\")\n            except:\n                minion = Minions.objects.get(minion=deny)\n                minion.status = 'Denied'\n                minion.save()\n\n\ndef UpdateMinionInfo(mininboj,minions,url,username,password):\n    salt = SaltApi(url, username, password)\n    alive_minions = salt.Saltalive(minions)\n\n    print alive_minions\n    if minions in alive_minions:\n        minion_status = True\n    else:\n        minion_status = False\n\n    try:\n        MinionStatus.objects.create(minion=mininboj, minion_status=minion_status)\n    except:\n        saltminion = MinionStatus.objects.get(minion=mininboj)\n        alive_old = MinionStatus.objects.get(minion=mininboj).minion_status\n\n        if minion_status != alive_old:\n            saltminion.alive_time_last = datetime.datetime.now()\n            saltminion.minion_status = minion_status\n        print \"-------------------------------%s\" %(minion_status,)\n        saltminion.alive_time_now = datetime.datetime.now()\n        saltminion.save()\n\n\ndef GetMinionConf():\n    GetALLkeys()\n    MinionsData=Minions.objects.filter(status='Accepted')\n    for minion in MinionsData:\n        t=threading.Thread(target=UpdateMinionInfo,args=(minion,\n                                                         minion.minion,\n                                                         minion.saltserver.url,\n                                                         minion.saltserver.username,\n                                                         minion.saltserver.password))\n        t.start()\n\n    return \"GET minion conf is Ok!!\"\n\n\n\ndef GetJobs(url,username,password):\n    salt = SaltApi(url,username,password)\n\n    data = salt.runner(\"jobs.list_jobs\")\n\n    for j,info in data.items():\n        if SaltJobs.objects.filter(jid=j):\n            pass\n        else:\n            SaltJobs.objects.create(jid=j,args=info['Arguments'],function=info['Function'],\n                                    startTime=info['StartTime'],target=info['Target'],user=info['User'],saltserver=url)\n\n\ndef GetSaltJobs():\n    SaltMaster_data = SaltServer.objects.all()\n    for salt in SaltMaster_data:\n        t = threading.Thread(target=GetJobs,args=(salt.url,salt.username,salt.password))\n        t.start()\n\n\n\ndef JobResultFromat(data):\n    result=[]\n\n    for resultkey,resultdata in data.items():\n\n        list = []\n        errors_count = []\n\n        for task,taskresult in resultdata.items():\n\n            taskLinedict ={}\n            taskLinedict['ID'] = task.split('|')[1].strip('_').lstrip('-')\n            taskLinedict['Name'] = task.split('|')[2].strip('_').lstrip('-')\n            if taskresult['result']  == False:\n                errors_count.append(taskresult)\n            taskLinedict['Result'] =taskresult['result']\n            taskLinedict['Comment'] = taskresult['comment']\n            if  not taskresult.has_key('start_time'):\n                taskresult['Started'] = ''\n            else:\n                taskresult['Started'] = taskresult['start_time']\n            if not taskresult.has_key('duration'):\n                taskresult['Duration'] = ''\n            else:\n                taskresult['Duration'] = taskresult['duration']\n            taskLinedict['Changes'] = taskresult['changes']\n            list.append(taskLinedict)\n\n        result_dict_list = {'url':resultkey,'result': list,'error':len(errors_count),'success':len(list) - len(errors_count)}\n        result.append(result_dict_list)\n\n    # for formatkey,formatresult in result.items():\n    #     print formatkey\n    #     for line in  formatresult:\n    #         print \"---------------------------------\"\n    #         for k,v in line.items():\n    #             if isinstance(v,dict):\n    #                 if len(v) == 0:\n    #                     v = None\n    #             print k+\":\",v\n    #\n    #     #result[k] = v\n\n    return result\n\n\n\n\n\nif __name__ == '__main__':\n    #GetMinionConf()\n    #GetSaltJobs()\n    #a={u'192.168.2.148': {u'user_|-zabbix-user-group_|-zabbix_|-present': {u'comment': u'User zabbix set to be added', u'name': u'zabbix', u'start_time': u'10:41:43.381761', u'result': None, u'duration': 16.003, u'__run_num__': 1, u'changes': {}, u'__id__': u'zabbix-user-group'}, u'file_|-start-file_|-/etc/rc.local_|-append': {u'comment': u'File /etc/rc.local is set to be updated', u'pchanges': {}, u'name': u'/etc/rc.local', u'start_time': u'10:41:43.439903', u'result': None, u'duration': 1.483, u'__run_num__': 7, u'changes': {u'diff': u'--- \\n\\n+++ \\n\\n@@ -13,3 +13,4 @@\\n\\n touch /var/lock/subsys/local\\n mount  /home/data /data  --bind\\n mount /data/docker /var/lib/docker --bind\\n+/etc/init.d/zabbix_agentd start'}, u'__id__': u'start-file'}, u'file_|-zabbix-client-transport_|-/usr/local/src/zabbix-3.0.5-client.tar.gz_|-managed': {u'comment': u'The file /usr/local/src/zabbix-3.0.5-client.tar.gz is set to be changed', u'pchanges': {u'newfile': u'/usr/local/src/zabbix-3.0.5-client.tar.gz'}, u'name': u'/usr/local/src/zabbix-3.0.5-client.tar.gz', u'start_time': u'10:41:43.399380', u'result': None, u'duration': 9.981, u'__run_num__': 2, u'changes': {}, u'__id__': u'zabbix-client-transport'}, u'cmd_|-zabbix-start-sh_|-/etc/init.d/zabbix_agentd start_|-run': {u'comment': u'Command \"/etc/init.d/zabbix_agentd start\" would have been executed', u'name': u'/etc/init.d/zabbix_agentd start', u'start_time': u'10:41:43.439464', u'result': None, u'duration': 0.355, u'__run_num__': 6, u'changes': {}, u'__id__': u'zabbix-start-sh'}, u'group_|-zabbix-user-group_|-zabbix_|-present': {u'comment': u'Group zabbix set to be added', u'name': u'zabbix', u'start_time': u'10:41:43.380688', u'result': None, u'duration': 0.683, u'__run_num__': 0, u'changes': {}, u'__id__': u'zabbix-user-group'}, u'file_|-zabbix-file-copy_|-/usr/local/zabbix-3.0.5/etc/zabbix_agentd.conf_|-managed': {u'comment': u'The file /usr/local/zabbix-3.0.5/etc/zabbix_agentd.conf is set to be changed', u'pchanges': {u'newfile': u'/usr/local/zabbix-3.0.5/etc/zabbix_agentd.conf'}, u'name': u'/usr/local/zabbix-3.0.5/etc/zabbix_agentd.conf', u'start_time': u'10:41:43.410485', u'result': None, u'duration': 24.638, u'__run_num__': 4, u'changes': {}, u'__id__': u'zabbix-file-copy'}, u'cmd_|-zabbix-client-transport_|-cd /usr/local/src/ && tar -zxf zabbix-3.0.5-client.tar.gz -C /usr/local/_|-run': {u'comment': u'Command \"cd /usr/local/src/ && tar -zxf zabbix-3.0.5-client.tar.gz -C /usr/local/\" would have been executed', u'name': u'cd /usr/local/src/ && tar -zxf zabbix-3.0.5-client.tar.gz -C /usr/local/', u'start_time': u'10:41:43.410143', u'result': None, u'duration': 0.276, u'__run_num__': 3, u'changes': {}, u'__id__': u'zabbix-client-transport'}, u'file_|-zabbix-start-sh_|-/etc/init.d/zabbix_agentd_|-managed': {u'comment': u'The file /etc/init.d/zabbix_agentd is set to be changed', u'pchanges': {u'newfile': u'/etc/init.d/zabbix_agentd'}, u'name': u'/etc/init.d/zabbix_agentd', u'start_time': u'10:41:43.435245', u'result': None, u'duration': 3.886, u'__run_num__': 5, u'changes': {}, u'__id__': u'zabbix-start-sh'}}, u'192.168.2.147': {u'user_|-zabbix-user-group_|-zabbix_|-present': {u'comment': u'User zabbix set to be added', u'name': u'zabbix', u'start_time': u'10:41:43.649409', u'result': None, u'duration': 16.626, u'__run_num__': 1, u'changes': {}, u'__id__': u'zabbix-user-group'}, u'file_|-start-file_|-/etc/rc.local_|-append': {u'comment': u'File /etc/rc.local is set to be updated', u'pchanges': {}, u'name': u'/etc/rc.local', u'start_time': u'10:41:43.759598', u'result': None, u'duration': 2.015, u'__run_num__': 7, u'changes': {u'diff': u'--- \\n\\n+++ \\n\\n@@ -13,3 +13,4 @@\\n\\n touch /var/lock/subsys/local\\n mount  /home/data /data  --bind\\n mount /data/docker /var/lib/docker --bind\\n+/etc/init.d/zabbix_agentd start'}, u'__id__': u'start-file'}, u'file_|-zabbix-client-transport_|-/usr/local/src/zabbix-3.0.5-client.tar.gz_|-managed': {u'comment': u'The file /usr/local/src/zabbix-3.0.5-client.tar.gz is set to be changed', u'pchanges': {u'newfile': u'/usr/local/src/zabbix-3.0.5-client.tar.gz'}, u'name': u'/usr/local/src/zabbix-3.0.5-client.tar.gz', u'start_time': u'10:41:43.667990', u'result': None, u'duration': 20.692, u'__run_num__': 2, u'changes': {}, u'__id__': u'zabbix-client-transport'}, u'cmd_|-zabbix-start-sh_|-/etc/init.d/zabbix_agentd start_|-run': {u'comment': u'Command \"/etc/init.d/zabbix_agentd start\" would have been executed', u'name': u'/etc/init.d/zabbix_agentd start', u'start_time': u'10:41:43.758629', u'result': None, u'duration': 0.728, u'__run_num__': 6, u'changes': {}, u'__id__': u'zabbix-start-sh'}, u'group_|-zabbix-user-group_|-zabbix_|-present': {u'comment': u'Group zabbix set to be added', u'name': u'zabbix', u'start_time': u'10:41:43.647126', u'result': None, u'duration': 1.619, u'__run_num__': 0, u'changes': {}, u'__id__': u'zabbix-user-group'}, u'file_|-zabbix-file-copy_|-/usr/local/zabbix-3.0.5/etc/zabbix_agentd.conf_|-managed': {u'comment': u'The file /usr/local/zabbix-3.0.5/etc/zabbix_agentd.conf is set to be changed', u'pchanges': {u'newfile': u'/usr/local/zabbix-3.0.5/etc/zabbix_agentd.conf'}, u'name': u'/usr/local/zabbix-3.0.5/etc/zabbix_agentd.conf', u'start_time': u'10:41:43.690624', u'result': None, u'duration': 56.148, u'__run_num__': 4, u'changes': {}, u'__id__': u'zabbix-file-copy'}, u'cmd_|-zabbix-client-transport_|-cd /usr/local/src/ && tar -zxf zabbix-3.0.5-client.tar.gz -C /usr/local/_|-run': {u'comment': u'Command \"cd /usr/local/src/ && tar -zxf zabbix-3.0.5-client.tar.gz -C /usr/local/\" would have been executed', u'name': u'cd /usr/local/src/ && tar -zxf zabbix-3.0.5-client.tar.gz -C /usr/local/', u'start_time': u'10:41:43.689750', u'result': None, u'duration': 0.66, u'__run_num__': 3, u'changes': {}, u'__id__': u'zabbix-client-transport'}, u'file_|-zabbix-start-sh_|-/etc/init.d/zabbix_agentd_|-managed': {u'comment': u'The file /etc/init.d/zabbix_agentd is set to be changed', u'pchanges': {u'newfile': u'/etc/init.d/zabbix_agentd'}, u'name': u'/etc/init.d/zabbix_agentd', u'start_time': u'10:41:43.746988', u'result': None, u'duration': 11.198, u'__run_num__': 5, u'changes': {}, u'__id__': u'zabbix-start-sh'}}}\n    a={u'192.168.2.147': {u'file_|-nginx-config_|-/usr/local/nginx/conf/nginx.conf_|-managed': {u'comment': u'The file /usr/local/nginx/conf/nginx.conf is set to be changed', u'pchanges': {u'newfile': u'/usr/local/nginx/conf/nginx.conf'}, u'retcode': 2, u'start_time': u'12:00:11.704011', u'__id__': u'nginx-config', u'result': None, u'duration': 62.022, u'__run_num__': 6, u'changes': {}, u'name': u'/usr/local/nginx/conf/nginx.conf'}, u'file_|-/usr/local/nginx/conf/vhosts/_|-/usr/local/nginx/conf/vhosts/_|-directory': {u'comment': u'The following files will be changed:\\n/usr/local/nginx/conf/vhosts: directory - new\\n', u'pchanges': {u'/usr/local/nginx/conf/vhosts': {u'directory': u'new'}}, u'retcode': 2, u'start_time': u'12:00:11.766317', u'__id__': u'/usr/local/nginx/conf/vhosts/', u'result': None, u'duration': 0.813, u'__run_num__': 7, u'changes': {}, u'name': u'/usr/local/nginx/conf/vhosts/'}, u'file_|-nginx-install_|-/usr/local/src/nginx-1.2.0.tar.gz_|-managed': {u'comment': u'Source file salt://nginx/files/nginx-1.2.0.tar.gz not found', u'_stamp': u'2016-12-15T12:02:16.749601', u'pchanges': [False, u'Source file salt://nginx/files/nginx-1.2.0.tar.gz not found'], u'return': u'Error: file.managed', u'retcode': 2, u'success': False, u'start_time': u'12:00:11.690524', u'jid': u'20161215200215675300', u'duration': 12.813, u'result': False, u'__id__': u'nginx-install', u'fun': u'state.sls', u'__run_num__': 4, u'changes': {}, u'id': u'192.168.2.147', u'name': u'/usr/local/src/nginx-1.2.0.tar.gz'}, u'user_|-www-user-group_|-www_|-present': {u'comment': u'User www set to be added', u'retcode': 2, u'start_time': u'12:00:11.674525', u'__id__': u'www-user-group', u'result': None, u'duration': 15.774, u'__run_num__': 3, u'changes': {}, u'name': u'www'}, u'file_|-pcre-install_|-/usr/local/src/pcre-8.37.tar.gz_|-managed': {u'comment': u'The file /usr/local/src/pcre-8.37.tar.gz is set to be changed', u'pchanges': {u'newfile': u'/usr/local/src/pcre-8.37.tar.gz'}, u'retcode': 2, u'start_time': u'12:00:11.641509', u'__id__': u'pcre-install', u'result': None, u'duration': 22.872, u'__run_num__': 0, u'changes': {}, u'name': u'/usr/local/src/pcre-8.37.tar.gz'}, u'file_|-/usr/local/nginx/conf/vhosts/www.test.com.conf_|-/usr/local/nginx/conf/vhosts/www.test.com.conf_|-managed': {u'comment': u'The file /usr/local/nginx/conf/vhosts/www.test.com.conf is set to be changed', u'pchanges': {u'newfile': u'/usr/local/nginx/conf/vhosts/www.test.com.conf'}, u'retcode': 2, u'start_time': u'12:00:11.767427', u'__id__': u'/usr/local/nginx/conf/vhosts/www.test.com.conf', u'result': None, u'duration': 431.954, u'__run_num__': 8, u'changes': {}, u'name': u'/usr/local/nginx/conf/vhosts/www.test.com.conf'}, u'cmd_|-nginx-install_|-cd /usr/local/src/ && tar zxf nginx-1.8.0.tar.gz && cd nginx-1.8.0 && ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_stub_status_module --with-file-aio --with-http_dav_module --with-pcre=/usr/local/src/pcre-8.37 && make && make install && chown -R www. /usr/local/nginx_|-run': {u'comment': u'One or more requisite failed: nginx.install.nginx-install', u'__run_num__': 5, u'__sls__': u'nginx.install', u'changes': {}, u'result': False}, u'file_|-nginx-service_|-/usr/lib/systemd/system/nginx.service_|-managed': {u'comment': u'The file /usr/lib/systemd/system/nginx.service is set to be changed', u'pchanges': {u'newfile': u'/usr/lib/systemd/system/nginx.service'}, u'retcode': 2, u'start_time': u'12:00:12.199726', u'__id__': u'nginx-service', u'result': None, u'duration': 13.078, u'__run_num__': 9, u'changes': {}, u'name': u'/usr/lib/systemd/system/nginx.service'}, u'file_|-log_logrotate_|-/etc/logrotate.d/logrotate_nginx_|-managed': {u'comment': u'The file /etc/logrotate.d/logrotate_nginx is set to be changed', u'pchanges': {u'newfile': u'/etc/logrotate.d/logrotate_nginx'}, u'retcode': 2, u'start_time': u'12:00:12.229231', u'__id__': u'log_logrotate', u'result': None, u'duration': 13.148, u'__run_num__': 11, u'changes': {}, u'name': u'/etc/logrotate.d/logrotate_nginx'}, u'cmd_|-pcre-install_|-cd /usr/local/src/ && tar zxf pcre-8.37.tar.gz && cd pcre-8.37 && ./configure --prefix=/usr/local/pcre  && make && make install_|-run': {u'comment': u'Command \"cd /usr/local/src/ && tar zxf pcre-8.37.tar.gz && cd pcre-8.37 && ./configure --prefix=/usr/local/pcre  && make && make install\" would have been executed', u'retcode': 2, u'start_time': u'12:00:11.665282', u'__id__': u'pcre-install', u'result': None, u'duration': 6.168, u'__run_num__': 1, u'changes': {}, u'name': u'cd /usr/local/src/ && tar zxf pcre-8.37.tar.gz && cd pcre-8.37 && ./configure --prefix=/usr/local/pcre  && make && make install'}, u'cmd_|-nginx-service_|-chmod +x /usr/lib/systemd/system/nginx.service && systemctl enable nginx.service && systemctl start nginx.service_|-run': {u'comment': u'Command \"chmod +x /usr/lib/systemd/system/nginx.service && systemctl enable nginx.service && systemctl start nginx.service\" would have been executed', u'retcode': 2, u'start_time': u'12:00:12.213134', u'__id__': u'nginx-service', u'result': None, u'duration': 15.835, u'__run_num__': 10, u'changes': {}, u'name': u'chmod +x /usr/lib/systemd/system/nginx.service && systemctl enable nginx.service && systemctl start nginx.service'}, u'group_|-www-user-group_|-www_|-present': {u'comment': u'Group www set to be added', u'name': u'www', u'start_time': u'12:00:11.672088', u'result': None, u'duration': 1.803, u'__run_num__': 2, u'changes': {}, u'__id__': u'www-user-group'}}}\n    JobResultFromat(a)\n\n"
  },
  {
    "path": "saltadmin/__init__.py",
    "content": ""
  },
  {
    "path": "saltadmin/admin.py",
    "content": "from django.contrib import admin\nfrom saltadmin.models import *\n\nclass SaltJobsModels(admin.ModelAdmin):\n    list_display = ('jid','args','function','target','startTime','saltserver','user')\n    search_fields = ('function','jid')\n\n\nclass CmdRunLogModels(admin.ModelAdmin):\n    list_display = ('user','time','target','cmd','total','runsuccess','runerror')\n    search_fields = ('user','cmd')\n\nclass MinionGroupModels(admin.ModelAdmin):\n    list_display = ('groupname',)\n    filter_horizontal = ('minions', )\n\n\nadmin.site.register(SaltJobs,SaltJobsModels)\nadmin.site.register(CmdRunLog,CmdRunLogModels)\nadmin.site.register(MinionGroup,MinionGroupModels)\nadmin.site.register(Modules)\n"
  },
  {
    "path": "saltadmin/apps.py",
    "content": "from __future__ import unicode_literals\n\nfrom django.apps import AppConfig\n\n\nclass SaltadminConfig(AppConfig):\n    name = 'saltadmin'\n"
  },
  {
    "path": "saltadmin/forms.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\n\nfrom django import forms\nfrom saltadmin.models import SaltServer,Minions\n\n\nclass KeyManager(forms.Form):\n    status = forms.ChoiceField(choices=Minions.Status,widget=forms.Select(attrs={'class':'form-control'}))\n\n\n\nclass CheckSaltServer(forms.ModelForm):\n    url=forms.URLField(required=True,error_messages={'required': u'请输入一个URL格式'},\n                       widget=forms.TextInput(attrs={'class':'form-control','placeholder': 'http://127.0.0.1',}))\n\n    username = forms.CharField(required=True,error_messages={'required':u'请输入API用户名'},\n                               widget=forms.TextInput(attrs={'class':'form-control','placeholder': 'username',}))\n\n    password = forms.CharField(required=True, error_messages={'required': u'请输入API验证密码'},\n                               widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'password', }))\n\n\n    # def clean(self):\n    #     cleaned_data = sum(CheckSaltServer,self).clean()\n    #     value = cleaned_data.get('url')\n    #     try:\n    #         SaltServer.objects.get(url=value)\n    #         self._errors['url'] = self.error_class([\"%s url 信息已存在\" % value])\n    #     except SaltServer.DoesNotExist:\n    #         pass\n    #     return cleaned_data\n\n\n    class Meta:\n        model = SaltServer\n        exclude= ('id',)\n        widgets = {\n            'role': forms.Select(attrs={'class': 'form-control'}),\n        }\n\n\n\n\n\n"
  },
  {
    "path": "saltadmin/migrations/__init__.py",
    "content": ""
  },
  {
    "path": "saltadmin/models.py",
    "content": "#coding:utf8\nfrom __future__ import unicode_literals\n\nfrom django.db import models\n\nclass SaltServer(models.Model):\n    Role = (\n    ('Master', 'Master'),\n    ('Backend', 'Backend'),\n    )\n    url = models.URLField(max_length=100,verbose_name=u'URL地址')\n    username = models.CharField(max_length=50, verbose_name=u'用户名')\n    password = models.CharField(max_length=50,verbose_name=u'密码')\n    role = models.CharField(choices=Role,max_length=20,default='Master',verbose_name=u'角色')\n\n    def __unicode__(self):\n        return u\"%s - %s\" %(self.url,self.role)\n\n    class Meta:\n        verbose_name = u'Salt服务器'\n        verbose_name_plural = u'Salt服务器列表'\n        permissions = (\n            (\"salt_index_view\", \"Can view %s\"  % verbose_name),\n        )\n\n\nclass Modules(models.Model):\n    name = models.CharField(max_length=20,verbose_name=u'Salt模块名称')\n    models_site = models.CharField(max_length=50,null=True,blank=True,verbose_name=u'Salt模块参数')\n\n    def __unicode__(self):\n        return self.name\n\n    class Meta:\n        verbose_name = u'Salt软件'\n        verbose_name_plural = u'Salt软件'\n\n\n'''\nclass Command(models.Model):\n    cmd = models.CharField(max_length=100,verbose_name=u'Salt命令')\n    doc = models.TextField(max_length=2000,blank=True,verbose_name=u'帮助文档')\n    module = models.ForeignKey(Module,verbose_name=u'所属模块')\n\n    def __unicode__(self):\n        return  u\"%s - %s\"%(self.module,self.cmd)\n\n    class Meta:\n        verbose_name = u'Salt命令'\n        verbose_name_plural = u'Salt命令列表'\n        unique_together = (\"module\", \"cmd\")\n'''\n\nclass Minions(models.Model):\n    Status = (\n    ('Accepted', 'Accepted'),\n    ('Unaccepted', 'Unaccepted'),\n    ('Rejected', 'Rejected'),\n    )\n    minion = models.CharField(max_length=50,verbose_name=u'客户端',unique=True)\n    saltserver = models.ForeignKey(SaltServer,verbose_name=u'所属Salt服务器')\n    status = models.CharField(choices=Status,max_length=20,default='Unknown',verbose_name=u'Key状态')\n    create_date=models.DateTimeField(auto_now_add=True,verbose_name=u'创建时间')\n\n    def __unicode__(self):\n        return self.minion\n\n    class Meta:\n        verbose_name = u'Salt客户端'\n        verbose_name_plural = u'Salt客户端列表'\n\n\nclass MinionStatus(models.Model):\n    minion = models.OneToOneField(Minions)\n    minion_status = models.CharField(max_length=20,verbose_name=u'在线状态')\n    # 上次检测时间\n    alive_time_last = models.DateTimeField(auto_now=True,null=True)\n    # 当前检测时间\n    alive_time_now = models.DateTimeField(auto_now=True,null=True)\n\nclass MinionGroup(models.Model):\n    groupname = models.CharField(u'Minion组',max_length=50,default='default')\n    minions = models.ManyToManyField(Minions,verbose_name=u'Minions',blank=True)\n\n    def __unicode__(self):\n        return self.groupname\n\n    class Meta:\n        verbose_name = u'Minion组'\n        verbose_name_plural = u'Minion组'\n\n\nclass CmdRunLog(models.Model):\n    user=models.CharField(max_length=30)\n    time=models.DateTimeField(auto_now_add=True,null=True)\n    target=models.CharField(max_length=500)\n    cmd=models.CharField(max_length=500)\n    total=models.IntegerField()\n    runsuccess = models.IntegerField(default=0)\n    runerror = models.IntegerField(default=0)\n    runresult = models.TextField(max_length=65535,null=True,blank=True)\n\n    class Meta:\n        verbose_name = u'命令执行日志'\n        verbose_name_plural = u'命令执行日志'\n\n\nclass SaltJobs(models.Model):\n    jid = models.CharField(max_length=50,unique=True)\n    args = models.CharField(max_length=50,null=True,blank=True)\n    function = models.CharField(max_length=50)\n    startTime = models.CharField(max_length=100)\n    target = models.CharField(max_length=500)\n    user = models.CharField(max_length=50)\n    saltserver = models.CharField(max_length=100,null=True,blank=True)\n\n    class Meta:\n        verbose_name = u'Jobs列表'\n        verbose_name_plural = u'Jobs列表'\n\n\n\nclass ModuleDeployLog(models.Model):\n    user=models.CharField(max_length=50)\n    time=models.DateTimeField()\n    target=models.CharField(max_length=100)\n    application=models.CharField(max_length=100)\n    #成功的主机\n    success_hosts=models.CharField(max_length=500)\n    #失败的主机\n    failed_hosts=models.CharField(max_length=500)\n    #执行总共结果\n    total=models.IntegerField()\n    #执行过程\n    log=models.TextField()\n    #持续时间\n    duration=models.CharField(max_length=500)\n    class Meta:\n        verbose_name = u'软件部署'\n        verbose_name_plural = u'软件部署'"
  },
  {
    "path": "saltadmin/tests.py",
    "content": "from django.test import TestCase\n\n# Create your tests here.\n"
  },
  {
    "path": "saltadmin/urls.py",
    "content": "from django.conf.urls import url\n\nfrom saltadmin.views import (KeyList,Minion_Status,SoftInstall,JobList,RemoteCmd,SaltMasterList,\n                              SaltMinionGrains,CmdResult,jobdetail,DeployResult,SaltMasterDelete,\n                              SalMasterChange\n                             )\n\nurlpatterns = [\n    url(r'keylist/', KeyList, name='KeyList'),\n    url(r'minion/status/',Minion_Status,name='Minion_Status'),\n    url(r'minion/softinstall/',SoftInstall,name='SoftInstall'),\n    url(r'job/list/(?P<page>\\d+)',JobList,name='JobList'),\n    url(r'cmd/$',RemoteCmd,name='RemoteCmd'),\n    url(r'master/$',SaltMasterList,name='SaltMasterList'),\n    url(r'master/delete/(?P<masterid>\\d+)$',SaltMasterDelete,name='SaltMasterDelete'),\n    url(r'master/change/(?P<masterid>\\d+)$',SalMasterChange,name='SalMasterChange'),\n    url(r'grains/$',SaltMinionGrains,name='SaltMinionGrains'),\n    url(r'cmdresult/(?P<jid>\\d+)$',CmdResult,name='CmdResult'),\n    url(r'deployresult/(?P<jid>\\d+)$',DeployResult,name='DeployResult'),\n    url(r'job/detail/$',jobdetail,name='jobdetail'),\n]\n"
  },
  {
    "path": "saltadmin/utils.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\nimport commands\nimport os\n\ndef get_system_info():\n    cmd_get_cpu_sockect=r\"lscpu|grep Socket|awk '{print $NF}'\"\n    cmd_get_cpu_cores=r\"cat /proc/cpuinfo|grep processor|wc -l\"\n    cmd_get_mem_total=r\"free -m |head -n 2|tail -n 1|awk '{print $2}'\"\n    cmd_get_mem_used=r\"free -m |tail -n 2|head -n 1|awk '{print $3}'\"\n    cmd_get_users_num=r\"w -h |wc -l\"\n    cmd_get_uptime=r\"uptime |awk -F',' '{print $1}'\"\n    cpu_sockets=commands.getoutput(cmd_get_cpu_sockect)\n    res=os.system('lscpu &>/dev/null')\n    if res != 0:\n        cpu_sockets=1  #如果没有lscpu命令，默认的CPU个数为1个\n    cpu_cores=commands.getoutput(cmd_get_cpu_cores)\n    mem_total=commands.getoutput(cmd_get_mem_total)\n    mem_used=commands.getoutput(cmd_get_mem_used)\n    users=commands.getoutput(cmd_get_users_num)\n    uptime=commands.getoutput(cmd_get_uptime)\n    mem_percentage=round(float(mem_used)/float(mem_total)*100,2)\n    mem_left_percentage=100-mem_percentage\n    info_dict={'cpu_sockets':cpu_sockets,\n               'cpu_cores':cpu_cores,\n               'mem_total':mem_total,\n               'mem_used':mem_used,\n               'mem_percentage':mem_percentage,\n               'users':users,\n               'uptime':uptime,\n               'mem_left_percentage':mem_left_percentage}\n\n    return info_dict"
  },
  {
    "path": "saltadmin/views.py",
    "content": "#coding:utf8\nfrom django.shortcuts import render\nfrom django.http import HttpResponse,HttpResponseRedirect\nfrom django.core import serializers\nfrom django.contrib.auth.decorators import login_required\nfrom django.contrib.auth.decorators import permission_required\nfrom saltadmin.models import *\nfrom Publicapi.saltstackapi.SaltConApi import SaltApi\nimport json\nfrom django.db.models import Q\nfrom saltadmin.forms import CheckSaltServer,KeyManager\nfrom webapp.Extends import PageList\nimport yaml\nfrom saltadmin.Minions_Controller import JobResultFromat\nfrom webapp.models import Operation\n\n\n\n\n@login_required()\ndef SaltMasterList(request):\n    usersession = request.session.get('user_id')\n    form = CheckSaltServer()\n    if request.method == 'POST':\n        form = CheckSaltServer(request.POST)\n        if form.is_valid():\n            form.save()\n            return HttpResponseRedirect('/salt/master/')\n        else:\n            form = form\n    SaltMasterData = SaltServer.objects.all()\n    Role=SaltServer.Role\n    return render(request, 'saltadmin/saltmaster_list.html', locals())\n\n\n@login_required()\ndef SaltMasterDelete(request,masterid):\n    user_name = request.session.get('user_name')\n    if request.method == 'GET':\n        SaltServer.objects.get(id=masterid).delete()\n        Operation.objects.create(Opuser=user_name, Opaction=u'删除salt主机')\n        msg = {'msginfo': u'Salt主机及所有管理信息已经删除成功!!'}\n        return HttpResponse(json.dumps(msg))\n\n\n@login_required()\ndef SalMasterChange(request,masterid):\n    user_name = request.session.get('user_name')\n    if request.method == 'POST':\n        url = request.POST.get('url')\n        username  = request.POST.get('username')\n        password = request.POST.get('password')\n        role = request.POST.get('role')\n\n        Changeserver = SaltServer.objects.get(id=masterid)\n        Changeserver.url = url\n        Changeserver.username = username\n        Changeserver.password = password\n        Changeserver.role = role\n        Changeserver.save()\n        Operation.objects.create(Opuser=user_name, Opaction=u'修改salt主机信息')\n        msg = {'msginfo': u'Master修改成功!!!!',}\n        return HttpResponse(json.dumps(msg))\n\n    else:\n        Changeserver = SaltServer.objects.get(id=masterid)\n        data = {'url': Changeserver.url,'username':Changeserver.username,'password':Changeserver.password,'role':Changeserver.role }\n        return HttpResponse(json.dumps(data))\n\n\n\n\n\n\n\n\n@login_required()\ndef KeyList(request):\n    usersession = request.session.get('user_id')\n    user_name = request.session.get('user_name')\n    if request.method == 'GET':\n        Accepted = Minions.objects.filter(status='Accepted')\n        Unaccepted = Minions.objects.filter(status='Unaccepted')\n        Rejected = Minions.objects.filter(status='Rejected')\n        froms=KeyManager()\n        return render(request,'saltadmin/key_list.html',locals())\n\n\n    if request.method == 'POST':\n        minion = request.POST.get('minion')\n        status = request.POST.get('status')\n        Minion_data=Minions.objects.get(minion=minion)\n        Minion_data.status = status\n        Minion_data.save()\n        Operation.objects.create(Opuser=user_name, Opaction=u'修改 minion Key状态 %s to %s' %(Minion_data.minion,status))\n        url = Minion_data.saltserver.url\n\n        username = Minion_data.saltserver.username\n        password = Minion_data.saltserver.password\n\n        salt = SaltApi(url, username, password)\n        if status == 'Accepted':\n            ret = salt.AcceptKey(minion)\n        elif status == 'Unaccepted':\n            ret = salt.DeleteKey(minion)\n        elif status == 'Rejected':\n            ret = salt.RejectKey(minion)\n\n        return HttpResponse('OK')\n\n\n\n\n\n\n@login_required()\ndef Minion_Status(request):\n    usersession = request.session.get('user_id')\n    if request.method == 'GET':\n        SaltMinionData = MinionStatus.objects.filter(minion__status='Accepted')\n        return render(request,'saltadmin/minion_status.html',locals())\n\n\n\n\n\n\n\n\n@login_required()\ndef SoftInstall(request):\n    usersession = request.session.get('user_id')\n    user_name = request.session.get('user_name')\n    if request.method == 'GET':\n        SoftModuleData = Modules.objects.all()\n        GroupData = MinionGroup.objects.all()\n        # hosts = \"\"\"[ {type: 1, list: [{ text: 'yang', id: 1}, {text: 'asdasd',id: 4}]}, }]\"\"\"\n\n        groupall = []\n        for g in GroupData:\n            group = {}\n            list = []\n            for m in g.minions.all():\n                dir = {}\n                dir['text'] = m.minion\n                dir['id'] = m.minion\n                list.append(dir)\n\n            group['type'] = g.id\n            group['list'] = list\n            groupall.append(group)\n        groupall = json.dumps(groupall)\n\n        return render(request,'saltadmin/saltmodule_deploy.html',locals())\n\n    else:\n        if not request.POST.get('minion'):\n            minions_id = request.POST.get('minion_group')\n            minions_data=MinionGroup.objects.get(id=minions_id).minions.all()\n        else:\n            minions_data = request.POST.getlist('minion')\n\n        minions_list = ''\n        for m in minions_data:\n            minions_list += str(m) + ','\n        minions_list = minions_list.strip(',')\n\n        software = request.POST.getlist('software')\n        salt_env = request.POST.get('env')\n\n        soft=''\n        for i in software:\n            soft += i + ','\n        soft=soft.strip(',')\n\n\n        saltm = Minions.objects.get(minion=minions_list.split(',')[0])\n\n        url = saltm.saltserver.url\n        username = saltm.saltserver.username\n        password = saltm.saltserver.password\n\n        salt = SaltApi(url, username, password)\n\n        jid = salt.Softwarete_deploy(minions_list,arg=[\"saltenv=%s\" %(salt_env), str(soft), 'test=True'])\n\n        Operation.objects.create(Opuser=user_name, Opaction=u'部署软件 %s' %soft)\n        #savelog = CmdRunLog.objects.create(user=user_name, target=minions_list, cmd=cmd, total=len(minions_list.split(',')))\n\n        ret={'jid':jid,'minion':minions_list,'savelogid':1}\n        return  HttpResponse(json.dumps(ret))\n\n\n\n\n\n\n@login_required()\ndef JobList(request,page):\n    usersession = request.session.get('user_id')\n    if request.method == 'GET':\n\n        # 分页代码\n        (page, start, end, per_item) = PageList.PageCount(page)\n        count = SaltJobs.objects.filter(~Q(function='test.ping')).count()\n        result = SaltJobs.objects.filter(~Q(function='test.ping')).order_by('-jid')[start:end]\n        url = \"/salt/job/list\"\n        if count % per_item == 0:\n            all_pages_count = count / per_item\n        else:\n            all_pages_count = count / per_item + 1\n        page = PageList.Page(page, url, all_pages_count)\n        ret = {'SaltMaster_data': result,\n               'count': count,\n               'page': page,\n               'usersession': usersession}\n\n        return render(request,'saltadmin/saltjob_list.html',ret)\n\n\n@login_required()\ndef jobdetail(request):\n    if request.method == 'GET':\n        jid = request.GET.get('jid')\n        print jid\n        jiddata = SaltJobs.objects.get(jid=jid)\n        masterdata = SaltServer.objects.get(url=jiddata.saltserver)\n        url = masterdata.url\n        username =masterdata.username\n        password = masterdata.password\n\n        salt = SaltApi(url, username, password)\n        resultdata = salt.salt_runner(jid)\n        return HttpResponse(json.dumps(resultdata))\n\n\n\n\n\n@login_required()\ndef RemoteCmd(request):\n    usersession = request.session.get('user_id')\n    user_name = request.session.get('user_name')\n\n    if request.method == 'GET':\n        GroupData = MinionGroup.objects.all()\n        #hosts = \"\"\"[ {type: 1, list: [{ text: 'yang', id: 1}, {text: 'asdasd',id: 4}]}, }]\"\"\"\n\n        groupall=[]\n        for g in GroupData:\n            group={}\n            list = []\n            for m in g.minions.all():\n                dir = {}\n                dir['text']  = m.minion\n                dir['id'] = m.minion\n                list.append(dir)\n\n            group['type'] = g.id\n            group['list'] = list\n            groupall.append(group)\n        groupall=json.dumps(groupall)\n        return render(request,'saltadmin/salt_cmd.html',locals())\n\n    else:\n        if not request.POST.get('minion'):\n            minions_id = request.POST.get('minion_group')\n            minions_data=MinionGroup.objects.get(id=minions_id).minions.all()\n\n        else:\n            minions_data = request.POST.getlist('minion')\n\n        minions_list = ''\n        for m in minions_data:\n            minions_list += str(m) + ','\n        minions_list = minions_list.strip(',')\n\n\n        cmd =request.POST.get('cmd')\n        #必须是同一台master上的才能为一个组，这样只需要查询一个就可\n\n        saltm = Minions.objects.get(minion=minions_list.split(',')[0])\n        url = saltm.saltserver.url\n        username = saltm.saltserver.username\n        password = saltm.saltserver.password\n\n        salt = SaltApi(url, username, password)\n        jid = salt.shell_remote_execution(minions_list, cmd)\n        Operation.objects.create(Opuser=user_name, Opaction=u'执行命令 %s' %cmd)\n\n        savelog = CmdRunLog.objects.create(user=user_name, target=minions_list, cmd=cmd, total=len(minions_list.split(',')))\n\n\n        ret={'jid':jid,'minion':minions_list,'savelogid':savelog.id}\n        return  HttpResponse(json.dumps(ret))\n\n\n\n\n\n@login_required()\ndef CmdResult(request,jid):\n    if request.method == 'GET':\n        minions_list = request.GET.get('minion')\n        savelogid = request.GET.get('savelogid')\n\n        saltm = Minions.objects.get(minion=minions_list.split(',')[0])\n        url = saltm.saltserver.url\n        username = saltm.saltserver.username\n        password = saltm.saltserver.password\n\n        salt = SaltApi(url,username,password)\n        resultdata = salt.salt_runner(jid)\n\n        print savelogid\n        logs = CmdRunLog.objects.get(id=savelogid)\n        logs.runresult=resultdata\n        logs.runsuccess=len(resultdata)\n        logs.save()\n\n        ret={'minion':minions_list,'resultdata':resultdata}\n\n        return HttpResponse(json.dumps(ret))\n\n\n\n\n@login_required()\ndef DeployResult(request,jid):\n    if request.method == 'GET':\n        minions_list = request.GET.get('minion')\n        savelogid = request.GET.get('savelogid')\n\n        saltm = Minions.objects.get(minion=minions_list.split(',')[0])\n\n        url = saltm.saltserver.url\n        username = saltm.saltserver.username\n        password = saltm.saltserver.password\n\n        salt = SaltApi(url,username,password)\n        resultdata = salt.salt_runner(jid)\n        resultdata=JobResultFromat(resultdata)\n\n        #print savelogid\n        #logs = CmdRunLog.objects.get(id=savelogid)\n        #logs.runresult=resultdata\n        #logs.runsuccess=len(resultdata)\n        #logs.save()\n        #print yaml.load_all(resultdata)\n\n        ret={'minion':minions_list,'resultdata':resultdata}\n\n        return HttpResponse(json.dumps(ret))\n\n\n\n@login_required()\ndef SaltMinionGrains(request):\n    id = request.GET.get('minion')\n    action =  request.GET.get('action')\n    Minion_data=MinionStatus.objects.get(id=id)\n    url = Minion_data.minion.saltserver.url\n    username = Minion_data.minion.saltserver.username\n    password = Minion_data.minion.saltserver.password\n    salt = SaltApi(url,username,password)\n\n    if str(action) == 'grains':\n        Data = salt.grainsall(str(Minion_data.minion))\n    elif str(action) == 'pillar':\n        Data = salt.pillarall(str(Minion_data.minion))\n    else:\n        Data={\"msg\": '无法查询'}\n    return HttpResponse(json.dumps(Data))\n\n\n\n\n\n\n\n"
  },
  {
    "path": "servermanager/__init__.py",
    "content": "\n\n"
  },
  {
    "path": "servermanager/admin.py",
    "content": "#coding:utf8\n\nfrom django.contrib import admin\nfrom django.forms import ModelForm,TextInput,Textarea\nfrom django.contrib.admin import ModelAdmin\n\n#from suit.widgets import SuitDateWidget, SuitTimeWidget, SuitSplitDateTimeWidget\nfrom servermanager.models import *\nfrom import_export import resources\nfrom django.forms import ModelForm\n\n#导入和导出\nfrom import_export.admin import ImportExportModelAdmin\n\n\n\n#定义导出的内容\nclass ServerResource(resources.ModelResource):\n    class Meta:\n        model = Server\n\nclass AssetsResource(resources.ModelResource):\n    class Meta:\n        model = Assets\n\n'''\nclass AssetsTimeForm(ModelForm):\n    class Meta:\n        widgets = {\n            'euse_time': SuitDateWidget,\n            'suse_time': SuitDateWidget,\n        }'''\n\n# Register your models here.\nclass AssetsAdmin(ImportExportModelAdmin):\n    resource_class = AssetsResource\n    #form = AssetsTimeForm\n    list_display = ('id','host_name','device_type','device_number','IDC','status','business','buy_time','buy_type','price','admin')\n    list_filter = ('IDC','business','status','device_type')\n    search_fields = ['hostname','id']\n\n    fieldsets = (\n        ('基本信息', {'fields': ('host_name', 'device_type', 'device_number','business','buy_type', 'IDC','status', 'admin','provider',)}),\n        ('其它信息', {'fields': ('Warranty','buy_time', 'suse_time', 'euse_time','price','description')}),\n    )\n\n\nclass CpuModels(admin.ModelAdmin):\n    list_display = ('id','uuid','cpu_mhz','model','Architecture')\n    list_display_links = ('uuid',)\n    list_editable = ('cpu_mhz',)\n\nclass DiskModels(admin.ModelAdmin):\n    search_fields = ['parent_sn']\n    list_display = ('id','uuid', 'capacity','disk_type','Firm')\n\nclass NicModels(admin.ModelAdmin):\n    search_fields = ('ip',)\n    list_display = ('id','uuid','name','ip','model')\n    list_display_links = ('uuid',)\n\nclass SoftwareModels(admin.ModelAdmin):\n    list_display = ('id','name','version')\n\nclass DeviceTypeModels(admin.ModelAdmin):\n    search_fields = ('name',)\n    list_display = ('id','name',)\n\nclass BusinessModels(admin.ModelAdmin):\n    list_display = ('id','name',)\n    search_fields = ('name',)\n    list_editable = ('name',)\n\nclass ProviderModels(admin.ModelAdmin):\n    list_display = ('id','provider_name', 'address', 'contacts', 'phone')\n\nclass ServerModels(admin.ModelAdmin):\n    list_display = ('id','Assets','Firm','cpu','hostname','saltid','mem','swap','system','version','platform')\n    list_display_links = ('Assets',)\n\n    def get_idc(self, obj):\n        return obj.Assets.IDC\n    get_idc.short_description = '资产'\n\n    filter_horizontal = ('disk','nic','software')\n\nclass IdcModels(admin.ModelAdmin):\n    search_fields = ('idc_name',)\n    list_display = ('idc_name','address','floor','contacts','phone')\n\n\nadmin.site.register(Assets,AssetsAdmin)\nadmin.site.register(Server,ServerModels)\nadmin.site.register(DeviceType,DeviceTypeModels)\nadmin.site.register(Business,BusinessModels)\nadmin.site.register(Cpu,CpuModels)\nadmin.site.register(Disk,DiskModels)\nadmin.site.register(IDC,IdcModels)\nadmin.site.register(Software,SoftwareModels)\nadmin.site.register(NIC,NicModels)\nadmin.site.register(Provider,ProviderModels)\n\n\n\n"
  },
  {
    "path": "servermanager/apps.py",
    "content": "from __future__ import unicode_literals\n\nfrom django.apps import AppConfig\n\n\nclass ServermanagerConfig(AppConfig):\n    name = 'servermanager'\n"
  },
  {
    "path": "servermanager/migrations/0001_initial.py",
    "content": "# -*- coding: utf-8 -*-\n# Generated by Django 1.9.9 on 2016-11-21 17:40\nfrom __future__ import unicode_literals\n\nfrom django.db import migrations, models\nimport django.db.models.deletion\n\n\nclass Migration(migrations.Migration):\n\n    initial = True\n\n    dependencies = [\n    ]\n\n    operations = [\n        migrations.CreateModel(\n            name='Assets',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('host_name', models.CharField(max_length=128, null=True, unique=True, verbose_name='\\u8bbe\\u5907\\u540d')),\n                ('device_number', models.CharField(max_length=128, unique=True, verbose_name='\\u8bbe\\u5907\\u7f16\\u53f7')),\n                ('Warranty', models.SmallIntegerField(verbose_name='\\u4fdd\\u4fee\\u671f')),\n                ('buy_time', models.CharField(blank=True, max_length=128, verbose_name='\\u8d2d\\u4e70\\u65e5\\u671f')),\n                ('buy_type', models.SmallIntegerField(blank=True, choices=[(1, '\\u516c\\u53f8\\u5185\\u8d2d'), (2, '\\u5458\\u5de5\\u81ea\\u8d2d')], verbose_name='\\u8d2d\\u4e70\\u65b9\\u5f0f')),\n                ('price', models.IntegerField(blank=True, verbose_name='\\u8d2d\\u4e70\\u4ef7\\u683c')),\n                ('suse_time', models.DateField(max_length=128, null=True, verbose_name='\\u5f00\\u59cb\\u4f7f\\u7528\\u65f6\\u95f4')),\n                ('euse_time', models.DateField(max_length=128, null=True, verbose_name='\\u622a\\u81f3\\u4f7f\\u7528\\u65f6\\u95f4')),\n                ('status', models.SmallIntegerField(blank=True, choices=[(1, '\\u6b63\\u5728\\u4f7f\\u7528'), (2, '\\u672a\\u4f7f\\u7528'), (3, '\\u8bbe\\u5907\\u6545\\u969c'), (4, '\\u5e93\\u5b58\\u5907\\u7528')], verbose_name='\\u72b6\\u6001')),\n                ('create_time', models.DateTimeField(auto_now_add=True, null=True, verbose_name='\\u8d44\\u4ea7\\u521b\\u5efa\\u65f6\\u95f4')),\n                ('devicetag', models.CharField(blank=True, max_length=255)),\n                ('description', models.TextField(blank=True, max_length=255, verbose_name='\\u5907\\u6ce8')),\n            ],\n            options={\n                'verbose_name': '\\u8d44\\u4ea7\\u8868\\u7ba1\\u7406',\n                'verbose_name_plural': '\\u8d44\\u4ea7\\u8868\\u7ba1\\u7406',\n                'permissions': (('cmdb_assets_view', 'Can view \\u8d44\\u4ea7\\u8868\\u7ba1\\u7406'), ('assets_index_view', '\\u8d44\\u4ea7\\u7ba1\\u7406')),\n            },\n        ),\n        migrations.CreateModel(\n            name='Business',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('name', models.CharField(blank=True, max_length=128, unique=True, verbose_name='\\u4e1a\\u52a1\\u540d')),\n                ('memo', models.CharField(blank=True, max_length=64, verbose_name='\\u5907\\u6ce8')),\n            ],\n            options={\n                'verbose_name': '\\u4e1a\\u52a1\\u5217\\u8868',\n                'verbose_name_plural': '\\u4e1a\\u52a1\\u5217\\u8868',\n                'permissions': (('cmdb_devicetype_view', 'Can view \\u4e1a\\u52a1\\u5217\\u8868'),),\n            },\n        ),\n        migrations.CreateModel(\n            name='Cpu',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('uuid', models.CharField(blank=True, max_length=64, verbose_name='UUID\\u53f7')),\n                ('parent_sn', models.CharField(blank=True, max_length=128, verbose_name='\\u670d\\u52a1\\u5668SN')),\n                ('Architecture', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u67b6\\u6784')),\n                ('Vendor', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u5236\\u9020\\u5546')),\n                ('model', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u578b\\u53f7')),\n                ('cpu_mhz', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u9891\\u7387')),\n                ('L1cache', models.CharField(blank=True, max_length=128, null=True)),\n                ('L2cache', models.CharField(blank=True, max_length=128, null=True)),\n                ('L3cache', models.CharField(blank=True, max_length=128, null=True)),\n                ('Thread', models.SmallIntegerField(null=True, verbose_name='\\u7ebf\\u7a0b')),\n                ('create_time', models.DateTimeField(auto_now_add=True)),\n                ('update_time', models.DateTimeField(auto_now=True)),\n            ],\n            options={\n                'verbose_name': 'CPU',\n                'verbose_name_plural': 'CPU',\n            },\n        ),\n        migrations.CreateModel(\n            name='DeviceType',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('name', models.CharField(blank=True, max_length=128, verbose_name='\\u8bbe\\u5907\\u7c7b\\u578b')),\n            ],\n            options={\n                'verbose_name': '\\u8bbe\\u5907\\u7c7b\\u578b',\n                'verbose_name_plural': '\\u8bbe\\u5907\\u7c7b\\u578b',\n                'permissions': (('cmdb_devicetype_view', 'Can view \\u8bbe\\u5907\\u7c7b\\u578b'),),\n            },\n        ),\n        migrations.CreateModel(\n            name='Disk',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('name', models.CharField(blank=True, max_length=128, verbose_name='\\u786c\\u76d8\\u540d\\u79f0')),\n                ('uuid', models.CharField(blank=True, max_length=128, unique=True)),\n                ('parent_sn', models.CharField(blank=True, max_length=128, verbose_name='\\u670d\\u52a1\\u5668SN')),\n                ('Firm', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u5236\\u9020\\u5546')),\n                ('capacity', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u5bb9\\u91cf')),\n                ('disk_type', models.SmallIntegerField(blank=True, choices=[(1, 'SATA'), (2, 'SSD')], null=True, verbose_name='\\u78c1\\u76d8\\u7c7b\\u578b')),\n                ('create_time', models.DateTimeField(auto_now_add=True)),\n                ('update_time', models.DateTimeField(auto_now=True)),\n                ('tag', models.CharField(blank=True, max_length=128, null=True)),\n            ],\n            options={\n                'verbose_name': '\\u786c\\u76d8',\n                'verbose_name_plural': '\\u786c\\u76d8',\n            },\n        ),\n        migrations.CreateModel(\n            name='IDC',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('idc_name', models.CharField(blank=True, max_length=128, unique=True)),\n                ('address', models.CharField(blank=True, max_length=255, null=True)),\n                ('floor', models.CharField(blank=True, max_length=20, null=True, verbose_name='\\u697c\\u5c42')),\n                ('contacts', models.CharField(blank=True, max_length=128, null=True)),\n                ('phone', models.CharField(blank=True, max_length=20, null=True)),\n            ],\n            options={\n                'verbose_name': 'IDC',\n                'verbose_name_plural': 'IDC',\n                'permissions': (('cmdb_idc_view', 'Can view IDC'),),\n            },\n        ),\n        migrations.CreateModel(\n            name='NIC',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('uuid', models.CharField(blank=True, max_length=128, verbose_name='UUID\\u53f7')),\n                ('parent_sn', models.CharField(blank=True, max_length=128, verbose_name='\\u670d\\u52a1\\u5668SN')),\n                ('name', models.CharField(max_length=128, verbose_name='\\u7f51\\u5361\\u540d\\u79f0')),\n                ('model', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u578b\\u53f7')),\n                ('ip', models.GenericIPAddressField(default='', verbose_name='IP\\u5730\\u5740')),\n                ('mac', models.CharField(max_length=64, verbose_name='mac\\u5730\\u5740')),\n                ('netmask', models.CharField(blank=True, max_length=64, null=True, verbose_name='\\u5b50\\u7f51\\u63a9\\u7801')),\n                ('nicstatus', models.CharField(blank=True, max_length=64, null=True, verbose_name='\\u7f51\\u5361\\u72b6\\u6001')),\n                ('create_time', models.DateTimeField(auto_now_add=True)),\n                ('update_time', models.DateTimeField(auto_now=True)),\n                ('tag', models.CharField(blank=True, max_length=128, null=True)),\n            ],\n            options={\n                'verbose_name': '\\u7f51\\u5361',\n                'verbose_name_plural': '\\u7f51\\u5361',\n            },\n        ),\n        migrations.CreateModel(\n            name='Provider',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('provider_name', models.CharField(blank=True, max_length=128, unique=True, verbose_name='\\u63d0\\u4f9b\\u5546')),\n                ('address', models.CharField(blank=True, max_length=255, verbose_name='\\u5730\\u5740')),\n                ('contacts', models.CharField(blank=True, max_length=128, verbose_name='\\u8054\\u7cfb\\u4eba')),\n                ('phone', models.CharField(blank=True, max_length=20, verbose_name='\\u8054\\u7cfb\\u7535\\u8bdd')),\n                ('Fax', models.CharField(blank=True, max_length=20, verbose_name='\\u4f20\\u771f')),\n            ],\n            options={\n                'verbose_name': '\\u4f9b\\u5e94\\u5546',\n                'verbose_name_plural': '\\u4f9b\\u5e94\\u5546',\n                'permissions': (('cmdb_provider_view', 'Can view \\u4f9b\\u5e94\\u5546'),),\n            },\n        ),\n        migrations.CreateModel(\n            name='Server',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('sn', models.CharField(max_length=128, unique=True, verbose_name='SN\\u53f7')),\n                ('hostname', models.CharField(max_length=128, verbose_name='\\u4e3b\\u673a\\u540d')),\n                ('mem', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u5185\\u5b58\\u603b\\u5bb9\\u91cf')),\n                ('swap', models.CharField(blank=True, max_length=128, null=True, verbose_name='swap\\u5bb9\\u91cf')),\n                ('platform', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u5e73\\u53f0')),\n                ('system', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u7cfb\\u7edf')),\n                ('version', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u7248\\u672c')),\n                ('Firm', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u5236\\u9020\\u5546')),\n                ('cpu_count', models.SmallIntegerField(blank=True, verbose_name='cpu\\u4e2a\\u6570')),\n                ('cpu_core_count', models.SmallIntegerField(blank=True, verbose_name='cpu\\u6838\\u6570')),\n                ('raid', models.CharField(blank=True, max_length=128, null=True, verbose_name='RAID\\u7ea7\\u522b')),\n                ('saltid', models.CharField(blank=True, max_length=128, null=True, verbose_name='SaltID\\u540d')),\n                ('create_time', models.DateTimeField(auto_now_add=True)),\n                ('addtype', models.SmallIntegerField(blank=True, choices=[(1, '\\u624b\\u52a8\\u6dfb\\u52a0'), (2, '\\u81ea\\u52a8\\u91c7\\u96c6')], default=1, verbose_name='\\u91c7\\u96c6\\u6a21\\u5f0f')),\n                ('update_time', models.DateTimeField(auto_now=True, null=True)),\n                ('Assets', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='pub', to='servermanager.Assets', verbose_name='\\u8d44\\u4ea7\\u5173\\u8054')),\n                ('cpu', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='servermanager.Cpu')),\n                ('disk', models.ManyToManyField(blank=True, to='servermanager.Disk', verbose_name='\\u786c\\u76d8')),\n                ('nic', models.ManyToManyField(to='servermanager.NIC', verbose_name='\\u7f51\\u5361\\u5217\\u8868')),\n            ],\n            options={\n                'verbose_name': '\\u670d\\u52a1\\u5668\\u7ba1\\u7406',\n                'verbose_name_plural': '\\u670d\\u52a1\\u5668\\u7ba1\\u7406',\n                'permissions': (('cmdb_server_view', 'Can view \\u670d\\u52a1\\u5668\\u7ba1\\u7406'),),\n            },\n        ),\n        migrations.CreateModel(\n            name='Software',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('name', models.CharField(blank=True, max_length=128, verbose_name='\\u8f6f\\u4ef6\\u540d\\u79f0')),\n                ('version', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u7248\\u672c')),\n                ('license', models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u5e8f\\u5217\\u53f7')),\n            ],\n            options={\n                'verbose_name': '\\u8f6f\\u4ef6\\u7ba1\\u7406',\n                'verbose_name_plural': '\\u8f6f\\u4ef6\\u7ba1\\u7406',\n                'permissions': (('cmdb_software_view', 'Can view \\u8f6f\\u4ef6\\u7ba1\\u7406'),),\n            },\n        ),\n        migrations.AddField(\n            model_name='server',\n            name='software',\n            field=models.ManyToManyField(blank=True, to='servermanager.Software', verbose_name='\\u8f6f\\u4ef6\\u5217\\u8868'),\n        ),\n        migrations.AddField(\n            model_name='assets',\n            name='IDC',\n            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='servermanager.IDC'),\n        ),\n    ]\n"
  },
  {
    "path": "servermanager/migrations/0002_auto_20161121_1740.py",
    "content": "# -*- coding: utf-8 -*-\n# Generated by Django 1.9.9 on 2016-11-21 17:40\nfrom __future__ import unicode_literals\n\nfrom django.conf import settings\nfrom django.db import migrations, models\nimport django.db.models.deletion\n\n\nclass Migration(migrations.Migration):\n\n    initial = True\n\n    dependencies = [\n        ('servermanager', '0001_initial'),\n        migrations.swappable_dependency(settings.AUTH_USER_MODEL),\n    ]\n\n    operations = [\n        migrations.AddField(\n            model_name='assets',\n            name='admin',\n            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='\\u7ba1\\u7406\\u5458\\u90ae\\u7bb1'),\n        ),\n        migrations.AddField(\n            model_name='assets',\n            name='business',\n            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='servermanager.Business', verbose_name='\\u4e1a\\u52a1'),\n        ),\n        migrations.AddField(\n            model_name='assets',\n            name='device_type',\n            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='servermanager.DeviceType', verbose_name='\\u8bbe\\u5907\\u7c7b\\u578b'),\n        ),\n        migrations.AddField(\n            model_name='assets',\n            name='provider',\n            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='servermanager.Provider', verbose_name='\\u63d0\\u4f9b\\u5546'),\n        ),\n    ]\n"
  },
  {
    "path": "servermanager/migrations/0003_auto_20161128_1031.py",
    "content": "# -*- coding: utf-8 -*-\n# Generated by Django 1.9.9 on 2016-11-28 10:31\nfrom __future__ import unicode_literals\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    dependencies = [\n        ('servermanager', '0002_auto_20161121_1740'),\n    ]\n\n    operations = [\n        migrations.AlterField(\n            model_name='cpu',\n            name='uuid',\n            field=models.CharField(max_length=64, verbose_name='UUID\\u53f7'),\n        ),\n    ]\n"
  },
  {
    "path": "servermanager/migrations/0004_auto_20161128_1032.py",
    "content": "# -*- coding: utf-8 -*-\n# Generated by Django 1.9.9 on 2016-11-28 10:32\nfrom __future__ import unicode_literals\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    dependencies = [\n        ('servermanager', '0003_auto_20161128_1031'),\n    ]\n\n    operations = [\n        migrations.AlterField(\n            model_name='cpu',\n            name='parent_sn',\n            field=models.CharField(max_length=128, verbose_name='\\u670d\\u52a1\\u5668SN'),\n        ),\n    ]\n"
  },
  {
    "path": "servermanager/migrations/0005_auto_20161128_1032.py",
    "content": "# -*- coding: utf-8 -*-\n# Generated by Django 1.9.9 on 2016-11-28 10:32\nfrom __future__ import unicode_literals\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    dependencies = [\n        ('servermanager', '0004_auto_20161128_1032'),\n    ]\n\n    operations = [\n        migrations.AlterField(\n            model_name='idc',\n            name='idc_name',\n            field=models.CharField(max_length=128, unique=True),\n        ),\n    ]\n"
  },
  {
    "path": "servermanager/migrations/0006_auto_20161128_1034.py",
    "content": "# -*- coding: utf-8 -*-\n# Generated by Django 1.9.9 on 2016-11-28 10:34\nfrom __future__ import unicode_literals\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    dependencies = [\n        ('servermanager', '0005_auto_20161128_1032'),\n    ]\n\n    operations = [\n        migrations.AlterField(\n            model_name='business',\n            name='name',\n            field=models.CharField(max_length=128, unique=True, verbose_name='\\u4e1a\\u52a1\\u540d'),\n        ),\n        migrations.AlterField(\n            model_name='devicetype',\n            name='name',\n            field=models.CharField(max_length=128, verbose_name='\\u8bbe\\u5907\\u7c7b\\u578b'),\n        ),\n        migrations.AlterField(\n            model_name='disk',\n            name='name',\n            field=models.CharField(max_length=128, verbose_name='\\u786c\\u76d8\\u540d\\u79f0'),\n        ),\n        migrations.AlterField(\n            model_name='disk',\n            name='parent_sn',\n            field=models.CharField(max_length=128, verbose_name='\\u670d\\u52a1\\u5668SN'),\n        ),\n        migrations.AlterField(\n            model_name='disk',\n            name='uuid',\n            field=models.CharField(max_length=128, unique=True),\n        ),\n        migrations.AlterField(\n            model_name='nic',\n            name='parent_sn',\n            field=models.CharField(max_length=128, verbose_name='\\u670d\\u52a1\\u5668SN'),\n        ),\n        migrations.AlterField(\n            model_name='nic',\n            name='uuid',\n            field=models.CharField(max_length=128, verbose_name='UUID\\u53f7'),\n        ),\n        migrations.AlterField(\n            model_name='provider',\n            name='provider_name',\n            field=models.CharField(max_length=128, unique=True, verbose_name='\\u63d0\\u4f9b\\u5546'),\n        ),\n        migrations.AlterField(\n            model_name='software',\n            name='name',\n            field=models.CharField(max_length=128, verbose_name='\\u8f6f\\u4ef6\\u540d\\u79f0'),\n        ),\n    ]\n"
  },
  {
    "path": "servermanager/migrations/0007_auto_20161128_1038.py",
    "content": "# -*- coding: utf-8 -*-\n# Generated by Django 1.9.9 on 2016-11-28 10:38\nfrom __future__ import unicode_literals\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    dependencies = [\n        ('servermanager', '0006_auto_20161128_1034'),\n    ]\n\n    operations = [\n        migrations.AlterField(\n            model_name='idc',\n            name='address',\n            field=models.CharField(blank=True, max_length=255, null=True, verbose_name='\\u5730\\u5740'),\n        ),\n        migrations.AlterField(\n            model_name='idc',\n            name='contacts',\n            field=models.CharField(blank=True, max_length=128, null=True, verbose_name='\\u8054\\u7cfb\\u4eba'),\n        ),\n        migrations.AlterField(\n            model_name='idc',\n            name='idc_name',\n            field=models.CharField(max_length=128, unique=True, verbose_name='IDC'),\n        ),\n        migrations.AlterField(\n            model_name='idc',\n            name='phone',\n            field=models.CharField(blank=True, max_length=20, null=True, verbose_name='\\u8054\\u7cfb\\u7535\\u8bdd'),\n        ),\n    ]\n"
  },
  {
    "path": "servermanager/migrations/0008_auto_20161128_1109.py",
    "content": "# -*- coding: utf-8 -*-\n# Generated by Django 1.9.9 on 2016-11-28 11:09\nfrom __future__ import unicode_literals\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    dependencies = [\n        ('servermanager', '0007_auto_20161128_1038'),\n    ]\n\n    operations = [\n        migrations.AlterField(\n            model_name='server',\n            name='cpu_core_count',\n            field=models.SmallIntegerField(blank=True, default=0, verbose_name='cpu\\u6838\\u6570'),\n        ),\n        migrations.AlterField(\n            model_name='server',\n            name='cpu_count',\n            field=models.SmallIntegerField(blank=True, default=0, verbose_name='cpu\\u4e2a\\u6570'),\n        ),\n    ]\n"
  },
  {
    "path": "servermanager/migrations/0009_auto_20161128_1112.py",
    "content": "# -*- coding: utf-8 -*-\n# Generated by Django 1.9.9 on 2016-11-28 11:12\nfrom __future__ import unicode_literals\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    dependencies = [\n        ('servermanager', '0008_auto_20161128_1109'),\n    ]\n\n    operations = [\n        migrations.AlterField(\n            model_name='server',\n            name='saltid',\n            field=models.CharField(max_length=128, verbose_name='SaltID\\u540d'),\n        ),\n    ]\n"
  },
  {
    "path": "servermanager/migrations/0010_auto_20161128_1113.py",
    "content": "# -*- coding: utf-8 -*-\n# Generated by Django 1.9.9 on 2016-11-28 11:13\nfrom __future__ import unicode_literals\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    dependencies = [\n        ('servermanager', '0009_auto_20161128_1112'),\n    ]\n\n    operations = [\n        migrations.AlterField(\n            model_name='server',\n            name='nic',\n            field=models.ManyToManyField(blank=True, null=True, to='servermanager.NIC', verbose_name='\\u7f51\\u5361\\u5217\\u8868'),\n        ),\n    ]\n"
  },
  {
    "path": "servermanager/migrations/0011_auto_20161202_1049.py",
    "content": "# -*- coding: utf-8 -*-\n# Generated by Django 1.9.9 on 2016-12-02 10:49\nfrom __future__ import unicode_literals\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    dependencies = [\n        ('servermanager', '0010_auto_20161128_1113'),\n    ]\n\n    operations = [\n        migrations.AlterField(\n            model_name='server',\n            name='nic',\n            field=models.ManyToManyField(blank=True, to='servermanager.NIC', verbose_name='\\u7f51\\u5361\\u5217\\u8868'),\n        ),\n    ]\n"
  },
  {
    "path": "servermanager/migrations/__init__.py",
    "content": ""
  },
  {
    "path": "servermanager/models.py",
    "content": "#coding:utf8\nfrom __future__ import unicode_literals\nfrom django.db import models\nfrom webapp.models import Suser\n\n\n'''设备类型表'''\nclass DeviceType(models.Model):\n    name = models.CharField(max_length=128,verbose_name=u'设备类型')\n\n    def __unicode__(self):\n        return self.name\n\n    class Meta:\n        verbose_name = u'设备类型'\n        verbose_name_plural = u\"设备类型\"\n        permissions = (\n\n            (\"cmdb_devicetype_view\", \"Can view %s\" %verbose_name),\n\n        )\n\n'''IDC信息管理表'''\nclass IDC(models.Model):\n    idc_name = models.CharField(u'IDC',max_length=128, unique=True)\n    address = models.CharField(u'地址',max_length=255, null=True,blank=True)\n    floor = models.CharField(u'楼层',max_length=20,null=True,blank=True)\n    contacts = models.CharField(u'联系人',max_length=128, null=True,blank=True)\n    phone = models.CharField(u'联系电话',max_length=20,null=True,blank=True)\n\n    def __unicode__(self):\n        return self.idc_name\n\n    class Meta:\n        verbose_name = u'IDC'\n        verbose_name_plural = u'IDC'\n        permissions = (\n            (\"cmdb_idc_view\", \"Can view %s\" %verbose_name),\n        )\n'''业务表'''\nclass Business(models.Model):\n    name = models.CharField(max_length=128,unique=True,verbose_name=u'业务名')\n    memo = models.CharField(u'备注',max_length=64, blank=True)\n\n    def __unicode__(self):\n        return self.name\n\n    class Meta:\n        verbose_name = u'业务列表'\n        verbose_name_plural = u'业务列表'\n        permissions = (\n\n            (\"cmdb_devicetype_view\", \"Can view %s\" %verbose_name),\n\n        )\n\n'''提供商表'''\nclass Provider(models.Model):\n    provider_name = models.CharField(max_length=128,  unique=True, verbose_name=u'提供商')\n    address = models.CharField(max_length=255, blank=True, verbose_name=u'地址')\n    contacts = models.CharField(max_length=128, blank=True, verbose_name=u'联系人')\n    phone = models.CharField(max_length=20,blank=True, verbose_name=u'联系电话')\n    Fax = models.CharField(max_length=20,blank=True, verbose_name=u'传真')\n\n    def __unicode__(self):\n        return self.provider_name\n\n    class Meta:\n        verbose_name = u'供应商'\n        verbose_name_plural = u'供应商'\n        permissions = (\n            (\"cmdb_provider_view\", \"Can view %s\" %verbose_name),\n        )\n'''资产表'''\nclass Assets(models.Model):\n\n    host_name = models.CharField(verbose_name=u'设备名',max_length=128,null=True, unique=True)\n\n    device_number = models.CharField(u'设备编号',max_length=128, unique=True)\n\n    device_type = models.ForeignKey('DeviceType',verbose_name=u'设备类型',null=True,blank=True)\n\n    #保修期\n    Warranty = models.SmallIntegerField(u'保修期')\n\n    IDC = models.ForeignKey('IDC', null=True,blank=True)\n\n    business = models.ForeignKey('Business',verbose_name=u'业务', null=True,blank=True)\n\n    buy_time = models.CharField(u'购买日期', max_length=128, blank=True)\n\n    buy_type_choice = (\n        (1, u'公司内购'),\n        (2, u'员工自购'),\n    )\n\n\n\n    buy_type = models.SmallIntegerField(u'购买方式',choices=buy_type_choice,blank=True)\n\n    price = models.IntegerField(u'购买价格',blank=True)\n\n\n    #管理员,可以是多个管理员进行维护\n    admin = models.ForeignKey(Suser, verbose_name=u'管理员邮箱',null=True,blank=True)\n\n    suse_time = models.DateField(u'开始使用时间', max_length=128, null=True)\n\n    euse_time = models.DateField(u'截至使用时间', max_length=128, null=True)\n\n    status_choice = (\n        (1, u'正在使用'),\n        (2, u'未使用'),\n        (3, u'设备故障'),\n        (4, u'库存备用'),\n    )\n\n    status =models.SmallIntegerField(u'状态',choices=status_choice,blank=True)\n\n    create_time = models.DateTimeField(u'资产创建时间', auto_now_add=True,null=True)\n\n    devicetag = models.CharField(max_length=255, blank=True)\n\n    #提供商\n    provider = models.ForeignKey('Provider',verbose_name=u'提供商', null=True,blank=True)\n\n    #其它备注\n    description = models.TextField(max_length=255,blank=True,verbose_name=u'备注')\n\n    def __unicode__(self):\n        return self.host_name\n\n    class Meta:\n        verbose_name = u'资产表管理'\n        verbose_name_plural = u'资产表管理'\n        permissions = (\n\n            (\"cmdb_assets_view\", \"Can view %s\" %verbose_name),\n\n            (\"assets_index_view\", \"资产管理\"),\n        )\n\n'''软件版本'''\nclass Software(models.Model):\n    name = models.CharField(max_length=128, verbose_name=u'软件名称')\n    version = models.CharField(max_length=128,null=True, blank=True,verbose_name=u'版本')\n    license = models.CharField(max_length=128,null=True, blank=True,verbose_name=u'序列号')\n\n    def __unicode__(self):\n        return self.name\n\n    class Meta:\n        verbose_name = u'软件管理'\n        verbose_name_plural = u'软件管理'\n        permissions = (\n\n            (\"cmdb_software_view\", \"Can view %s\" %verbose_name),\n\n        )\n'''服务器主表'''\nclass Server(models.Model):\n    Assets = models.OneToOneField('Assets',verbose_name=u'资产关联',null=True,blank=True,related_name='pub')\n\n    sn = models.CharField(max_length=128,verbose_name=u'SN号',unique=True)\n\n    hostname = models.CharField(max_length=128,verbose_name=u'主机名')\n\n    mem = models.CharField(max_length=128,null=True, blank=True,verbose_name=u'内存总容量')\n\n    swap = models.CharField(max_length=128,null=True, blank=True,verbose_name=u'swap容量')\n\n    platform = models.CharField(max_length=128,null=True, blank=True,verbose_name=u'平台')\n\n    system = models.CharField(max_length=128,null=True, blank=True,verbose_name=u'系统')\n\n    version = models.CharField(max_length=128,null=True, blank=True,verbose_name=u'版本')\n\n    #产商\n    Firm = models.CharField(max_length=128,null=True, blank=True,verbose_name=u'制造商')\n\n\n    #软件安装列表\n    software  = models.ManyToManyField('Software', blank=True,verbose_name=u'软件列表')\n\n    #CPU\n    cpu = models.ForeignKey('Cpu',blank=True,null=True)\n\n    cpu_count = models.SmallIntegerField(u'cpu个数',blank=True,default=0)\n\n    cpu_core_count = models.SmallIntegerField(u'cpu核数',blank=True,default=0)\n\n    #nic\n    nic = models.ManyToManyField('NIC', verbose_name=u'网卡列表',blank=True)\n\n    #磁盘\n    disk = models.ManyToManyField('Disk', verbose_name=u'硬盘',blank=True)\n\n    #raid\n    raid = models.CharField(max_length=128,null=True,blank=True,verbose_name=u'RAID级别')\n\n    saltid = models.CharField(max_length=128,verbose_name=u'SaltID名')\n\n    create_time = models.DateTimeField(blank=True, auto_now_add=True)\n\n    add_type_choice = (\n        (1,u'手动添加'),\n        (2,u'自动采集'),\n    )\n    addtype =models.SmallIntegerField(u'采集模式',choices=add_type_choice,blank=True,default=1)\n\n    #修改时间\n    update_time = models.DateTimeField(blank=True, auto_now=True, null=True)\n\n    def __unicode__(self):\n        return \"%s %s\" %(self.sn, self.Assets.host_name)\n\n    class Meta:\n        verbose_name = u'服务器管理'\n        verbose_name_plural = '服务器管理'\n        permissions = (\n\n            (\"cmdb_server_view\", \"Can view %s\" %verbose_name),\n\n        )\nclass Cpu(models.Model):\n    uuid = models.CharField(u'UUID号',max_length=64)\n\n    parent_sn = models.CharField(max_length=128, verbose_name=u'服务器SN')\n\n    #cpu架构\n    Architecture = models.CharField(max_length=128,blank=True,null=True,verbose_name=u'架构')\n\n    #产商\n    Vendor = models.CharField(max_length=128,blank=True,null=True,verbose_name=u'制造商')\n\n    #型号\n    model = models.CharField(max_length=128,blank=True,null=True,verbose_name=u'型号')\n\n    cpu_mhz = models.CharField(max_length=128,blank=True,null=True,verbose_name=u'频率')\n\n    L1cache = models.CharField(max_length=128,blank=True,null=True)\n\n    L2cache = models.CharField(max_length=128,blank=True,null=True)\n\n    L3cache = models.CharField(max_length=128,blank=True,null=True)\n\n    Thread = models.SmallIntegerField(null=True,verbose_name=u'线程')\n\n    create_time = models.DateTimeField(blank=True, auto_now_add=True)\n\n    update_time = models.DateTimeField(blank=True, auto_now=True)\n\n    def __unicode__(self):\n        return self.parent_sn\n\n    class Meta:\n        verbose_name = u'CPU'\n        verbose_name_plural = u'CPU'\nclass Disk(models.Model):\n    name  = models.CharField(max_length=128,verbose_name=u'硬盘名称')\n\n    uuid = models.CharField(max_length=128,unique=True)\n\n    parent_sn = models.CharField(max_length=128,verbose_name=u'服务器SN')\n\n    #产商\n    Firm = models.CharField(max_length=128,null=True, blank=True,verbose_name=u'制造商')\n\n    #容量\n    capacity = models.CharField(max_length=128,null=True, blank=True,verbose_name=u'容量')\n\n    type_choice = (\n        (1, u'SATA'),\n        (2, u'SSD'),\n    )\n\n    #磁盘类型\n    disk_type = models.SmallIntegerField(choices=type_choice,null=True,blank=True,verbose_name='磁盘类型')\n\n\n\n    create_time = models.DateTimeField(blank=True, auto_now_add=True)\n\n    update_time = models.DateTimeField(blank=True, auto_now=True)\n\n    tag = models.CharField(max_length=128,blank=True,null=True)\n\n    def __unicode__(self):\n        return self.parent_sn\n\n\n    class Meta:\n        verbose_name = u'硬盘'\n        verbose_name_plural = u'硬盘'\nclass NIC(models.Model):\n    uuid = models.CharField(u'UUID号',max_length=128,)\n    parent_sn = models.CharField(max_length=128,verbose_name=u'服务器SN')\n    name = models.CharField(u'网卡名称', max_length=128,)\n    model = models.CharField(max_length=128,blank=True,null=True,verbose_name=u'型号')\n    ip = models.GenericIPAddressField(max_length=128,null=False,default='',verbose_name=u'IP地址')\n    mac = models.CharField(u'mac地址', max_length=64)\n    netmask = models.CharField(max_length=64,blank=True,null=True,verbose_name=u'子网掩码')\n    nicstatus = models.CharField(max_length=64,blank=True,null=True,verbose_name=u'网卡状态')\n    create_time = models.DateTimeField(blank=True, auto_now_add=True)\n    update_time = models.DateTimeField(blank=True, auto_now=True)\n    tag = models.CharField(max_length=128,blank=True,null=True)\n\n\n    def __unicode__(self):\n        return self.ip\n\n    class Meta:\n        verbose_name = u'网卡'\n        verbose_name_plural = u'网卡'\n\n\n\n"
  },
  {
    "path": "servermanager/tests.py",
    "content": "from django.test import TestCase\n\n# Create your tests here.\n"
  },
  {
    "path": "servermanager/urls.py",
    "content": "from django.conf.urls import url\n\n\nfrom servermanager.views import (HostLists,ServerDetail,ChangeServer,\n                                 AssetsLists,CeleryStatus,\n                                 AssetsDetail,\n                                 ServerList,\n                                 DeleteAsset,\n                                 DeleteServer,\n                                 UpdateServer,\n                                 ChangeAsset,)\n\nurlpatterns = [\n    url(r'assets/(\\d+)$', AssetsLists, name='AssetsLists'),\n    url(r'assets/detail/(\\d+)$', AssetsDetail, name='AssetsDetail'),\n    url(r'assets/delete/(\\d+)$', DeleteAsset, name='DeleteAsset'),\n    url(r'assets/change/(\\d+)$', ChangeAsset, name='ChangeAsset'),\n\n    url(r'servers/detail/(\\d+)$',ServerDetail,name='ServerDetail'),\n    url(r'servers/(\\d+)$', ServerList, name='ServerList'),\n    url(r'servers/delete/(\\d+)$', DeleteServer, name='DeleteServer'),\n    url(r'servers/update/(\\d+)$',UpdateServer,name='UpdateServer'),\n    url(r'servers/change/(\\d+)$',ChangeServer,name='ChangeServer'),\n    url(r'servers/task/(\\w+\\-\\w+\\-\\w+\\-\\w+\\-\\w+)$',CeleryStatus,name='CeleryStatus'),\n]\n"
  },
  {
    "path": "servermanager/views.py",
    "content": "#coding:utf8\nfrom django.shortcuts import render\nfrom django.http import HttpResponse\nfrom django.contrib.auth.decorators import login_required\nfrom servermanager.models import *\nfrom webapp.models import *\nfrom webapp.Extends import PageList\nfrom webapp.tasks import SaltGrains,UpdateServerInfo\nfrom django.db.models import Q\nfrom django.contrib.auth.decorators import permission_required\n\nimport json\n\n@login_required()\ndef HostLists(request):\n    return render(request,'servermanager/hosts.html')\n\n@login_required()\n@permission_required('servermanager.cmdb_assets_view',raise_exception=True)\ndef AssetsLists(request,page):\n    usersession=request.session.get('user_id')\n    if request.method == 'POST':\n        searchdata = request.POST.get('search')\n        #分页代码\n        (page,start,end,per_item)=PageList.PageCount(page)\n        count = Assets.objects.filter(Q(host_name__contains=searchdata) | Q(device_number__contains=searchdata)).count()\n        result = Assets.objects.filter(Q(host_name__contains=searchdata) | Q(device_number__contains=searchdata)).order_by('-id')[start:end]\n        url = \"/server/assets\"\n        if count%per_item == 0:\n            all_pages_count = count/per_item\n        else:\n            all_pages_count = count/per_item+1\n        page=PageList.Page(page, url, all_pages_count)\n        ret = {'Assetsdata': result,\n                   'count': count,\n                   'page': page,\n                   'usersession':usersession}\n        return render(request,'servermanager/assets_list.html', ret)\n    else:\n        AssetsData=Assets.objects.all()\n        for asset in AssetsData:\n            if Server.objects.filter(Assets=asset):\n\n                asset.status = 1\n                asset.save()\n            else:\n                asset.status = 2\n                asset.save()\n        #分页代码\n        (page,start,end,per_item)=PageList.PageCount(page)\n        count = Assets.objects.all().count()\n        result = Assets.objects.all().order_by('-id')[start:end]\n        url = \"/server/assets\"\n        if count%per_item == 0:\n            all_pages_count = count/per_item\n        else:\n            all_pages_count = count/per_item+1\n        page=PageList.Page(page, url, all_pages_count)\n\n        ret = {'Assetsdata': result,\n                   'count': count,\n                   'page': page,\n                   'usersession':usersession}\n        return render(request,'servermanager/assets_list.html', ret)\n\n@login_required()\ndef AssetsDetail(request,id):\n    usersession=request.session.get('user_id')\n    if request.method == 'GET':\n        result = Assets.objects.get(id=id)\n        ret={'Assetsdata':result,'usersession':usersession}\n        return render(request,'servermanager/assetsdetail.html',ret)\n\n@login_required()\n@permission_required('servermanager.cmdb_server_view',raise_exception=True)\ndef ServerList(request,page):\n    usersession=request.session.get('user_id')\n    if request.method  == 'POST':\n        searchdata = request.POST.get('search')\n        #分页代码\n        (page,start,end,per_item)=PageList.PageCount(page)\n        count = Server.objects.filter(Q(Assets__host_name__contains=searchdata) | Q(hostname__contains=searchdata) | Q(sn__contains=searchdata)).count()\n\n        result = Server.objects.filter(Q(Assets__host_name__contains=searchdata) | Q(hostname__contains=searchdata) | Q(sn__contains=searchdata)).order_by('-id')[start:end]\n        url = \"/server/servers\"\n        if count%per_item == 0:\n            all_pages_count = count/per_item\n        else:\n            all_pages_count = count/per_item+1\n        page=PageList.Page(page, url, all_pages_count)\n        ret = {'Serverdata': result,\n                   'count': count,\n                   'page': page,\n                   'usersession':usersession}\n        return render(request,'servermanager/servers_list.html', ret)\n    else:\n        #分页代码\n        (page,start,end,per_item)=PageList.PageCount(page)\n        count = Server.objects.all().count()\n        result = Server.objects.all().order_by('-id')[start:end]\n        url = \"/server/servers\"\n        if count%per_item == 0:\n            all_pages_count = count/per_item\n        else:\n            all_pages_count = count/per_item+1\n        page=PageList.Page(page, url, all_pages_count)\n        ret = {'Serverdata': result,\n               'count': count,\n               'page': page,\n               'usersession':usersession}\n        return render(request, 'servermanager/servers_list.html', ret)\n\n@login_required()\ndef ServerDetail(request,id):\n    usersession=request.session.get('user_id')\n    if request.method == 'GET':\n        ServerData = Server.objects.get(id=id)\n\n\n        Diskall=ServerData.disk.all()\n        colors = [\"#5fbeaa\",\"#ebeff2\",\"#36404a\",\"#5fbeaa\",\"#ebeff2\",\"#5d9cec\"]\n\n        Diskhtml=[]\n        for i in range(Diskall.count()):\n            disk={}\n            disk['label']=Diskall[i].name.encode()   #传给前端去掉unicode\n            disk['value']=Diskall[i].capacity.encode()\n            disk['color']=colors[i]\n            disk['highlight']=colors[i]\n            Diskhtml.append(disk)\n\n        ret = {'usersession':usersession,'ServerData':ServerData,'Diskhtml':json.dumps(Diskhtml)}\n        return render(request,'servermanager/servers_detail.html',ret)\n\n@login_required()\n@permission_required('servermanager.delete_assets',raise_exception=True)\ndef DeleteServer(request,id):\n    username = request.session.get('user_name')\n    if request.method == 'GET':\n        ServerData = Server.objects.get(id=id)\n        ServerData.delete()\n\n        msg=u'删除服务器信息 %s'  %ServerData.hostname\n        Operation.objects.create(Opuser=username,Opaction=msg)\n        return HttpResponse(u'删除主机成功')\n\n@login_required()\n@permission_required('servermanager.delete_assets',raise_exception=True)\ndef DeleteAsset(request,id):\n    username = request.session.get('user_name')\n    if request.method == 'GET':\n        selectid=Assets.objects.filter(id=id)\n        if Server.objects.filter(Assets=selectid):\n            msg={'msgerror':u'请删除所关联的服务器!!'}\n            return HttpResponse(json.dumps(msg))\n        else:\n            AssetData = Assets.objects.get(id=id)\n            AssetData.delete()\n            msg=u'删除资产信息 %s'  %AssetData.host_name\n            Operation.objects.create(Opuser=username,Opaction=msg)\n            msg={'msginfo':u'OK，资产信息删除成功!!!!'}\n            return HttpResponse(json.dumps(msg))\n\n@login_required()\n@permission_required('servermanager.change_assets',raise_exception=True)\ndef ChangeAsset(request,id):\n    usersession=request.session.get('user_id')\n    username = request.session.get('user_name')\n    if request.method == 'POST':\n        PostData=request.POST\n        AssetDsata=Assets.objects.get(id=id)\n        AssetDsata.status = PostData['status']\n        AssetDsata.Warranty =PostData['Warranty']\n        AssetDsata.device_number = PostData['device_number']\n\n        device_type=DeviceType.objects.get(id=PostData['device_type'])\n        AssetDsata.device_type = device_type\n        AssetDsata.host_name = PostData['host_name']\n\n        idc = IDC.objects.get(id=PostData['idc'])\n        AssetDsata.IDC = idc\n\n        business = Business.objects.get(id=PostData['business'])\n        AssetDsata.business = business\n        AssetDsata.buy_time = PostData['buytime']\n        AssetDsata.price = PostData['price']\n\n        admin  = Suser.objects.get(id=PostData['admin'])\n        AssetDsata.admin = admin\n        AssetDsata.suse_time = PostData['start']\n        AssetDsata.euse_time = PostData['end']\n\n        provider = Provider.objects.get(id=PostData['provider'])\n        AssetDsata.provider = provider\n\n        AssetDsata.description = PostData['summernote']\n        AssetDsata.save()\n\n\n        Operation.objects.create(Opuser=username,Opaction=u'修改资产信息')\n\n        msg={'msginfo':u'恭喜您，资产修改成功！！！'}\n        return HttpResponse(json.dumps(msg))\n\n    else:\n        AssetsData=Assets.objects.get(id=id)\n        IdcData = IDC.objects.all()\n        BusinessData = Business.objects.all()\n        DeviceTypeData  = DeviceType.objects.all()\n        AdminUser = Suser.objects.all()\n        ProviderData = Provider.objects.all()\n\n        ret = {\n            'usersession': usersession,\n            'AssetsData': AssetsData,\n            'IdcData': IdcData,\n            'BusinessData': BusinessData,\n            'DeviceTypeData': DeviceTypeData,\n            'AdminUser': AdminUser,\n            'ProviderData':ProviderData,\n        }\n        return render(request,'servermanager/assetschange.html',ret)\n\n\n@login_required()\n@permission_required('servermanager.change_assets',raise_exception=True)\ndef ChangeServer(request,id):\n    usersession=request.session.get('user_id')\n    username = request.session.get('user_name')\n    if request.method == 'POST':\n        software=request.POST.getlist('software')\n        disk=request.POST.getlist('disk')\n        nic=request.POST.getlist('nic')\n\n        Assetsid=request.POST['Assets']\n        AssetsInfo = Assets.objects.get(id=Assetsid)\n\n        ServerData=Server.objects.get(id=id)\n        ServerData.Assets=AssetsInfo\n        ServerData.mem = request.POST['mem']\n        ServerData.swap=request.POST['swap']\n        ServerData.platform = request.POST['platform']\n        ServerData.system = request.POST['system']\n        ServerData.version = request.POST['version']\n        ServerData.Firm = request.POST['firm']\n        ServerData.saltid = request.POST['saltid']\n        ServerData.hostname = request.POST['hostname']\n        ServerData.sn = request.POST['sn']\n        CPU = request.POST['CPU']\n        CPU = Cpu.objects.get(id=CPU)\n        ServerData.cpu=CPU\n        ServerData.cpu_count = request.POST['cpu_count']\n        ServerData.cpu_core_count = request.POST['cpu_core_count']\n        ServerData.raid = request.POST['raid']\n        ServerData.addtype = request.POST['addtype']\n\n        for n in ServerData.nic.all():\n            group_set = NIC.objects.get(id=n.id)\n            ServerData.nic.remove(group_set)\n\n        for d in ServerData.disk.all():\n            group_set = Disk.objects.get(id=d.id)\n            ServerData.disk.remove(group_set)\n\n        for s in ServerData.software.all():\n            group_set = Software.objects.get(id=s.id)\n            ServerData.software.remove(group_set)\n\n        for n in nic:\n            print n\n            group_set = NIC.objects.get(id=n)\n            ServerData.nic.add(group_set)\n\n        for d in disk:\n            group_set = Disk.objects.get(id=d)\n            ServerData.disk.add(group_set)\n\n        for s in software:\n            group_set = Software.objects.get(id=s)\n            ServerData.software.add(group_set)\n\n        ServerData.save()\n        Operation.objects.create(Opuser=username,Opaction=u'修改服务器信息')\n        return HttpResponse(u'Server 修改成功!!')\n\n\n    else:\n\n        listdata=[]\n        [listdata.append(int(i.Assets.id)) for i in Server.objects.all()]\n        hostid=Server.objects.get(id=id)\n        listdata.remove(hostid.Assets_id)\n        AssetsData=Assets.objects.exclude(id__in=listdata)\n\n\n        CpuData = Cpu.objects.all()\n        SoftwareData = Software.objects.all()\n        DiskData = Disk.objects.all()\n        NicData = NIC.objects.all()\n        ServerData = Server.objects.get(id=id)\n        ret={'usersession':usersession,\n             'AssetsData':AssetsData,\n             'ServerData':ServerData,\n             'SoftwareData':SoftwareData,\n             'DiskData':DiskData,\n             'NicData':NicData,\n             'CpuData':CpuData}\n        return render(request,'servermanager/servers_change.html',ret)\n\n\n\n@login_required()\ndef UpdateServer(request,id):\n    username = request.session.get('user_name')\n    if request.method == 'GET':\n        a=UpdateServerInfo.apply_async((str(id),))\n        msg={'celeryId':a.id}\n        Operation.objects.create(Opuser=username,Opaction=u'Salt更新服务器信息 服务器 %s' %id)\n        return HttpResponse(json.dumps(msg))\n\n@login_required()\ndef CeleryStatus(request,celeryid):\n    if request.method == 'GET':\n        task=UpdateServerInfo.AsyncResult(celeryid)\n        if task.state == 'PENDING':\n            response = {\n                'state': task.state,\n                'status': 'Pending...'\n            }\n        elif task.state != 'FAILURE':\n            response = {\n                'state': task.state,\n                'status': task.status,\n            }\n            if 'result' in task.info:\n                response['result'] = task.info['result']\n        else:\n            response = {\n                'state': task.state,\n                'current': 1,\n                'total': 1,\n                'status': str(task.info),  # this is the exception raised\n            }\n        return HttpResponse(json.dumps(response))\n\n\n\n\n\n\n"
  },
  {
    "path": "static/assets/css/_variables.css",
    "content": "/*\nTemplate Name: Moltran Dashboard\nAuthor: CoderThemes\nEmail: coderthemes@gmail.com\nFile: Variables.less\n*/\n"
  },
  {
    "path": "static/assets/css/bootstrap-theme.css",
    "content": "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn-default.disabled,\n.btn-primary.disabled,\n.btn-success.disabled,\n.btn-info.disabled,\n.btn-warning.disabled,\n.btn-danger.disabled,\n.btn-default[disabled],\n.btn-primary[disabled],\n.btn-success[disabled],\n.btn-info[disabled],\n.btn-warning[disabled],\n.btn-danger[disabled],\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nfieldset[disabled] .btn-success,\nfieldset[disabled] .btn-info,\nfieldset[disabled] .btn-warning,\nfieldset[disabled] .btn-danger {\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n  text-shadow: none;\n}\n.btn:active,\n.btn.active {\n  background-image: none;\n}\n.btn-default {\n  text-shadow: 0 1px 0 #fff;\n  background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n  background-image:      -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));\n  background-image:         linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #dbdbdb;\n  border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n  background-color: #e0e0e0;\n  background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n  background-color: #e0e0e0;\n  border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n  background-color: #e0e0e0;\n  background-image: none;\n}\n.btn-primary {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n  background-color: #265a88;\n  background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n  background-color: #265a88;\n  border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n  background-color: #265a88;\n  background-image: none;\n}\n.btn-success {\n  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n  background-image:      -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));\n  background-image:         linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n  background-color: #419641;\n  background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n  background-color: #419641;\n  border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n  background-color: #419641;\n  background-image: none;\n}\n.btn-info {\n  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n  background-image:      -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));\n  background-image:         linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n  background-color: #2aabd2;\n  background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n  background-color: #2aabd2;\n  border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n  background-color: #2aabd2;\n  background-image: none;\n}\n.btn-warning {\n  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n  background-image:      -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));\n  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n  background-color: #eb9316;\n  background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n  background-color: #eb9316;\n  border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n  background-color: #eb9316;\n  background-image: none;\n}\n.btn-danger {\n  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n  background-image:      -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));\n  background-image:         linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n  background-color: #c12e2a;\n  background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n  background-color: #c12e2a;\n  border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n  background-color: #c12e2a;\n  background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);\n          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  background-color: #e8e8e8;\n  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image:      -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));\n  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n  background-repeat: repeat-x;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  background-color: #2e6da4;\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n  background-repeat: repeat-x;\n}\n.navbar-default {\n  background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);\n  background-image:      -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));\n  background-image:         linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n  background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n  background-image:      -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));\n  background-image:         linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n  background-repeat: repeat-x;\n  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n  text-shadow: 0 1px 0 rgba(255, 255, 255, .25);\n}\n.navbar-inverse {\n  background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);\n  background-image:      -o-linear-gradient(top, #3c3c3c 0%, #222 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));\n  background-image:         linear-gradient(to bottom, #3c3c3c 0%, #222 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-radius: 4px;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n  background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n  background-image:      -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));\n  background-image:         linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n  background-repeat: repeat-x;\n  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);\n          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  border-radius: 0;\n}\n@media (max-width: 767px) {\n  .navbar .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #fff;\n    background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n    background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n    background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));\n    background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n    background-repeat: repeat-x;\n  }\n}\n.alert {\n  text-shadow: 0 1px 0 rgba(255, 255, 255, .2);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);\n}\n.alert-success {\n  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n  background-image:      -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));\n  background-image:         linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #b2dba1;\n}\n.alert-info {\n  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n  background-image:      -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));\n  background-image:         linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #9acfea;\n}\n.alert-warning {\n  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n  background-image:      -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));\n  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #f5e79e;\n}\n.alert-danger {\n  background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n  background-image:      -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));\n  background-image:         linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #dca7a7;\n}\n.progress {\n  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n  background-image:      -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));\n  background-image:         linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-success {\n  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n  background-image:      -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));\n  background-image:         linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-info {\n  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n  background-image:      -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));\n  background-image:         linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-warning {\n  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n  background-image:      -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));\n  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-danger {\n  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n  background-image:      -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));\n  background-image:         linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n  background-repeat: repeat-x;\n}\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}\n.list-group {\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);\n          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  text-shadow: 0 -1px 0 #286090;\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n  text-shadow: none;\n}\n.panel {\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);\n          box-shadow: 0 1px 2px rgba(0, 0, 0, .05);\n}\n.panel-default > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image:      -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));\n  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-primary > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-success > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n  background-image:      -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));\n  background-image:         linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-info > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n  background-image:      -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));\n  background-image:         linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-warning > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n  background-image:      -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));\n  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-danger > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n  background-image:      -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));\n  background-image:         linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n  background-repeat: repeat-x;\n}\n.well {\n  background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n  background-image:      -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));\n  background-image:         linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #dcdcdc;\n  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */\n"
  },
  {
    "path": "static/assets/css/bootstrap.css",
    "content": "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 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: \"\\2a\";\n}\n.glyphicon-plus:before {\n  content: \"\\2b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n  content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n  content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n  content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n  content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n  content: \"\\270f\";\n}\n.glyphicon-glass:before {\n  content: \"\\e001\";\n}\n.glyphicon-music:before {\n  content: \"\\e002\";\n}\n.glyphicon-search:before {\n  content: \"\\e003\";\n}\n.glyphicon-heart:before {\n  content: \"\\e005\";\n}\n.glyphicon-star:before {\n  content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n  content: \"\\e007\";\n}\n.glyphicon-user:before {\n  content: \"\\e008\";\n}\n.glyphicon-film:before {\n  content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n  content: \"\\e010\";\n}\n.glyphicon-th:before {\n  content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n  content: \"\\e012\";\n}\n.glyphicon-ok:before {\n  content: \"\\e013\";\n}\n.glyphicon-remove:before {\n  content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n  content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n  content: \"\\e016\";\n}\n.glyphicon-off:before {\n  content: \"\\e017\";\n}\n.glyphicon-signal:before {\n  content: \"\\e018\";\n}\n.glyphicon-cog:before {\n  content: \"\\e019\";\n}\n.glyphicon-trash:before {\n  content: \"\\e020\";\n}\n.glyphicon-home:before {\n  content: \"\\e021\";\n}\n.glyphicon-file:before {\n  content: \"\\e022\";\n}\n.glyphicon-time:before {\n  content: \"\\e023\";\n}\n.glyphicon-road:before {\n  content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n  content: \"\\e025\";\n}\n.glyphicon-download:before {\n  content: \"\\e026\";\n}\n.glyphicon-upload:before {\n  content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n  content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n  content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n  content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n  content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n  content: \"\\e032\";\n}\n.glyphicon-lock:before {\n  content: \"\\e033\";\n}\n.glyphicon-flag:before {\n  content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n  content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n  content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n  content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n  content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n  content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n  content: \"\\e040\";\n}\n.glyphicon-tag:before {\n  content: \"\\e041\";\n}\n.glyphicon-tags:before {\n  content: \"\\e042\";\n}\n.glyphicon-book:before {\n  content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n  content: \"\\e044\";\n}\n.glyphicon-print:before {\n  content: \"\\e045\";\n}\n.glyphicon-camera:before {\n  content: \"\\e046\";\n}\n.glyphicon-font:before {\n  content: \"\\e047\";\n}\n.glyphicon-bold:before {\n  content: \"\\e048\";\n}\n.glyphicon-italic:before {\n  content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n  content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n  content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n  content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n  content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n  content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n  content: \"\\e055\";\n}\n.glyphicon-list:before {\n  content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n  content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n  content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n  content: \"\\e059\";\n}\n.glyphicon-picture:before {\n  content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n  content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n  content: \"\\e063\";\n}\n.glyphicon-tint:before {\n  content: \"\\e064\";\n}\n.glyphicon-edit:before {\n  content: \"\\e065\";\n}\n.glyphicon-share:before {\n  content: \"\\e066\";\n}\n.glyphicon-check:before {\n  content: \"\\e067\";\n}\n.glyphicon-move:before {\n  content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n  content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n  content: \"\\e070\";\n}\n.glyphicon-backward:before {\n  content: \"\\e071\";\n}\n.glyphicon-play:before {\n  content: \"\\e072\";\n}\n.glyphicon-pause:before {\n  content: \"\\e073\";\n}\n.glyphicon-stop:before {\n  content: \"\\e074\";\n}\n.glyphicon-forward:before {\n  content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n  content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n  content: \"\\e077\";\n}\n.glyphicon-eject:before {\n  content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n  content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n  content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n  content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n  content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n  content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n  content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n  content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n  content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n  content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n  content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n  content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n  content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n  content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n  content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n  content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n  content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n  content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n  content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n  content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n  content: \"\\e101\";\n}\n.glyphicon-gift:before {\n  content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n  content: \"\\e103\";\n}\n.glyphicon-fire:before {\n  content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n  content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n  content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n  content: \"\\e107\";\n}\n.glyphicon-plane:before {\n  content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n  content: \"\\e109\";\n}\n.glyphicon-random:before {\n  content: \"\\e110\";\n}\n.glyphicon-comment:before {\n  content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n  content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n  content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n  content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n  content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n  content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n  content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n  content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n  content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n  content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n  content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n  content: \"\\e122\";\n}\n.glyphicon-bell:before {\n  content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n  content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n  content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n  content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n  content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n  content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n  content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n  content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n  content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n  content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n  content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n  content: \"\\e134\";\n}\n.glyphicon-globe:before {\n  content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n  content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n  content: \"\\e137\";\n}\n.glyphicon-filter:before {\n  content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n  content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n  content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n  content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n  content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n  content: \"\\e143\";\n}\n.glyphicon-link:before {\n  content: \"\\e144\";\n}\n.glyphicon-phone:before {\n  content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n  content: \"\\e146\";\n}\n.glyphicon-usd:before {\n  content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n  content: \"\\e149\";\n}\n.glyphicon-sort:before {\n  content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n  content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n  content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n  content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n  content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n  content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n  content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n  content: \"\\e157\";\n}\n.glyphicon-expand:before {\n  content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n  content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n  content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n  content: \"\\e161\";\n}\n.glyphicon-flash:before {\n  content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n  content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n  content: \"\\e164\";\n}\n.glyphicon-record:before {\n  content: \"\\e165\";\n}\n.glyphicon-save:before {\n  content: \"\\e166\";\n}\n.glyphicon-open:before {\n  content: \"\\e167\";\n}\n.glyphicon-saved:before {\n  content: \"\\e168\";\n}\n.glyphicon-import:before {\n  content: \"\\e169\";\n}\n.glyphicon-export:before {\n  content: \"\\e170\";\n}\n.glyphicon-send:before {\n  content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n  content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n  content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n  content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n  content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n  content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n  content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n  content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n  content: \"\\e179\";\n}\n.glyphicon-header:before {\n  content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n  content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n  content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n  content: \"\\e183\";\n}\n.glyphicon-tower:before {\n  content: \"\\e184\";\n}\n.glyphicon-stats:before {\n  content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n  content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n  content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n  content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n  content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n  content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n  content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n  content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n  content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n  content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n  content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n  content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n  content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n  content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n  content: \"\\e200\";\n}\n.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: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\nfigure {\n  margin: 0;\n}\nimg {\n  vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  max-width: 100%;\n  height: auto;\n}\n.img-rounded {\n  border-radius: 6px;\n}\n.img-thumbnail {\n  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: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\noutput {\n  display: block;\n  padding-top: 7px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #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[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: 14.333333px;\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: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n  color: #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,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n  background-color: #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,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary .badge {\n  color: #337ab7;\n  background-color: #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,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success .badge {\n  color: #5cb85c;\n  background-color: #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,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info .badge {\n  color: #5bc0de;\n  background-color: #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,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning .badge {\n  color: #f0ad4e;\n  background-color: #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,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger .badge {\n  color: #d9534f;\n  background-color: #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-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-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-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: 3;\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: 2;\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  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  min-height: 16.42857143px;\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  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: -15px;\n    font-size: 30px;\n  }\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .icon-prev {\n    margin-left: -15px;\n  }\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-next {\n    margin-right: -15px;\n  }\n  .carousel-caption {\n    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-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-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/assets/css/components.css",
    "content": "/*\nTemplate Name: UBold Dashboard\nAuthor: CoderThemes\nEmail: coderthemes@gmail.com\nFile: Components\n*/\n/* =============\n   Buttons\n============= */\n.btn {\n  border-radius: 3px;\n  outline: none !important;\n}\n.btn-md {\n  padding: 8px 16px;\n}\n.btn-primary,\n.btn-success,\n.btn-default,\n.btn-info,\n.btn-warning,\n.btn-danger,\n.btn-inverse,\n.btn-purple,\n.btn-pink {\n  color: #ffffff !important;\n}\n.btn-default,\n.btn-default:hover,\n.btn-default:focus,\n.btn-default:active,\n.btn-default.active,\n.btn-default.focus,\n.btn-default:active,\n.btn-default:focus,\n.btn-default:hover,\n.open > .dropdown-toggle.btn-default {\n  background-color: #5fbeaa !important;\n  border: 1px solid #5fbeaa !important;\n}\n.btn-white,\n.btn-white:hover,\n.btn-white:focus,\n.btn-white:active,\n.btn-white.active,\n.btn-white.focus,\n.btn-white:active,\n.btn-white:focus,\n.btn-white:hover,\n.open > .dropdown-toggle.btn-white {\n  border: 1px solid #eaeaea !important;\n  background-color: #ffffff;\n  color: #4c5667;\n}\n.btn-white:hover,\n.btn-white:hover:hover,\n.btn-white:focus:hover,\n.btn-white:active:hover,\n.btn-white.active:hover,\n.btn-white.focus:hover,\n.btn-white:active:hover,\n.btn-white:focus:hover,\n.btn-white:hover:hover,\n.open > .dropdown-toggle.btn-white:hover {\n  background-color: #f9f9f9;\n}\n.btn-white:focus,\n.btn-white:hover:focus,\n.btn-white:focus:focus,\n.btn-white:active:focus,\n.btn-white.active:focus,\n.btn-white.focus:focus,\n.btn-white:active:focus,\n.btn-white:focus:focus,\n.btn-white:hover:focus,\n.open > .dropdown-toggle.btn-white:focus {\n  background-color: #f9f9f9;\n}\n.btn-white:active,\n.btn-white:hover:active,\n.btn-white:focus:active,\n.btn-white:active:active,\n.btn-white.active:active,\n.btn-white.focus:active,\n.btn-white:active:active,\n.btn-white:focus:active,\n.btn-white:hover:active,\n.open > .dropdown-toggle.btn-white:active {\n  background-color: #f9f9f9;\n}\n.btn-primary,\n.btn-primary:hover,\n.btn-primary:focus,\n.btn-primary:active,\n.btn-primary.active,\n.btn-primary.focus,\n.btn-primary:active,\n.btn-primary:focus,\n.btn-primary:hover,\n.open > .dropdown-toggle.btn-primary {\n  background-color: #5d9cec !important;\n  border: 1px solid #5d9cec !important;\n}\n.btn-success,\n.btn-success:hover,\n.btn-success:focus,\n.btn-success:active,\n.btn-success.active,\n.btn-success.focus,\n.btn-success:active,\n.btn-success:focus,\n.btn-success:hover,\n.open > .dropdown-toggle.btn-success {\n  background-color: #81c868 !important;\n  border: 1px solid #81c868 !important;\n}\n.btn-info,\n.btn-info:hover,\n.btn-info:focus,\n.btn-info:active,\n.btn-info.active,\n.btn-info.focus,\n.btn-info:active,\n.btn-info:focus,\n.btn-info:hover,\n.open > .dropdown-toggle.btn-info {\n  background-color: #34d3eb !important;\n  border: 1px solid #34d3eb !important;\n}\n.btn-warning,\n.btn-warning:hover,\n.btn-warning:focus,\n.btn-warning:active,\n.btn-warning.active,\n.btn-warning.focus,\n.btn-warning:active,\n.btn-warning:focus,\n.btn-warning:hover,\n.open > .dropdown-toggle.btn-warning {\n  background-color: #ffbd4a !important;\n  border: 1px solid #ffbd4a !important;\n}\n.btn-danger,\n.btn-danger:active,\n.btn-danger:focus,\n.btn-danger:hover,\n.btn-danger.active,\n.btn-danger.focus,\n.btn-danger:active,\n.btn-danger:focus,\n.btn-danger:hover,\n.open > .dropdown-toggle.btn-danger {\n  background-color: #f05050 !important;\n  border: 1px solid #f05050 !important;\n}\n.btn-inverse,\n.btn-inverse:hover,\n.btn-inverse:focus,\n.btn-inverse:active,\n.btn-inverse.active,\n.btn-inverse.focus,\n.btn-inverse:active,\n.btn-inverse:focus,\n.btn-inverse:hover,\n.open > .dropdown-toggle.btn-inverse {\n  background-color: #4c5667 !important;\n  border: 1px solid #4c5667 !important;\n  color: #ffffff;\n}\n.btn-purple,\n.btn-purple:hover,\n.btn-purple:focus,\n.btn-purple:active {\n  background-color: #7266ba !important;\n  border: 1px solid #7266ba !important;\n  color: #ffffff;\n}\n.btn-pink,\n.btn-pink:hover,\n.btn-pink:focus,\n.btn-pink:active {\n  background-color: #fb6d9d !important;\n  border: 1px solid #fb6d9d !important;\n  color: #ffffff;\n}\n.open > .dropdown-toggle.btn-primary.btn-custom,\n.open > .dropdown-toggle.btn-success.btn-custom,\n.open > .dropdown-toggle.btn-info.btn-custom,\n.open > .dropdown-toggle.btn-warning.btn-custom,\n.open > .dropdown-toggle.btn-danger.btn-custom,\n.open > .dropdown-toggle.btn-default.btn-custom {\n  border-width: 2px !important;\n  color: #ffffff !important;\n}\n.open > .dropdown-toggle.btn-white.btn-custom {\n  border-width: 2px !important;\n}\n.btn-custom.btn-default {\n  color: #5fbeaa !important;\n}\n.btn-custom.btn-primary {\n  color: #5d9cec !important;\n}\n.btn-custom.btn-success {\n  color: #81c868 !important;\n}\n.btn-custom.btn-info {\n  color: #34d3eb !important;\n}\n.btn-custom.btn-warning {\n  color: #ffbd4a !important;\n}\n.btn-custom.btn-danger {\n  color: #f05050 !important;\n}\n.btn-custom.btn-inverse {\n  color: #4c5667 !important;\n}\n.btn-custom.btn-purple {\n  color: #7266ba !important;\n}\n.btn-custom.btn-white {\n  color: #4c5667 !important;\n}\n.btn-custom.btn-white:hover,\n.btn-custom.btn-white:focus,\n.btn-custom.btn-white:active {\n  color: #4c5667 !important;\n  background-color: #f4f8fb !important;\n}\n.btn-custom.btn-pink {\n  color: #fb6d9d !important;\n}\n.btn-rounded {\n  border-radius: 2em !important;\n  padding: 6px 20px;\n}\n.btn-rounded .btn-label {\n  padding: 7px 15px 7px 20px;\n  margin-left: -20px;\n}\n.btn-rounded .btn-label-right {\n  margin-right: -20px;\n  margin-left: 12px;\n}\n.btn-custom {\n  -moz-border-radius: 2px;\n  -moz-transition: all 400ms ease-in-out;\n  -o-transition: all 400ms ease-in-out;\n  -webkit-border-radius: 2px;\n  -webkit-transition: all 400ms ease-in-out;\n  background: transparent;\n  background-color: transparent !important;\n  -webkit-border-radius: 5px;\n  border-radius: 5px;\n  -moz-border-radius: 5px;\n  background-clip: padding-box;\n  border-width: 2px !important;\n  font-weight: 600;\n  transition: all 400ms ease-in-out;\n  background-clip: inherit;\n}\n.btn-custom:hover {\n  color: #ffffff !important;\n  border-width: 2px !important;\n}\n.btn-custom:focus {\n  color: #ffffff !important;\n  border-width: 2px !important;\n}\n.btn-label {\n  background: rgba(0, 0, 0, 0.05);\n  display: inline-block;\n  padding: 7px 15px;\n  border-radius: 3px 0 0 3px;\n  margin: -7px -13px;\n  margin-right: 12px;\n}\n.btn-label-right {\n  margin-left: 12px;\n  margin-right: -13px;\n  border-radius: 0px 3px 3px 0px;\n}\n.btn-group.open .dropdown-toggle {\n  box-shadow: none;\n}\n/* File Upload */\n.fileupload {\n  overflow: hidden;\n  position: relative;\n}\n.fileupload input.upload {\n  cursor: pointer;\n  filter: alpha(opacity=0);\n  font-size: 20px;\n  margin: 0;\n  opacity: 0;\n  padding: 0;\n  position: absolute;\n  right: 0;\n  top: 0;\n}\n/* Social Buttons */\n.btn-facebook {\n  color: #ffffff !important;\n  background-color: #3b5998 !important;\n}\n.btn-twitter {\n  color: #ffffff !important;\n  background-color: #00aced !important;\n}\n.btn-linkedin {\n  color: #ffffff !important;\n  background-color: #007bb6 !important;\n}\n.btn-dribbble {\n  color: #ffffff !important;\n  background-color: #ea4c89 !important;\n}\n.btn-googleplus {\n  color: #ffffff !important;\n  background-color: #dd4b39 !important;\n}\n.btn-instagram {\n  color: #ffffff !important;\n  background-color: #517fa4 !important;\n}\n.btn-pinterest {\n  color: #ffffff !important;\n  background-color: #cb2027 !important;\n}\n.btn-dropbox {\n  color: #ffffff !important;\n  background-color: #007ee5 !important;\n}\n.btn-flickr {\n  color: #ffffff !important;\n  background-color: #ff0084 !important;\n}\n.btn-tumblr {\n  color: #ffffff !important;\n  background-color: #32506d !important;\n}\n.btn-skype {\n  color: #ffffff !important;\n  background-color: #00aff0 !important;\n}\n.btn-youtube {\n  color: #ffffff !important;\n  background-color: #bb0000 !important;\n}\n.btn-github {\n  color: #ffffff !important;\n  background-color: #171515 !important;\n}\n/* =============\n   Checkbox and Radios\n============= */\n.checkbox {\n  padding-left: 20px;\n}\n.checkbox label {\n  display: inline-block;\n  padding-left: 5px;\n  position: relative;\n}\n.checkbox label::before {\n  -o-transition: 0.3s ease-in-out;\n  -webkit-transition: 0.3s ease-in-out;\n  background-color: #ffffff;\n  border-radius: 3px;\n  border: 1px solid #cccccc;\n  content: \"\";\n  display: inline-block;\n  height: 17px;\n  left: 0;\n  margin-left: -20px;\n  position: absolute;\n  transition: 0.3s ease-in-out;\n  width: 17px;\n  outline: none !important;\n}\n.checkbox label::after {\n  color: #555555;\n  display: inline-block;\n  font-size: 11px;\n  height: 16px;\n  left: 0;\n  margin-left: -20px;\n  padding-left: 3px;\n  padding-top: 1px;\n  position: absolute;\n  top: 0;\n  width: 16px;\n}\n.checkbox input[type=\"checkbox\"] {\n  cursor: pointer;\n  opacity: 0;\n  z-index: 1;\n  outline: none !important;\n}\n.checkbox input[type=\"checkbox\"]:disabled + label {\n  opacity: 0.65;\n}\n.checkbox input[type=\"checkbox\"]:focus + label::before {\n  outline-offset: -2px;\n  outline: none;\n  outline: thin dotted;\n}\n.checkbox input[type=\"checkbox\"]:checked + label::after {\n  content: \"\\f00c\";\n  font-family: 'FontAwesome';\n}\n.checkbox input[type=\"checkbox\"]:disabled + label::before {\n  background-color: #eeeeee;\n  cursor: not-allowed;\n}\n.checkbox.checkbox-circle label::before {\n  border-radius: 50%;\n}\n.checkbox.checkbox-inline {\n  margin-top: 0;\n}\n.checkbox.checkbox-single label {\n  height: 17px;\n}\n.checkbox-custom input[type=\"checkbox\"]:checked + label::before {\n  background-color: #5fbeaa;\n  border-color: #5fbeaa;\n}\n.checkbox-custom input[type=\"checkbox\"]:checked + label::after {\n  color: #ffffff;\n}\n.checkbox-primary input[type=\"checkbox\"]:checked + label::before {\n  background-color: #5d9cec;\n  border-color: #5d9cec;\n}\n.checkbox-primary input[type=\"checkbox\"]:checked + label::after {\n  color: #ffffff;\n}\n.checkbox-danger input[type=\"checkbox\"]:checked + label::before {\n  background-color: #f05050;\n  border-color: #f05050;\n}\n.checkbox-danger input[type=\"checkbox\"]:checked + label::after {\n  color: #ffffff;\n}\n.checkbox-info input[type=\"checkbox\"]:checked + label::before {\n  background-color: #34d3eb;\n  border-color: #34d3eb;\n}\n.checkbox-info input[type=\"checkbox\"]:checked + label::after {\n  color: #ffffff;\n}\n.checkbox-warning input[type=\"checkbox\"]:checked + label::before {\n  background-color: #ffbd4a;\n  border-color: #ffbd4a;\n}\n.checkbox-warning input[type=\"checkbox\"]:checked + label::after {\n  color: #ffffff;\n}\n.checkbox-success input[type=\"checkbox\"]:checked + label::before {\n  background-color: #81c868;\n  border-color: #81c868;\n}\n.checkbox-success input[type=\"checkbox\"]:checked + label::after {\n  color: #ffffff;\n}\n.checkbox-purple input[type=\"checkbox\"]:checked + label::before {\n  background-color: #7266ba;\n  border-color: #7266ba;\n}\n.checkbox-purple input[type=\"checkbox\"]:checked + label::after {\n  color: #ffffff;\n}\n.checkbox-pink input[type=\"checkbox\"]:checked + label::before {\n  background-color: #fb6d9d;\n  border-color: #fb6d9d;\n}\n.checkbox-pink input[type=\"checkbox\"]:checked + label::after {\n  color: #ffffff;\n}\n.checkbox-inverse input[type=\"checkbox\"]:checked + label::before {\n  background-color: #4c5667;\n  border-color: #4c5667;\n}\n.checkbox-inverse input[type=\"checkbox\"]:checked + label::after {\n  color: #ffffff;\n}\n/* Radios */\n.radio {\n  padding-left: 20px;\n}\n.radio label {\n  display: inline-block;\n  padding-left: 5px;\n  position: relative;\n}\n.radio label::before {\n  -o-transition: border 0.5s ease-in-out;\n  -webkit-transition: border 0.5s ease-in-out;\n  background-color: #ffffff;\n  border-radius: 50%;\n  border: 1px solid #cccccc;\n  content: \"\";\n  display: inline-block;\n  height: 17px;\n  left: 0;\n  margin-left: -20px;\n  position: absolute;\n  transition: border 0.5s ease-in-out;\n  width: 17px;\n  outline: none !important;\n}\n.radio label::after {\n  -moz-transition: -moz-transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33);\n  -ms-transform: scale(0, 0);\n  -o-transform: scale(0, 0);\n  -o-transition: -o-transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33);\n  -webkit-transform: scale(0, 0);\n  -webkit-transition: -webkit-transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33);\n  background-color: #555555;\n  border-radius: 50%;\n  content: \" \";\n  display: inline-block;\n  height: 11px;\n  left: 3px;\n  margin-left: -20px;\n  position: absolute;\n  top: 3px;\n  transform: scale(0, 0);\n  transition: transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33);\n  width: 11px;\n}\n.radio input[type=\"radio\"] {\n  cursor: pointer;\n  opacity: 0;\n  z-index: 1;\n  outline: none !important;\n}\n.radio input[type=\"radio\"]:disabled + label {\n  opacity: 0.65;\n}\n.radio input[type=\"radio\"]:focus + label::before {\n  outline-offset: -2px;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline: thin dotted;\n}\n.radio input[type=\"radio\"]:checked + label::after {\n  -ms-transform: scale(1, 1);\n  -o-transform: scale(1, 1);\n  -webkit-transform: scale(1, 1);\n  transform: scale(1, 1);\n}\n.radio input[type=\"radio\"]:disabled + label::before {\n  cursor: not-allowed;\n}\n.radio.radio-inline {\n  margin-top: 0;\n}\n.radio.radio-single label {\n  height: 17px;\n}\n.radio-custom input[type=\"radio\"] + label::after {\n  background-color: #5fbeaa;\n}\n.radio-custom input[type=\"radio\"]:checked + label::before {\n  border-color: #5fbeaa;\n}\n.radio-custom input[type=\"radio\"]:checked + label::after {\n  background-color: #5fbeaa;\n}\n.radio-primary input[type=\"radio\"] + label::after {\n  background-color: #5d9cec;\n}\n.radio-primary input[type=\"radio\"]:checked + label::before {\n  border-color: #5d9cec;\n}\n.radio-primary input[type=\"radio\"]:checked + label::after {\n  background-color: #5d9cec;\n}\n.radio-danger input[type=\"radio\"] + label::after {\n  background-color: #f05050;\n}\n.radio-danger input[type=\"radio\"]:checked + label::before {\n  border-color: #f05050;\n}\n.radio-danger input[type=\"radio\"]:checked + label::after {\n  background-color: #f05050;\n}\n.radio-info input[type=\"radio\"] + label::after {\n  background-color: #34d3eb;\n}\n.radio-info input[type=\"radio\"]:checked + label::before {\n  border-color: #34d3eb;\n}\n.radio-info input[type=\"radio\"]:checked + label::after {\n  background-color: #34d3eb;\n}\n.radio-warning input[type=\"radio\"] + label::after {\n  background-color: #ffbd4a;\n}\n.radio-warning input[type=\"radio\"]:checked + label::before {\n  border-color: #ffbd4a;\n}\n.radio-warning input[type=\"radio\"]:checked + label::after {\n  background-color: #ffbd4a;\n}\n.radio-success input[type=\"radio\"] + label::after {\n  background-color: #81c868;\n}\n.radio-success input[type=\"radio\"]:checked + label::before {\n  border-color: #81c868;\n}\n.radio-success input[type=\"radio\"]:checked + label::after {\n  background-color: #81c868;\n}\n.radio-purple input[type=\"radio\"] + label::after {\n  background-color: #7266ba;\n}\n.radio-purple input[type=\"radio\"]:checked + label::before {\n  border-color: #7266ba;\n}\n.radio-purple input[type=\"radio\"]:checked + label::after {\n  background-color: #7266ba;\n}\n.radio-pink input[type=\"radio\"] + label::after {\n  background-color: #fb6d9d;\n}\n.radio-pink input[type=\"radio\"]:checked + label::before {\n  border-color: #fb6d9d;\n}\n.radio-pink input[type=\"radio\"]:checked + label::after {\n  background-color: #fb6d9d;\n}\n/* =============\n   Panels\n============= */\n.panel {\n  border: none;\n  margin-bottom: 20px;\n}\n.panel .panel-body {\n  padding: 20px;\n}\n.panel .panel-body p {\n  margin: 0px;\n}\n.panel .panel-body p + p {\n  margin-top: 15px;\n}\n.panel-heading {\n  border: none !important;\n  padding: 10px 20px;\n}\n.panel-default > .panel-heading {\n  background-color: #f4f8fb;\n  border-bottom: none;\n  color: #797979;\n}\n.panel-title {\n  font-size: 15px;\n  font-weight: 600;\n  margin-bottom: 0;\n  margin-top: 0;\n  text-transform: uppercase;\n  letter-spacing: 0.03em;\n}\n.panel-footer {\n  background: #f4f8fb;\n  border-top: 0px;\n}\n.panel-color .panel-title {\n  color: #ffffff;\n}\n.panel-custom > .panel-heading {\n  background-color: #5fbeaa;\n}\n.panel-primary > .panel-heading {\n  background-color: #5d9cec;\n}\n.panel-success > .panel-heading {\n  background-color: #81c868;\n}\n.panel-info > .panel-heading {\n  background-color: #34d3eb;\n}\n.panel-warning > .panel-heading {\n  background-color: #ffbd4a;\n}\n.panel-danger > .panel-heading {\n  background-color: #f05050;\n}\n.panel-purple > .panel-heading {\n  background-color: #7266ba;\n}\n.panel-pink > .panel-heading {\n  background-color: #fb6d9d;\n}\n.panel-inverse > .panel-heading {\n  background-color: #4c5667;\n}\n.panel-border .panel-heading {\n  background-color: #ffffff;\n  border-top: 3px solid #DADFE2 !important;\n  padding: 10px 20px 0px;\n}\n.panel-border .panel-body {\n  padding: 15px 20px 20px 20px;\n}\n.panel-border.panel-custom .panel-heading {\n  border-color: #5fbeaa !important;\n  color: #5fbeaa !important;\n}\n.panel-border.panel-primary .panel-heading {\n  border-color: #5d9cec !important;\n  color: #5d9cec !important;\n}\n.panel-border.panel-success .panel-heading {\n  border-color: #81c868 !important;\n  color: #81c868 !important;\n}\n.panel-border.panel-info .panel-heading {\n  border-color: #34d3eb !important;\n  color: #34d3eb !important;\n}\n.panel-border.panel-warning .panel-heading {\n  border-color: #ffbd4a !important;\n  color: #ffbd4a !important;\n}\n.panel-border.panel-danger .panel-heading {\n  border-color: #f05050 !important;\n  color: #f05050 !important;\n}\n.panel-border.panel-purple .panel-heading {\n  border-color: #7266ba !important;\n  color: #7266ba !important;\n}\n.panel-border.panel-pink .panel-heading {\n  border-color: #fb6d9d !important;\n  color: #fb6d9d !important;\n}\n.panel-border.panel-inverse .panel-heading {\n  border-color: #4c5667 !important;\n  color: #4c5667 !important;\n}\n.panel-group .panel .panel-heading a[data-toggle=collapse].collapsed:before {\n  content: '\\f0d7';\n}\n.panel-group .panel .panel-heading .accordion-toggle.collapsed:before {\n  content: '\\f0d7';\n}\n.panel-group .panel .panel-heading a[data-toggle=collapse] {\n  display: block;\n}\n.panel-group .panel .panel-heading a[data-toggle=collapse]:before {\n  content: '\\f0d8';\n  display: block;\n  float: right;\n  font-family: 'FontAwesome';\n  font-size: 14px;\n  text-align: right;\n  width: 25px;\n}\n.panel-group .panel .panel-heading .accordion-toggle {\n  display: block;\n}\n.panel-group .panel .panel-heading .accordion-toggle:before {\n  content: '\\f0d8';\n  display: block;\n  float: right;\n  font-family: 'FontAwesome';\n  font-size: 14px;\n  text-align: right;\n  width: 25px;\n}\n.panel-group .panel .panel-heading + .panel-collapse .panel-body {\n  border-top: none;\n}\n.panel-group .panel-heading {\n  padding: 12px 26px;\n}\n.panel-group.panel-group-joined .panel + .panel {\n  border-top: 1px solid #eeeeee;\n  margin-top: 0;\n}\n.panel-group-joined .panel-group .panel + .panel {\n  border-top: 1px solid #eeeeee;\n  margin-top: 0;\n}\n.panel .nav-pills li a {\n  color: #4c5667 !important;\n}\n.panel .nav-pills li.active a {\n  color: #ffffff !important;\n}\n/* =============\n   Portlets\n============= */\n.portlet {\n  background: #ffffff;\n  border: 1px solid rgba(54, 64, 74, 0.05);\n  -webkit-border-radius: 5px;\n  border-radius: 5px;\n  -moz-border-radius: 5px;\n  background-clip: padding-box;\n  margin-bottom: 20px;\n}\n.portlet .portlet-heading {\n  -webkit-border-radius: 3px 3px 0px 0px;\n  border-radius: 3px 3px 0px 0px;\n  -moz-border-radius: 3px 3px 0px 0px;\n  background-clip: padding-box;\n  color: #ffffff;\n  padding: 12px 20px;\n}\n.portlet .portlet-heading .portlet-title {\n  color: #ffffff;\n  float: left;\n  font-size: 15px;\n  font-weight: 600;\n  margin-bottom: 0;\n  margin-top: 0;\n  text-transform: uppercase;\n  letter-spacing: 0.03em;\n}\n.portlet .portlet-heading .portlet-widgets {\n  display: inline-block;\n  float: right;\n  font-size: 15px;\n  line-height: 30px;\n  padding-left: 15px;\n  position: relative;\n  text-align: right;\n}\n.portlet .portlet-heading .portlet-widgets .divider {\n  margin: 0 5px;\n}\n.portlet .portlet-heading .portlet-widgets .collapsed .ion-minus-round:before {\n  content: \"\\f217\" !important;\n}\n.portlet .portlet-heading a {\n  color: #999999;\n}\n.portlet .portlet-body {\n  -moz-border-radius-bottomleft: 5px;\n  -moz-border-radius-bottomright: 5px;\n  -webkit-border-bottom-left-radius: 5px;\n  -webkit-border-bottom-right-radius: 5px;\n  background: #ffffff;\n  border-bottom-left-radius: 5px;\n  border-bottom-right-radius: 5px;\n  padding: 15px;\n}\n.portlet-default .portlet-title {\n  color: #797979 !important;\n}\n.portlet .portlet-heading.bg-custom a,\n.portlet .portlet-heading.bg-purple a,\n.portlet .portlet-heading.bg-info a,\n.portlet .portlet-heading.bg-success a,\n.portlet .portlet-heading.bg-primary a,\n.portlet .portlet-heading.bg-danger a,\n.portlet .portlet-heading.bg-warning a,\n.portlet .portlet-heading.bg-inverse a,\n.portlet .portlet-heading.bg-pink a {\n  color: #ffffff;\n}\n.panel-disabled {\n  background: rgba(243, 242, 241, 0.5);\n  bottom: 15px;\n  left: 0px;\n  position: absolute;\n  right: -5px;\n  top: 0;\n}\n.loader-1 {\n  -moz-animation: loaderAnimate 1000ms linear infinite;\n  -o-animation: loaderAnimate 1000ms linear infinite;\n  -webkit-animation: loaderAnimate 1000ms linear infinite;\n  animation: loaderAnimate 1000ms linear infinite;\n  clip: rect(0, 30px, 30px, 15px);\n  height: 30px;\n  left: 50%;\n  margin-left: -15px;\n  margin-top: -15px;\n  position: absolute;\n  top: 50%;\n  width: 30px;\n}\n.loader-1:after {\n  -moz-animation: loaderAnimate2 1000ms ease-in-out infinite;\n  -o-animation: loaderAnimate2 1000ms ease-in-out infinite;\n  -webkit-animation: loaderAnimate2 1000ms ease-in-out infinite;\n  animation: loaderAnimate2 1000ms ease-in-out infinite;\n  border-radius: 50%;\n  clip: rect(0, 30px, 30px, 15px);\n  content: '';\n  height: 30px;\n  position: absolute;\n  width: 30px;\n}\n/* =============\n   Progressbars\n============= */\n.progress {\n  -webkit-box-shadow: none !important;\n  background-color: #ebeff2;\n  box-shadow: none !important;\n  height: 10px;\n  margin-bottom: 18px;\n  overflow: hidden;\n}\n.progress-bar {\n  box-shadow: none;\n  font-size: 8px;\n  font-weight: 600;\n  line-height: 12px;\n}\n.progress.progress-sm {\n  height: 5px !important;\n}\n.progress.progress-sm .progress-bar {\n  font-size: 8px;\n  line-height: 5px;\n}\n.progress.progress-md {\n  height: 15px !important;\n}\n.progress.progress-md .progress-bar {\n  font-size: 10.8px;\n  line-height: 14.4px;\n}\n.progress.progress-lg {\n  height: 20px !important;\n}\n.progress.progress-lg .progress-bar {\n  font-size: 12px;\n  line-height: 20px;\n}\n.progress-bar-primary {\n  background-color: #5d9cec;\n}\n.progress-bar-success {\n  background-color: #81c868;\n}\n.progress-bar-info {\n  background-color: #34d3eb;\n}\n.progress-bar-warning {\n  background-color: #ffbd4a;\n}\n.progress-bar-danger {\n  background-color: #f05050;\n}\n.progress-bar-inverse {\n  background-color: #4c5667;\n}\n.progress-bar-purple {\n  background-color: #7266ba;\n}\n.progress-bar-pink {\n  background-color: #fb6d9d;\n}\n.progress-bar-custom {\n  background-color: #5fbeaa;\n}\n.progress-animated {\n  -webkit-animation-duration: 5s;\n  -webkit-animation-name: animationProgress;\n  -webkit-transition: 5s all;\n  animation-duration: 5s;\n  animation-name: animationProgress;\n  transition: 5s all;\n}\n/* Progressbar Vertical */\n.progress-vertical {\n  min-height: 250px;\n  height: 250px;\n  width: 10px;\n  position: relative;\n  display: inline-block;\n  margin-bottom: 0;\n  margin-right: 20px;\n}\n.progress-vertical .progress-bar {\n  width: 100%;\n}\n.progress-vertical-bottom {\n  min-height: 250px;\n  height: 250px;\n  position: relative;\n  width: 10px;\n  display: inline-block;\n  margin-bottom: 0;\n  margin-right: 20px;\n}\n.progress-vertical-bottom .progress-bar {\n  width: 100%;\n  position: absolute;\n  bottom: 0;\n}\n.progress-vertical.progress-sm,\n.progress-vertical-bottom.progress-sm {\n  width: 5px !important;\n}\n.progress-vertical.progress-sm .progress-bar,\n.progress-vertical-bottom.progress-sm .progress-bar {\n  font-size: 8px;\n  line-height: 5px;\n}\n.progress-vertical.progress-md,\n.progress-vertical-bottom.progress-md {\n  width: 15px !important;\n}\n.progress-vertical.progress-md .progress-bar,\n.progress-vertical-bottom.progress-md .progress-bar {\n  font-size: 10.8px;\n  line-height: 14.4px;\n}\n.progress-vertical.progress-lg,\n.progress-vertical-bottom.progress-lg {\n  width: 20px !important;\n}\n.progress-vertical.progress-lg .progress-bar,\n.progress-vertical-bottom.progress-lg .progress-bar {\n  font-size: 12px;\n  line-height: 20px;\n}\n/* =============\n   Tables\n============= */\n.table {\n  margin-bottom: 10px;\n}\n.table-striped > tbody > tr:nth-of-type(odd),\n.table-hover > tbody > tr:hover,\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: #f4f8fb !important;\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.table > thead > tr > th,\n.table-bordered {\n  border-top: 1px solid #ebeff2;\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 #ebeff2;\n}\n.table > thead > tr > th {\n  vertical-align: bottom;\n  border-bottom: 2px solid #ebeff2;\n}\ntbody {\n  color: #797979;\n}\nth {\n  color: #666666;\n  font-weight: 600;\n}\n.table-bordered {\n  border: 1px solid #ebeff2;\n}\ntable.focus-on tbody tr.focused th {\n  background-color: #5fbeaa;\n  color: #ffffff;\n}\ntable.focus-on tbody tr.focused td {\n  background-color: #5fbeaa;\n  color: #ffffff;\n}\n.table-rep-plugin .table-responsive {\n  border: none !important;\n}\n.table-rep-plugin tbody th {\n  font-size: 14px;\n  font-weight: normal;\n}\n.table-rep-plugin .checkbox-row {\n  padding-left: 40px;\n}\n.table-rep-plugin .checkbox-row label {\n  display: inline-block;\n  padding-left: 5px;\n  position: relative;\n}\n.table-rep-plugin .checkbox-row label::before {\n  -o-transition: 0.3s ease-in-out;\n  -webkit-transition: 0.3s ease-in-out;\n  background-color: #ffffff;\n  border-radius: 3px;\n  border: 1px solid #cccccc;\n  content: \"\";\n  display: inline-block;\n  height: 17px;\n  left: 0;\n  margin-left: -20px;\n  position: absolute;\n  transition: 0.3s ease-in-out;\n  width: 17px;\n  outline: none !important;\n}\n.table-rep-plugin .checkbox-row label::after {\n  color: #555555;\n  display: inline-block;\n  font-size: 11px;\n  height: 16px;\n  left: 0;\n  margin-left: -20px;\n  padding-left: 3px;\n  padding-top: 1px;\n  position: absolute;\n  top: -1px;\n  width: 16px;\n}\n.table-rep-plugin .checkbox-row input[type=\"checkbox\"] {\n  cursor: pointer;\n  opacity: 0;\n  z-index: 1;\n  outline: none !important;\n}\n.table-rep-plugin .checkbox-row input[type=\"checkbox\"]:disabled + label {\n  opacity: 0.65;\n}\n.table-rep-plugin .checkbox-row input[type=\"checkbox\"]:focus + label::before {\n  outline-offset: -2px;\n  outline: none;\n}\n.table-rep-plugin .checkbox-row input[type=\"checkbox\"]:checked + label::after {\n  content: \"\\f00c\";\n  font-family: 'FontAwesome';\n}\n.table-rep-plugin .checkbox-row input[type=\"checkbox\"]:disabled + label::before {\n  background-color: #eeeeee;\n  cursor: not-allowed;\n}\n.table-rep-plugin .checkbox-row input[type=\"checkbox\"]:checked + label::before {\n  background-color: #5fbeaa;\n  border-color: #5fbeaa;\n}\n.table-rep-plugin .checkbox-row input[type=\"checkbox\"]:checked + label::after {\n  color: #ffffff;\n}\n.fixed-table-container tbody .selected td {\n  background-color: #F4F8FB;\n}\n.modal-block {\n  background: transparent;\n  margin: 40px auto;\n  max-width: 600px;\n  padding: 0;\n  position: relative;\n  text-align: left;\n}\n/* Data table */\n#datatable-editable .actions a {\n  padding: 5px;\n}\n#datatable-editable .form-control {\n  background-color: #ffffff;\n  width: 100%;\n}\n#datatable-editable .fa-trash-o {\n  color: #f05050;\n}\n#datatable-editable .fa-times {\n  color: #f05050;\n}\n#datatable-editable .fa-pencil {\n  color: #29b6f6;\n}\n#datatable-editable .fa-save {\n  color: #33b86c;\n}\n#datatable td {\n  font-weight: normal;\n}\ndiv.dataTables_paginate ul.pagination {\n  margin-top: 30px;\n}\ndiv.dataTables_info {\n  padding-top: 38px;\n}\n/* Footable */\n.footable-odd {\n  background-color: #ffffff;\n}\n.footable-detail-show {\n  background-color: #ebeff2;\n}\n.footable-row-detail {\n  background-color: #F0F4F7;\n}\n/* Bootstrap Table */\n.fixed-table-pagination .pagination-detail,\n.fixed-table-pagination div.pagination {\n  margin-top: 20px;\n}\n.fixed-table-container {\n  border: 1px solid #ebeff2 !important;\n}\n.bootstrap-table .table > thead > tr > th {\n  border-bottom: 2px solid #ebeff2;\n  background: #ebeff2;\n}\n.fixed-table-container thead th .th-inner {\n  padding: 9px 12px;\n}\n.bootstrap-table .table,\n.bootstrap-table .table > tbody > tr > td,\n.bootstrap-table .table > tbody > tr > th,\n.bootstrap-table .table > tfoot > tr > td,\n.bootstrap-table .table > tfoot > tr > th,\n.bootstrap-table .table > thead > tr > td {\n  padding: 8px 12px !important;\n}\n/* =============\n   Widget\n============= */\n/* Widget-box styles */\n.widget-box-1 i.inform {\n  font-size: 20px;\n  cursor: pointer;\n}\n.widget-box-1 h4 {\n  margin-bottom: 5px;\n  margin-top: 0px;\n}\n.widget-box-1 h2 {\n  margin: 20px;\n  font-weight: 600;\n}\n.widget-box-1 p {\n  margin-bottom: 0px;\n}\n.widget-s-1 {\n  border-radius: 6px;\n}\n/* Widget (background-icon) */\n.widget-bg-color-icon .bg-icon {\n  height: 80px;\n  width: 80px;\n  text-align: center;\n  -webkit-border-radius: 50%;\n  border-radius: 50%;\n  -moz-border-radius: 50%;\n  background-clip: padding-box;\n}\n.widget-bg-color-icon .bg-icon i {\n  font-size: 32px;\n  line-height: 80px;\n}\n.widget-bg-color-icon .bg-icon-info {\n  background-color: rgba(52, 211, 235, 0.2);\n  border: 1px solid #34d3eb;\n}\n.widget-bg-color-icon .bg-icon-primary {\n  background-color: rgba(93, 156, 236, 0.2);\n  border: 1px solid #5d9cec;\n}\n.widget-bg-color-icon .bg-icon-pink {\n  background-color: rgba(251, 109, 157, 0.2);\n  border: 1px solid #fb6d9d;\n}\n.widget-bg-color-icon .bg-icon-purple {\n  background-color: rgba(114, 102, 186, 0.2);\n  border: 1px solid #7266ba;\n}\n.widget-bg-color-icon .bg-icon-success {\n  background-color: rgba(129, 200, 104, 0.2);\n  border: 1px solid #81c868;\n}\n.widget-bg-color-icon .bg-icon-custom {\n  background-color: rgba(95, 190, 170, 0.2);\n  border: 1px solid #5fbeaa;\n}\n.widget-bg-color-icon .bg-icon-warning {\n  background-color: rgba(255, 189, 74, 0.2);\n  border: 1px solid #ffbd4a;\n}\n.widget-bg-color-icon .bg-icon-danger {\n  background-color: rgba(240, 80, 80, 0.2);\n  border: 1px solid #f05050;\n}\n.widget-bg-color-icon .bg-icon-inverse {\n  background-color: rgba(76, 86, 103, 0.2);\n  border: 1px solid #4c5667;\n}\n.mini-stat-icon {\n  -moz-border-radius: 100%;\n  -webkit-border-radius: 100%;\n  border-radius: 100%;\n  background-color: rgba(255, 255, 255, 0.2);\n  display: inline-block;\n  float: left;\n  font-size: 30px;\n  height: 60px;\n  line-height: 60px;\n  margin-right: 10px;\n  text-align: center;\n  width: 60px;\n}\n.mini-stat-info {\n  padding-top: 2px;\n  color: #eeeeee;\n}\n.mini-stat-info span {\n  color: #ffffff;\n  display: block;\n  font-size: 24px;\n  font-weight: 600;\n}\n.mini-stat-info span.name {\n  color: #ffffff;\n  display: block;\n  font-size: 18px;\n  font-weight: 600;\n  margin-top: 5px;\n}\n.widget-inline {\n  padding: 20px 0px !important;\n}\n.widget-inline .col-lg-3 {\n  padding: 0px;\n}\n.widget-inline .widget-inline-box {\n  border-right: 1px solid #e3e8f1;\n  padding: 20px;\n}\n.widget-inline .widget-inline-box i {\n  font-size: 32px;\n}\n/* Inbox-widget */\n.inbox-widget .inbox-item {\n  border-bottom: 1px solid #f1f1f1;\n  overflow: hidden;\n  padding: 10px 0;\n  position: relative;\n}\n.inbox-widget .inbox-item .inbox-item-img {\n  display: block;\n  float: left;\n  margin-right: 15px;\n  width: 40px;\n}\n.inbox-widget .inbox-item img {\n  width: 40px;\n}\n.inbox-widget .inbox-item .inbox-item-author {\n  color: #333333;\n  display: block;\n  margin: 0;\n}\n.inbox-widget .inbox-item .inbox-item-text {\n  color: #a0a0a0;\n  display: block;\n  font-size: 12px;\n  margin: 0;\n}\n.inbox-widget .inbox-item .inbox-item-date {\n  color: #a9a9a9;\n  font-size: 11px;\n  position: absolute;\n  right: 7px;\n  top: 2px;\n}\n/* Chat widget */\n.conversation-list {\n  list-style: none;\n  height: 332px;\n  padding: 0px 20px;\n}\n.conversation-list li {\n  margin-bottom: 24px;\n}\n.conversation-list .chat-avatar {\n  display: inline-block;\n  float: left;\n  text-align: center;\n  width: 42px;\n}\n.conversation-list .chat-avatar img {\n  border-radius: 100%;\n  width: 100%;\n}\n.conversation-list .chat-avatar i {\n  font-size: 12px;\n  font-style: normal;\n}\n.conversation-list .ctext-wrap {\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n  background: #f4f8fb;\n  border-radius: 3px;\n  display: inline-block;\n  padding: 12px;\n  position: relative;\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.conversation-list .ctext-wrap i {\n  color: #1a2942;\n  display: block;\n  font-size: 12px;\n  font-style: normal;\n  font-weight: bold;\n  position: relative;\n}\n.conversation-list .ctext-wrap p {\n  margin: 0px;\n  padding-top: 3px;\n}\n.conversation-list .ctext-wrap:after {\n  right: 100%;\n  top: 0%;\n  border: solid transparent;\n  content: \" \";\n  height: 0;\n  width: 0;\n  position: absolute;\n  pointer-events: none;\n  border-top-color: #f4f8fb;\n  border-width: 8px;\n  margin-left: -1px;\n  border-right-color: #f4f8fb;\n}\n.conversation-list .conversation-text {\n  display: inline-block;\n  float: left;\n  font-size: 12px;\n  margin-left: 12px;\n  width: 70%;\n}\n.conversation-list .odd .chat-avatar {\n  float: right !important;\n}\n.conversation-list .odd .conversation-text {\n  float: right !important;\n  margin-right: 12px;\n  text-align: right;\n  width: 70% !important;\n}\n.conversation-list .odd .ctext-wrap:after {\n  border-color: rgba(238, 238, 242, 0) !important;\n  border-left-color: #f4f8fb !important;\n  border-top-color: #f4f8fb !important;\n  left: 100% !important;\n  margin-right: -1px;\n}\n.chat-send {\n  padding-left: 0px;\n  padding-right: 30px;\n}\n.chat-send button {\n  width: 100%;\n}\n.chat-inputbar {\n  padding-left: 30px;\n}\n/* Todos widget */\n#todo-message {\n  font-size: 16px;\n}\n.todo-list li {\n  border-bottom: 1px solid #eeeeee;\n  border-radius: 0px;\n  border: 0px;\n  margin: 0px;\n  padding: 1px;\n  color: #98a6ad;\n}\n.todo-list li:last-of-type {\n  border-bottom: none;\n}\n.todo-send {\n  padding-left: 0px;\n}\n/* Widget-chart */\n.widget-chart ul li {\n  width: 31.5%;\n  display: inline-block;\n  padding: 0px;\n}\n.widget-panel {\n  padding: 30px 20px;\n  padding-left: 30px;\n  border-radius: 4px;\n  position: relative;\n  margin-bottom: 20px;\n}\n.widget-panel i {\n  font-size: 60px;\n  padding: 30px;\n  background: rgba(255, 255, 255, 0.2);\n  position: absolute;\n  right: 0px;\n  bottom: 0px;\n  top: 0px;\n  line-height: 60px;\n}\n.widget-style-2 i {\n  background: rgba(244, 248, 251, 0.6) !important;\n  font-size: 48px;\n  padding: 30px 40px;\n}\n/* Google maps */\n.gmap iframe {\n  width: 100%;\n  margin: 0px !important;\n  padding: 0px !important;\n}\n.gmap-info:before {\n  color: #333333;\n  content: \"\\f041\";\n  font-family: \"FontAwesome\";\n  font-size: 35px;\n  left: 10px;\n  position: absolute;\n  top: 8px;\n}\n.gmap-info {\n  float: left;\n  padding: 0 20px 0 50px;\n  position: relative;\n}\n.gmap-buttons {\n  float: right;\n  margin-top: 28px;\n}\n.gmap-buttons .btn {\n  margin-left: 3px;\n}\n/* Google maps ends */\n/* Table with Action */\n.table-actions-bar tr td {\n  vertical-align: middle !important;\n}\n.table-actions-bar .table-action-btn {\n  color: #98a6ad;\n  display: inline-block;\n  width: 28px;\n  border-radius: 50%;\n  text-align: center;\n  line-height: 24px;\n  font-size: 20px;\n}\n.table-actions-bar .table-action-btn:hover {\n  color: #5fbeaa;\n  border-color: #5fbeaa;\n}\n/* Transaction */\n.transaction-list li {\n  padding: 7px 0px;\n  border-bottom: 1px solid #ebeff2;\n  clear: both;\n  position: relative;\n}\n.transaction-list i {\n  width: 20px;\n  position: absolute;\n  top: 10px;\n  font-size: 12px;\n}\n.transaction-list .tran-text {\n  padding-left: 25px;\n  white-space: nowrap;\n  display: inline-block;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  width: 115px;\n}\n.transaction-list .tran-price {\n  margin-left: 30px;\n}\n/* Friend list */\n.friend-list a {\n  margin: 5px;\n  display: inline-block;\n}\n.friend-list .extra-number {\n  height: 48px;\n  width: 48px;\n  display: block;\n  line-height: 48px;\n  color: #98a6ad;\n  font-weight: 700;\n  background-color: #ebeff2;\n  border-radius: 50%;\n  border: 1px solid #98a6ad;\n}\n/* Profile widget */\n.profile-widget .bg-profile {\n  height: 125px;\n}\n.profile-widget .img-thumbnail {\n  margin-top: -42px;\n  border: none;\n}\n.profile-widget .widget-list {\n  padding: 10px;\n  margin-top: 20px;\n  margin-left: 0px;\n  padding-bottom: 30px;\n}\n.profile-widget .widget-list span {\n  display: block;\n  font-weight: bold;\n  font-size: 18px;\n}\n/*  Bar widget */\n.bar-widget .iconbox {\n  display: inline-block;\n  height: 50px;\n  width: 50px;\n  margin-right: 20px;\n  -webkit-border-radius: 50%;\n  border-radius: 50%;\n  -moz-border-radius: 50%;\n  background-clip: padding-box;\n  color: #ffffff;\n  text-align: center;\n}\n.bar-widget .iconbox i {\n  line-height: 50px;\n  font-size: 20px;\n}\n/* =============\n   Form elements\n============= */\n.error {\n  color: #f05050;\n  font-size: 12px;\n  font-weight: 500;\n}\n.parsley-error {\n  border-color: #f05050 !important;\n}\n.parsley-errors-list {\n  display: none;\n  margin: 0;\n  padding: 0;\n}\n.parsley-errors-list.filled {\n  display: block;\n}\n.parsley-errors-list > li {\n  font-size: 12px;\n  list-style: none;\n  color: #f6504d;\n}\n.datepicker {\n  padding: 8px;\n}\n.datepicker th {\n  font-size: 14px !important;\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.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.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-image: none;\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: #5fbeaa;\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: #5fbeaa !important;\n  background-image: none;\n  box-shadow: none;\n  text-shadow: none;\n}\n.datepicker thead tr:first-child th:hover,\n.datepicker tfoot tr th:hover {\n  background-color: #fafafa;\n}\n.datepicker-inline {\n  border: 2px solid #eeeeee;\n}\n.daterangepicker td.active,\n.daterangepicker td.active:hover {\n  background-color: #5d9cec;\n  border-color: #5d9cec;\n}\n.daterangepicker .input-mini.active {\n  border: 1px solid #AAAAAA;\n}\n.daterangepicker .ranges li {\n  -webkit-border-radius: 2px;\n  border-radius: 2px;\n  -moz-border-radius: 2px;\n  background-clip: padding-box;\n  color: #36404a;\n  font-weight: 600;\n  font-size: 12px;\n}\n.daterangepicker select.hourselect,\n.daterangepicker select.minuteselect,\n.daterangepicker select.secondselect,\n.daterangepicker select.ampmselect {\n  border: 1px solid #e3e3e3;\n  padding: 2px;\n  width: 60px;\n}\n.daterangepicker .ranges li.active,\n.daterangepicker .ranges li:hover {\n  background-color: #5d9cec;\n  border: 1px solid #5d9cec;\n}\n.search-input {\n  margin-bottom: 10px;\n}\n.ms-selectable {\n  box-shadow: none;\n  outline: none !important;\n}\n.ms-container .ms-list.ms-focus {\n  box-shadow: none;\n}\n.ms-container .ms-selectable li.ms-hover {\n  background-color: #5d9cec;\n}\n.ms-container .ms-selection li.ms-hover {\n  background-color: #5d9cec;\n}\n.note-editor {\n  border: 1px solid #eeeeee;\n  position: relative;\n}\n.note-editor .note-toolbar {\n  background-color: #f4f8fb;\n  border-bottom: 1px solid #eeeeee;\n  margin: 0;\n}\n.note-editor .note-statusbar {\n  background-color: #ffffff;\n}\n.note-editor .note-statusbar .note-resizebar {\n  border-top: none;\n  height: 15px;\n  padding-top: 3px;\n}\n.note-popover .popover .popover-content {\n  padding: 5px 0 10px 5px;\n}\n.note-toolbar {\n  padding: 5px 0 10px 5px;\n}\n.code-edit-wrap {\n  padding: 0px !important;\n}\n.cm-s-ambiance .CodeMirror-linenumber {\n  color: #bcbcbc;\n}\n.cm-s-ambiance .CodeMirror-gutters {\n  background-color: #4c5667 !important;\n  box-shadow: none;\n}\n.cm-s-ambiance.CodeMirror {\n  background-color: #4c5667 !important;\n  box-shadow: none;\n}\n.bootstrap-timepicker-widget table td a:hover {\n  background-color: transparent;\n  border-color: transparent;\n  border-radius: 4px;\n  color: #5d9cec;\n  text-decoration: none;\n}\n.editor-horizontal .popover-content {\n  padding: 9px 30px;\n}\n.wizard > .content {\n  background: #ffffff;\n  min-height: 240px;\n  padding: 20px;\n}\n.wizard > .content > .body {\n  padding: 0px;\n}\n.wizard > .content > .body input {\n  border: 1px solid #E3E3E3;\n}\n.wizard > .content > .body ul > li {\n  display: block;\n  line-height: 30px;\n}\n.wizard > .content > .body label.error {\n  color: #f05050;\n  margin-left: 0;\n}\n.wizard > .content > .body label {\n  display: inline-block;\n  margin-top: 10px;\n}\n.wizard > .steps .number {\n  border-radius: 50%;\n  background-color: rgba(255, 255, 255, 0.3);\n  display: inline-block;\n  line-height: 30px;\n  margin-right: 10px;\n  width: 30px;\n  text-align: center;\n}\n.wizard > .steps .disabled a {\n  background: #ffffff;\n  color: #333333;\n  cursor: default;\n  border: 1px solid #eaeaea;\n}\n.wizard > .steps .disabled a:hover {\n  background: #f9f9f9;\n  color: #333333;\n  cursor: default;\n  border: 1px solid #eaeaea;\n}\n.wizard > .steps .disabled a:active {\n  background: #f9f9f9;\n  color: #333333;\n  cursor: default;\n  border: 1px solid #eaeaea;\n}\n.wizard > .steps .current a {\n  background: #5fbeaa;\n}\n.wizard > .steps .current a:hover {\n  background: #5fbeaa;\n}\n.wizard > .steps .current a:hover .number {\n  color: #ffffff;\n}\n.wizard > .steps .current a:active {\n  background: #5fbeaa;\n}\n.wizard > .steps .current a:active .number {\n  color: #ffffff;\n}\n.wizard > .steps .current a .number {\n  color: #ffffff;\n}\n.wizard > .steps .done a {\n  background: #7a8c9a;\n}\n.wizard > .steps .done a:hover {\n  background: #7a8c9a;\n}\n.wizard > .steps .done a:active {\n  background: #7a8c9a;\n}\n.wizard > .steps a,\n.wizard > .steps a:hover,\n.wizard > .steps a:active,\n.wizard > .content {\n  border-radius: 2px;\n}\n.wizard > .actions a {\n  background: #5fbeaa;\n  border-radius: 2px;\n  color: #ffffff;\n}\n.wizard > .actions a:hover {\n  background: #5fbeaa;\n  border-radius: 2px;\n  color: #ffffff;\n}\n.wizard > .actions a:active {\n  background: #5fbeaa;\n  border-radius: 2px;\n  color: #ffffff;\n}\n.wizard > .actions .disabled a {\n  background: #ffffff;\n  color: #333333;\n  cursor: default;\n  border: 1px solid #eaeaea;\n}\n.wizard > .actions .disabled a:hover {\n  background: #f9f9f9;\n  color: #333333;\n  cursor: default;\n  border: 1px solid #eaeaea;\n}\n.wizard > .actions .disabled a:active {\n  background: #f9f9f9;\n  color: #333333;\n  cursor: default;\n  border: 1px solid #eaeaea;\n}\n/* Dropzone */\n.dropzone {\n  min-height: 230px;\n  border: 2px dashed rgba(0, 0, 0, 0.3);\n  background: white;\n  border-radius: 6px;\n}\n.dropzone .dz-message {\n  font-size: 30px;\n}\n/* X-Editable */\n.editable-click,\na.editable-click,\na.editable-click:hover {\n  border: none;\n}\n/* Image crop */\n.img-container,\n.img-preview {\n  background-color: #f7f7f7;\n  overflow: hidden;\n  width: 100%;\n  text-align: center;\n}\n.img-container {\n  min-height: 200px;\n  max-height: 466px;\n  margin-bottom: 20px;\n}\n@media (min-width: 768px) {\n  .img-container {\n    min-height: 466px;\n  }\n}\n.img-container > img {\n  max-width: 100%;\n}\n.docs-preview {\n  margin-right: -15px;\n  margin-bottom: 10px;\n}\n.img-preview {\n  float: left;\n  margin-right: 10px;\n  margin-bottom: 10px;\n}\n.img-preview > img {\n  max-width: 100%;\n}\n/* Sweet Alert */\n.sweet-alert p {\n  font-size: 14px;\n  font-weight: 400;\n  line-height: 22px;\n}\nbutton.confirm {\n  background-color: #5fbeaa !important;\n  box-shadow: none !important;\n}\n"
  },
  {
    "path": "static/assets/css/core.css",
    "content": "/*@import url(https://fonts.gmirror.org/css?family=Noto+Sans:400,700);\n@import url(https://fonts.gmirror.org/css?family=Source+Sans+Pro:400,600,700,300);*/\n/*\nTemplate Name: UBold Dashboard\nAuthor: CoderThemes\nEmail: coderthemes@gmail.com\nFile: Common\n*/\nbody {\n  background: #ebeff2;\n  font-family: 'Noto Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;\n  margin: 0;\n  overflow-x: hidden;\n  color: #797979;\n}\nhtml {\n  position: relative;\n  min-height: 100%;\n  background: #ebeff2;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n  color: #505458;\n  font-family: \"Source Sans Pro\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  margin: 10px 0;\n}\nh1 {\n  line-height: 43px;\n}\nh2 {\n  line-height: 35px;\n}\nh3 {\n  line-height: 30px;\n}\nh3 small {\n  color: #444444;\n}\nh4 {\n  line-height: 22px;\n}\nh4 small {\n  color: #444444;\n}\nh5 {\n  font-size: 15px;\n}\nh5 small {\n  color: #444444;\n}\np {\n  line-height: 1.6;\n}\n* {\n  outline: none !important;\n}\nb {\n  font-weight: 600;\n}\na:hover {\n  outline: 0;\n  text-decoration: none;\n}\na:active {\n  outline: 0;\n  text-decoration: none;\n}\na:focus {\n  outline: 0;\n  text-decoration: none;\n}\n.container {\n  width: auto;\n}\n.container-alt {\n  margin-left: auto;\n  margin-right: auto;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n/* Footer */\n.footer {\n  border-top: 1px solid rgba(0, 0, 0, 0.1);\n  bottom: 0px;\n  color: #58666e;\n  text-align: left !important;\n  padding: 20px 30px;\n  position: absolute;\n  right: 0px;\n  left: 240px;\n}\n#wrapper {\n  height: 100%;\n  overflow: hidden;\n  width: 100%;\n}\n.page {\n  bottom: 0;\n  left: 0;\n  right: 0;\n  top: 0;\n}\n/* Page titles */\n.page-title {\n  font-size: 20px;\n  font-weight: 600;\n  margin-bottom: 0px;\n  margin-top: 7px;\n}\n.page-title-alt {\n  margin-bottom: 23px;\n  margin-top: 10px;\n}\n.page-header {\n  border-bottom: 1px solid #DBDDDE;\n}\n.header-title {\n  text-transform: uppercase;\n  font-size: 16px;\n  font-weight: 600;\n  letter-spacing: 0.04em;\n  line-height: 16px;\n  margin-bottom: 8px;\n}\n.social-links li a {\n  -webkit-border-radius: 50%;\n  background: #EFF0F4;\n  border-radius: 50%;\n  color: #7A7676;\n  display: inline-block;\n  height: 30px;\n  line-height: 30px;\n  text-align: center;\n  width: 30px;\n}\n/*\nFile: Helper clasess\n*/\n.p-0 {\n  padding: 0px !important;\n}\n.p-20 {\n  padding: 20px !important;\n}\n.p-30 {\n  padding: 30px !important;\n}\n.p-l-0 {\n  padding-left: 0px !important;\n}\n.p-r-0 {\n  padding-right: 0px !important;\n}\n.p-t-0 {\n  padding-top: 0px !important;\n}\n.p-t-10 {\n  padding-top: 10px !important;\n}\n.p-b-10 {\n  padding-bottom: 10px !important;\n}\n.p-l-r-10 {\n  padding-left: 10px;\n  padding-right: 10px;\n}\n.m-0 {\n  margin: 0px !important;\n}\n.m-r-5 {\n  margin-right: 5px !important;\n}\n.m-r-10 {\n  margin-right: 10px !important;\n}\n.m-r-15 {\n  margin-right: 15px !important;\n}\n.m-l-5 {\n  margin-left: 5px !important;\n}\n.m-l-10 {\n  margin-left: 10px !important;\n}\n.m-l-15 {\n  margin-left: 15px !important;\n}\n.m-t-5 {\n  margin-top: 5px !important;\n}\n.m-t-0 {\n  margin-top: 0px !important;\n}\n.m-t-10 {\n  margin-top: 10px !important;\n}\n.m-t-15 {\n  margin-top: 15px !important;\n}\n.m-t-20 {\n  margin-top: 20px !important;\n}\n.m-t-30 {\n  margin-top: 30px !important;\n}\n.m-t-40 {\n  margin-top: 40px !important;\n}\n.m-b-0 {\n  margin-bottom: 0px !important;\n}\n.m-b-5 {\n  margin-bottom: 5px !important;\n}\n.m-b-10 {\n  margin-bottom: 10px !important;\n}\n.m-b-15 {\n  margin-bottom: 15px !important;\n}\n.m-b-20 {\n  margin-bottom: 20px !important;\n}\n.m-b-30 {\n  margin-bottom: 30px !important;\n}\n.w-xs {\n  min-width: 80px;\n}\n.w-sm {\n  min-width: 95px;\n}\n.w-md {\n  min-width: 110px;\n}\n.w-lg {\n  min-width: 140px;\n}\n.m-h-40 {\n  min-height: 40px;\n}\n.m-h-50 {\n  min-height: 50px;\n}\n.l-h-34 {\n  line-height: 34px;\n}\n.font-600 {\n  font-weight: 600;\n}\n.font-bold {\n  font-weight: 700;\n}\n.font-normal {\n  font-weight: normal;\n}\n.font-light {\n  font-weight: 300;\n}\n.font-13 {\n  font-size: 13px !important;\n}\n.wrapper-md {\n  padding: 20px;\n}\n.pull-in {\n  margin-left: -15px;\n  margin-right: -15px;\n}\n.b-0 {\n  border: none !important;\n}\n.vertical-middle {\n  vertical-align: middle;\n}\n.bx-shadow {\n  -moz-box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);\n  -webkit-box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);\n  box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);\n}\n.mx-box {\n  max-height: 380px;\n  min-height: 380px;\n}\n.thumb-sm {\n  height: 32px;\n  width: 32px;\n}\n.thumb-md {\n  height: 48px;\n  width: 48px;\n}\n.thumb-lg {\n  height: 88px;\n  width: 88px;\n}\n/* Table type box */\n.table-box {\n  display: table;\n  height: 100%;\n  width: 100%;\n}\n.table-box .table-detail {\n  display: table-cell;\n  vertical-align: middle;\n}\n/* Card Box */\n.card-box {\n  padding: 20px;\n  border: 1px solid rgba(54, 64, 74, 0.05);\n  -webkit-border-radius: 5px;\n  border-radius: 5px;\n  -moz-border-radius: 5px;\n  background-clip: padding-box;\n  margin-bottom: 20px;\n  background-color: #ffffff;\n}\n.grid-structure .grid-container {\n  background-color: #f4f8fb;\n  margin-bottom: 10px;\n  padding: 10px 20px;\n}\n.icon-list-demo div {\n  cursor: pointer;\n  line-height: 45px;\n  white-space: nowrap;\n  color: #75798B;\n}\n.icon-list-demo div:hover {\n  color: #ffffff;\n}\n.icon-list-demo div p {\n  margin-bottom: 0px;\n}\n.icon-list-demo i {\n  -webkit-transition: all 0.2s;\n  -webkit-transition: font-size 0.2s;\n  display: inline-block;\n  font-size: 18px;\n  margin: 0;\n  text-align: center;\n  transition: all 0.2s;\n  transition: font-size 0.2s;\n  vertical-align: middle;\n  width: 40px;\n}\n.icon-list-demo .col-md-4 {\n  -webkit-border-radius: 3px;\n  border-radius: 3px;\n  -moz-border-radius: 3px;\n  background-clip: padding-box;\n}\n.icon-list-demo .col-md-4:hover {\n  background-color: #5fbeaa;\n}\n.icon-list-demo .col-md-4:hover i {\n  -o-transform: scale(2);\n  -webkit-transform: scale(2);\n  moz-transform: scale(2);\n  transform: scale(2);\n}\n.button-list {\n  margin-left: -8px;\n  margin-bottom: -12px;\n}\n.button-list .btn {\n  margin-bottom: 12px;\n  margin-left: 8px;\n}\n/*\nFile: Bootstrap-custom\n*/\n.row {\n  margin-right: -10px;\n  margin-left: -10px;\n}\n.col-lg-1,\n.col-lg-10,\n.col-lg-11,\n.col-lg-12,\n.col-lg-2,\n.col-lg-3,\n.col-lg-4,\n.col-lg-5,\n.col-lg-6,\n.col-lg-7,\n.col-lg-8,\n.col-lg-9,\n.col-md-1,\n.col-md-10,\n.col-md-11,\n.col-md-12,\n.col-md-2,\n.col-md-3,\n.col-md-4,\n.col-md-5,\n.col-md-6,\n.col-md-7,\n.col-md-8,\n.col-md-9,\n.col-sm-1,\n.col-sm-10,\n.col-sm-11,\n.col-sm-12,\n.col-sm-2,\n.col-sm-3,\n.col-sm-4,\n.col-sm-5,\n.col-sm-6,\n.col-sm-7,\n.col-sm-8,\n.col-sm-9,\n.col-xs-1,\n.col-xs-10,\n.col-xs-11,\n.col-xs-12,\n.col-xs-2,\n.col-xs-3,\n.col-xs-4,\n.col-xs-5,\n.col-xs-6,\n.col-xs-7,\n.col-xs-8,\n.col-xs-9 {\n  padding-left: 10px;\n  padding-right: 10px;\n}\n.breadcrumb {\n  background-color: transparent;\n  margin-bottom: 15px;\n  padding-top: 10px;\n  padding-left: 0px;\n}\n/* Dropdown */\n.dropdown-menu {\n  padding: 4px 0;\n  transition: all 300ms ease;\n  -moz-transition: all 300ms ease;\n  -webkit-transition: all 300ms ease;\n  -o-transition: all 300ms ease;\n  -ms-transition: all 300ms ease;\n  border: 0;\n  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);\n}\n.dropdown-menu > li > a {\n  padding: 6px 20px;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  background-color: #f3f3f3;\n  color: #36404a;\n}\n.dropup .dropdown-menu {\n  box-shadow: 0px -1px 5px 0 rgba(0, 0, 0, 0.26);\n}\n/* Background colors */\n.bg-custom {\n  background-color: #5fbeaa !important;\n}\n.bg-primary {\n  background-color: #5d9cec !important;\n}\n.bg-success {\n  background-color: #81c868 !important;\n}\n.bg-info {\n  background-color: #34d3eb !important;\n}\n.bg-warning {\n  background-color: #ffbd4a !important;\n}\n.bg-danger {\n  background-color: #f05050 !important;\n}\n.bg-muted {\n  background-color: #f4f8fb !important;\n}\n.bg-inverse {\n  background-color: #4c5667 !important;\n}\n.bg-purple {\n  background-color: #7266ba !important;\n}\n.bg-pink {\n  background-color: #fb6d9d !important;\n}\n.bg-white {\n  background-color: #ffffff !important;\n}\n.bg-lightdark {\n  background-color: #f4f8fb !important;\n}\n/* Text colors */\n.text-custom {\n  color: #5fbeaa;\n}\n.text-white {\n  color: #ffffff;\n}\n.text-danger {\n  color: #f05050;\n}\n.text-muted {\n  color: #98a6ad;\n}\n.text-primary {\n  color: #5d9cec;\n}\n.text-warning {\n  color: #ffbd4a;\n}\n.text-success {\n  color: #81c868;\n}\n.text-info {\n  color: #34d3eb;\n}\n.text-inverse {\n  color: #4c5667;\n}\n.text-pink {\n  color: #fb6d9d;\n}\n.text-purple {\n  color: #7266ba;\n}\n.text-dark {\n  color: #797979 !important;\n}\n/* Form components */\ntextarea.form-control {\n  min-height: 90px;\n}\n.form-control {\n  background-color: #FFFFFF;\n  border: 1px solid #E3E3E3;\n  border-radius: 4px;\n  color: #565656;\n  padding: 7px 12px;\n  height: 38px;\n  max-width: 100%;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n  -webkit-transition: all 300ms linear;\n  -moz-transition: all 300ms linear;\n  -o-transition: all 300ms linear;\n  -ms-transition: all 300ms linear;\n  transition: all 300ms linear;\n}\n.form-control:focus {\n  background-color: #FFFFFF;\n  border: 1px solid #AAAAAA;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n  outline: 0 !important;\n  color: #333333;\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}\n.input-sm {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.form-horizontal .form-group {\n  margin-left: -10px;\n  margin-right: -10px;\n}\n.form-control-feedback {\n  line-height: 38px !important;\n}\n.input-group-btn .btn {\n  padding: 8px 12px;\n}\n.input-group-btn .btn-sm {\n  padding: 5px 10px;\n}\n.input-group-btn .btn-lg {\n  padding: 10px 17px;\n}\n/* Labels */\n.label {\n  font-weight: 600;\n  letter-spacing: 0.05em;\n  padding: .3em .6em .3em;\n}\n.label-default {\n  background-color: #5fbeaa;\n}\n.label-primary {\n  background-color: #5d9cec;\n}\n.label-success {\n  background-color: #81c868;\n}\n.label-info {\n  background-color: #34d3eb;\n}\n.label-warning {\n  background-color: #ffbd4a;\n}\n.label-danger {\n  background-color: #f05050;\n}\n.label-purple {\n  background-color: #7266ba;\n}\n.label-pink {\n  background-color: #fb6d9d;\n}\n.label-inverse {\n  background-color: #4c5667;\n}\n/* Badge */\n.badge {\n  text-transform: uppercase;\n  font-weight: 600;\n  padding: 3px 5px;\n  font-size: 12px;\n  margin-top: 1px;\n  background-color: #5fbeaa;\n}\n.badge-xs {\n  font-size: 9px;\n}\n.badge-xs,\n.badge-sm {\n  -webkit-transform: translate(0, -2px);\n  -ms-transform: translate(0, -2px);\n  -o-transform: translate(0, -2px);\n  transform: translate(0, -2px);\n}\n.badge-primary {\n  background-color: #5d9cec;\n}\n.badge-success {\n  background-color: #81c868;\n}\n.badge-info {\n  background-color: #34d3eb;\n}\n.badge-warning {\n  background-color: #ffbd4a;\n}\n.badge-danger {\n  background-color: #f05050;\n}\n.badge-purple {\n  background-color: #7266ba;\n}\n.badge-pink {\n  background-color: #fb6d9d;\n}\n.badge-inverse {\n  background-color: #4c5667;\n}\n/* Pagination/ Pager */\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-bottom-right-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.pagination > li > a,\n.pagination > li > span {\n  color: #636e7b;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n  background-color: #e4e7ea;\n}\n.pagination-split li {\n  margin-left: 5px;\n  display: inline-block;\n  float: left;\n}\n.pagination-split li:first-child {\n  margin-left: 0;\n}\n.pagination-split li a {\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n  border-radius: 3px;\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  background-color: #5fbeaa;\n  border-color: #5fbeaa;\n}\n.pager li > a,\n.pager li > span {\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n  border-radius: 3px;\n  color: #636e7b;\n}\n/* Tabs */\n.tabs {\n  background-color: #ffffff;\n  margin: 0 auto;\n  padding: 0px;\n  position: relative;\n  white-space: nowrap;\n  width: 100%;\n}\n.tabs li.tab {\n  background-color: #ffffff;\n  display: block;\n  float: left;\n  margin: 0;\n  text-align: center;\n}\n.tabs li.tab a {\n  -moz-transition: color 0.28s ease;\n  -ms-transition: color 0.28s ease;\n  -o-transition: color 0.28s ease;\n  -webkit-transition: color 0.28s ease;\n  color: #9398a0;\n  color: #ee6e73;\n  display: block;\n  height: 100%;\n  text-decoration: none;\n  transition: color 0.28s ease;\n  width: 100%;\n}\n.tabs li.tab a.active {\n  color: #5fbeaa !important;\n}\n.tabs .indicator {\n  background-color: #5fbeaa;\n  bottom: 0;\n  height: 2px;\n  position: absolute;\n  will-change: left, right;\n}\n.tabs-top .indicator {\n  top: 0;\n}\n.nav-pills li a {\n  line-height: 36px !important;\n}\n.nav-pills li.active a {\n  background-color: #5fbeaa !important;\n}\n.nav-pills li.active a:hover {\n  background-color: #5fbeaa !important;\n}\n.nav-pills li.active a:focus {\n  background-color: #5fbeaa !important;\n}\n.nav.nav-tabs + .tab-content {\n  background: #ffffff;\n  margin-bottom: 30px;\n  padding: 30px;\n}\n.tabs-vertical-env {\n  margin-bottom: 30px;\n}\n.tabs-vertical-env .tab-content {\n  background: #ffffff;\n  display: table-cell;\n  margin-bottom: 30px;\n  padding: 30px;\n  vertical-align: top;\n}\n.tabs-vertical-env .nav.tabs-vertical {\n  display: table-cell;\n  min-width: 120px;\n  vertical-align: top;\n  width: 150px;\n}\n.tabs-vertical-env .nav.tabs-vertical li.active > a {\n  background-color: #ffffff;\n  border: 0;\n}\n.tabs-vertical-env .nav.tabs-vertical li > a {\n  color: #333333;\n  text-align: center;\n  white-space: nowrap;\n}\n.nav.nav-tabs > li.active > a {\n  background-color: #ffffff;\n  border: 0;\n}\n.nav.nav-tabs > li > a,\n.nav.tabs-vertical > li > a {\n  background-color: transparent;\n  border-radius: 0;\n  border: none;\n  color: #505461 !important;\n  cursor: pointer;\n  line-height: 50px;\n  padding-left: 20px;\n  padding-right: 20px;\n  letter-spacing: 0.03em;\n  font-weight: 600;\n  text-transform: uppercase;\n  font-family: \"Source Sans Pro\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\n.nav.nav-tabs > li > a:hover,\n.nav.tabs-vertical > li > a:hover {\n  color: #5fbeaa !important;\n}\n.tab-content {\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  color: #777777;\n}\n.nav.nav-tabs > li:last-of-type a {\n  margin-right: 0px;\n}\n.nav.nav-tabs {\n  border-bottom: 0;\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.navtab-bg {\n  background-color: #f4f8fb;\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.tabs-vertical-env .nav.tabs-vertical li.active > a {\n  border: none;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:focus,\n.nav-tabs > li.active > a:hover,\n.tabs-vertical > li.active > a,\n.tabs-vertical > li.active > a:focus,\n.tabs-vertical > li.active > a:hover {\n  color: #5fbeaa !important;\n}\n/* List group */\n.list-group-item {\n  border: 1px solid #ebeff2;\n}\n/* Dropcap */\n.dropcap {\n  font-size: 3.1em;\n}\n.dropcap,\n.dropcap-circle,\n.dropcap-square {\n  display: block;\n  float: left;\n  font-weight: 400;\n  line-height: 36px;\n  margin-right: 6px;\n  text-shadow: none;\n}\n/* Alert */\n.alert .btn {\n  margin-top: 10px;\n}\n.alert-success {\n  background-color: rgba(95, 190, 170, 0.3);\n  border-color: rgba(95, 190, 170, 0.4);\n  color: #5fbeaa;\n}\n.alert-info {\n  background-color: rgba(52, 211, 235, 0.2);\n  border-color: rgba(52, 211, 235, 0.3);\n  color: #34d3eb;\n}\n.alert-warning {\n  background-color: rgba(255, 189, 74, 0.2);\n  border-color: rgba(255, 189, 74, 0.3);\n  color: #ffbd4a;\n}\n.alert-danger {\n  background-color: rgba(240, 80, 80, 0.2);\n  border-color: rgba(240, 80, 80, 0.3);\n  color: #f05050;\n}\n/* Modals */\n.modal .modal-dialog .modal-content {\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n  border-color: #DDDDDD;\n  border-radius: 2px;\n  box-shadow: none;\n  padding: 25px;\n}\n.modal .modal-dialog .modal-content .modal-header {\n  border-bottom-width: 2px;\n  margin: 0;\n  padding: 0;\n  padding-bottom: 15px;\n}\n.modal .modal-dialog .modal-content .modal-body {\n  padding: 20px 0;\n}\n.modal .modal-dialog .modal-content .modal-footer {\n  padding: 0;\n  padding-top: 15px;\n}\n.modal-full {\n  width: 98%;\n}\n.modal-content .nav.nav-tabs + .tab-content {\n  margin-bottom: 0px;\n}\n.modal-content .panel-group {\n  margin-bottom: 0px;\n}\n.modal-content .panel {\n  border-top: none;\n}\n/* Custom-modal */\n.modal-demo {\n  background-color: #FFF;\n  width: 600px;\n  -webkit-border-radius: 4px;\n  border-radius: 4px;\n  -moz-border-radius: 4px;\n  background-clip: padding-box;\n  display: none;\n}\n.modal-demo .close {\n  position: absolute;\n  top: 15px;\n  right: 25px;\n  color: #eeeeee;\n}\n.custom-modal-title {\n  padding: 15px 25px 15px 25px;\n  line-height: 22px;\n  font-size: 18px;\n  background-color: #36404a;\n  color: #ffffff;\n  text-align: left;\n  margin: 0px;\n}\n.custom-modal-text {\n  padding: 20px;\n}\n.custombox-modal-flash .close,\n.custombox-modal-rotatedown .close {\n  top: 20px;\n  z-index: 9999;\n}\n/* Tabs-Accordions */\n.tabs-vertical-env .tab-content {\n  margin-bottom: 0px;\n}\n.table > thead > tr > td.middle-align,\n.table > tbody > tr > td.middle-align,\n.table > .tfood > tr > td.middle-align,\n.table > thead > tr > th.middle-align,\n.table > tbody > tr > th.middle-align,\n.table > .tfood > tr > th.middle-align {\n  vertical-align: middle;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  background-color: #5fbeaa;\n  border-color: #5fbeaa;\n}\n.nav-pills > .active > a > .badge {\n  color: #5fbeaa;\n}\n.has-success .form-control {\n  border-color: #81c868;\n  box-shadow: none !important;\n}\n.has-warning .form-control {\n  border-color: #ffbd4a;\n  box-shadow: none !important;\n}\n.has-error .form-control {\n  border-color: #f05050;\n  box-shadow: none !important;\n}\n.input-group-addon {\n  border-radius: 2px;\n  border: 1px solid #eeeeee;\n}\n/* Tooltips */\n.tooltip-inner {\n  border-radius: 1px;\n  padding: 6px 10px;\n}\n.jqstooltip {\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  width: auto!important;\n  height: auto!important;\n}\n/* Popover */\n.popover {\n  font-family: inherit;\n  border: none;\n  -webkit-border-radius: 3px;\n  border-radius: 3px;\n  -moz-border-radius: 3px;\n  background-clip: padding-box;\n}\n.popover .popover-title {\n  background-color: transparent;\n  color: #5fbeaa;\n  font-weight: 600;\n}\n/* Code */\ncode {\n  color: #5d9cec;\n  background-color: #f4f8fb;\n  border-radius: 4px;\n}\n/* Pre */\npre {\n  background-color: #f4f8fb;\n  border: 1px solid #d4d8da;\n}\n/* Carousel */\n.carousel-control {\n  width: 10%;\n}\n.carousel-control span {\n  position: absolute;\n  top: 50%;\n  /* pushes the icon in the middle of the height */\n  z-index: 5;\n  display: inline-block;\n  font-size: 30px;\n}\n/* Owl */\n.slider-bg {\n  background-size: cover !important;\n  padding: 5.5% 4.5%;\n}\n/* Media */\n.media {\n  margin-bottom: 20px;\n}\n.media .media-heading {\n  font-weight: 600;\n  font-size: 16px;\n}\n.media:last-of-type {\n  margin-bottom: 0px;\n}\n/*===================================\nFile: Topbar,Left-sidebar,Right-sidebar\n  ===================================*/\n.topbar {\n  left: 0px;\n  position: fixed;\n  right: 0;\n  top: 0px;\n  z-index: 999;\n}\n.topbar .topbar-left {\n  float: left;\n  position: relative;\n  width: 240px;\n  z-index: 1;\n}\n.topbar .topbar-left-sm {\n  width: 180px;\n}\n.logo {\n  color: #ffffff !important;\n  font-size: 20px;\n  font-weight: 700;\n  letter-spacing: .05em;\n  line-height: 60px;\n  text-transform: uppercase;\n}\n.logo h1 {\n  height: 50px;\n  margin: 0px auto;\n  text-align: center;\n}\n.logo i {\n  color: #5fbeaa;\n}\n.logo .icon-c-logo {\n  display: none;\n}\n.navbar-default {\n  background-color: #36404a;\n  border-radius: 0px;\n  border: none;\n  margin-bottom: 0px;\n}\n.navbar-default .navbar-nav > .open > a {\n  background-color: rgba(255, 255, 255, 0.1);\n}\n.navbar-default .navbar-nav > .open > a:focus {\n  background-color: rgba(255, 255, 255, 0.1);\n}\n.navbar-default .navbar-nav > .open > a:hover {\n  background-color: rgba(255, 255, 255, 0.1);\n}\n.navbar-default .badge {\n  position: absolute;\n  top: 12px;\n  right: 7px;\n}\n.nav > li > a {\n  color: #ffffff !important;\n  line-height: 60px;\n  padding: 0px 15px;\n  position: relative;\n}\n.nav > li > a i {\n  font-size: 16px;\n}\n.profile img {\n  border: 2px solid #edf0f0;\n  height: 36px;\n  width: 36px;\n}\n.dropdown-menu-lg {\n  width: 300px;\n}\n.dropdown-menu-lg .list-group {\n  margin-bottom: 0px;\n}\n.dropdown-menu-lg .list-group-item {\n  border: none;\n  padding: 10px 20px;\n}\n.dropdown-menu-lg .media-heading {\n  margin-bottom: 0px;\n}\n.dropdown-menu-lg .media-body p {\n  color: #828282;\n}\n.notification-list {\n  max-height: 230px;\n}\n.notification-list em {\n  width: 34px;\n  text-align: center;\n}\n.notification-list .media-body {\n  display: inherit;\n  width: auto;\n  overflow: hidden;\n  margin-left: 50px;\n}\n.notification-list .media-body h5 {\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  display: block;\n  width: 100%;\n  font-weight: normal;\n  overflow: hidden;\n}\n.notifi-title {\n  border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n  font-size: 15px;\n  text-transform: uppercase;\n  font-weight: 600;\n  padding: 11px 20px 15px;\n  color: #4c5667;\n  font-family: \"Source Sans Pro\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\n.navbar-nav {\n  margin: 0px;\n}\n.side-menu {\n  bottom: 0;\n  top: 0;\n  width: 240px;\n  z-index: 2;\n}\n.side-menu.left {\n  background: #ffffff;\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n  position: absolute;\n  top: 60px;\n}\nbody.fixed-left .side-menu.left {\n  bottom: 50px;\n  height: 100%;\n  margin-bottom: -70px;\n  margin-top: 0px;\n  padding-bottom: 70px;\n  position: fixed;\n}\n.content-page {\n  margin-left: 240px;\n  overflow: hidden;\n}\n.content-page > .content {\n  margin-bottom: 60px;\n  margin-top: 60px;\n  padding: 20px 5px 15px 5px;\n}\n.button-menu-mobile {\n  background: transparent;\n  border: none;\n  color: #cccccc;\n  font-size: 21px;\n  line-height: 60px;\n  padding: 0px 15px;\n}\n.button-menu-mobile:hover {\n  color: #ffffff;\n}\n.sidebar-inner {\n  height: 100%;\n}\n#sidebar-menu,\n#sidebar-menu ul,\n#sidebar-menu li,\n#sidebar-menu a {\n  border: 0;\n  font-weight: normal;\n  line-height: 1;\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  position: relative;\n  text-decoration: none;\n}\n#sidebar-menu {\n  padding-bottom: 30px;\n  padding-top: 30px;\n  width: 100%;\n}\n#sidebar-menu .nav > li > a .badge {\n  position: absolute;\n  right: 10px;\n  top: 12px;\n}\n#sidebar-menu a {\n  line-height: 1.3;\n}\n#sidebar-menu ul ul {\n  display: none;\n}\n#sidebar-menu ul ul li {\n  border-top: 0;\n}\n#sidebar-menu ul ul li.active a {\n  color: #5fbeaa;\n}\n#sidebar-menu ul ul a {\n  color: #75798B;\n  display: block;\n  padding: 10px 20px 10px 65px;\n}\n#sidebar-menu ul ul a:hover {\n  color: #5fbeaa;\n}\n#sidebar-menu ul ul a i {\n  margin-right: 5px;\n}\n#sidebar-menu ul ul ul a {\n  padding-left: 80px;\n}\n#sidebar-menu .label {\n  margin-top: 2px;\n}\n#sidebar-menu .subdrop {\n  background: #f4f8fb !important;\n  border-left: 3px solid #5fbeaa;\n  color: #5fbeaa !important;\n}\n#sidebar-menu > ul > li > a {\n  color: #36404a;\n  display: block;\n  padding: 12px 20px;\n  margin: 4px 0px;\n  border-left: 3px solid #ffffff;\n}\n#sidebar-menu > ul > li > a:hover {\n  color: #5fbeaa;\n  text-decoration: none;\n}\n#sidebar-menu > ul > li > a > span {\n  vertical-align: middle;\n}\n#sidebar-menu ul li a i {\n  display: inline-block;\n  font-size: 16px;\n  line-height: 17px;\n  margin-left: 3px;\n  margin-right: 15px;\n  text-align: center;\n  vertical-align: middle;\n  width: 20px;\n}\n#sidebar-menu ul li a i.md {\n  font-size: 18px;\n}\n#sidebar-menu > ul > li > a > i.i-right {\n  float: right;\n  margin: 3px 0 0 0;\n}\n#sidebar-menu > ul > li > a.active {\n  background: #f4f8fb !important;\n  border-left: 3px solid #5fbeaa;\n  color: #5fbeaa !important;\n}\n.menu-title {\n  padding: 12px 20px !important;\n  letter-spacing: .035em;\n  pointer-events: none;\n  cursor: default;\n  font-size: 13px;\n}\n/* Small Menu */\n.side-menu-sm {\n  width: 180px;\n  text-align: center;\n}\n.side-menu-sm #sidebar-menu > ul > li > a > i {\n  display: block;\n  font-size: 18px;\n  line-height: 24px;\n  width: 100%;\n  margin: 0px;\n}\n.side-menu-sm #sidebar-menu ul ul a {\n  padding: 10px 20px 10px 20px;\n}\n.side-menu-sm + .content-page .footer {\n  left: 180px;\n}\n#wrapper.enlarged .side-menu-sm {\n  text-align: left;\n}\n#wrapper.enlarged .side-menu-sm #sidebar-menu ul li a i {\n  display: inline-block;\n  font-size: 18px;\n  line-height: 17px;\n  margin-left: 3px;\n  margin-right: 15px;\n  vertical-align: middle;\n  width: 20px;\n}\n.side-menu-sm + .content-page {\n  margin-left: 180px;\n}\n/* Header 2 */\n.page-header-2 {\n  background: #E3E7EC;\n  border-bottom: 1px solid #dee2e8;\n  margin: -25px -20px 22px -20px;\n  padding: 25px 20px 0px 20px;\n}\n#wrapper.enlarged .menu-title {\n  display: none;\n}\n#wrapper.enlarged #sidebar-menu ul ul {\n  border: 2px solid #f4f8fb;\n  margin-top: -5px;\n  padding-top: 5px;\n  z-index: 9999;\n  background-color: #ffffff;\n}\n#wrapper.enlarged .left.side-menu {\n  width: 70px;\n  z-index: 5;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu > ul > li > a {\n  padding: 15px 20px;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu > ul > li > a:hover {\n  background: #f4f8fb!important;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu > ul > li > a:active {\n  background: #f4f8fb!important;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu > ul > li > a:focus {\n  background: #f4f8fb!important;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu > ul > li > a i {\n  margin-right: 20px !important;\n  font-size: 20px;\n}\n#wrapper.enlarged .left.side-menu .label {\n  position: absolute;\n  top: 5px;\n  left: 35px;\n  text-indent: 0;\n  display: block !important;\n  padding: .2em .6em .3em !important;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu ul > li {\n  position: relative;\n  white-space: nowrap;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu ul > li:hover > a {\n  position: relative;\n  width: 260px;\n  background: #f4f8fb;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu ul > li:hover > ul {\n  display: block;\n  left: 70px;\n  position: absolute;\n  width: 190px;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu ul > li:hover > ul a {\n  background: #ffffff;\n  box-shadow: none;\n  padding-left: 15px;\n  position: relative;\n  width: 186px;\n  z-index: 6;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu ul > li:hover > ul a:hover {\n  color: #5fbeaa;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu ul > li:hover a span {\n  display: inline;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu a.subdrop {\n  color: #5fbeaa !important;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu ul > li > ul {\n  display: none;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu ul ul li:hover > ul {\n  display: block;\n  left: 190px;\n  margin-top: -36px;\n  position: absolute;\n  width: 190px;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu ul ul li > a span.pull-right {\n  -ms-transform: rotate(270deg);\n  -webkit-transform: rotate(270deg);\n  position: absolute;\n  right: 20px;\n  top: 12px;\n  transform: rotate(270deg);\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu ul ul li.active a {\n  color: #5fbeaa;\n}\n#wrapper.enlarged .left.side-menu #sidebar-menu ul > li > a span {\n  display: none;\n  padding-left: 10px;\n}\n#wrapper.enlarged .left.side-menu .user-details {\n  display: none;\n}\n#wrapper.enlarged .content-page {\n  margin-left: 70px;\n}\n#wrapper.enlarged .footer {\n  left: 70px;\n}\n#wrapper.enlarged .topbar .topbar-left {\n  width: 70px !important;\n}\n#wrapper.enlarged .topbar .topbar-left .logo span {\n  display: none;\n  opacity: 0;\n}\n#wrapper.enlarged .topbar .topbar-left .logo .icon-c-logo {\n  display: block;\n  line-height: 60px;\n}\n#wrapper.enlarged #sidebar-menu > ul > li:hover > a.open :after {\n  display: none;\n}\n#wrapper.enlarged #sidebar-menu > ul > li:hover > a.active :after {\n  display: none;\n}\n#wrapper.enlarged .tips-box {\n  display: none;\n}\n.tips-box .portlet {\n  -webkit-box-shadow: 0px 0px 7px 1px rgba(0, 0, 0, 0.05);\n  -moz-box-shadow: 0px 0px 7px 1px rgba(0, 0, 0, 0.05);\n  box-shadow: 0px 0px 7px 1px rgba(0, 0, 0, 0.05);\n}\n.user-details {\n  padding: 20px;\n  padding-bottom: 0px;\n  position: relative;\n}\n.user-details img {\n  position: relative;\n  z-index: 9999;\n}\n.user-details .user-info {\n  color: #444444;\n  margin-left: 60px;\n  position: relative;\n  z-index: 99999;\n}\n.user-details .user-info a.dropdown-toggle {\n  color: #797979;\n  display: block;\n  font-family: 'Roboto', sans-serif;\n  font-size: 16px;\n  font-weight: 600;\n  padding-top: 5px;\n}\n#wrapper.right-bar-enabled .right-bar {\n  right: 0;\n}\n#wrapper.right-bar-enabled .left-layout {\n  left: 0;\n}\n/* Right sidebar */\n.side-bar.right-bar {\n  float: right !important;\n  right: -266px;\n  top: 60px;\n}\n.side-bar {\n  -moz-transition: all 200ms ease-out;\n  -webkit-transition: all 200ms ease-out;\n  background-color: #ffffff;\n  box-shadow: 0px 0px 8px 1px rgba(0, 0, 0, 0.1);\n  display: block;\n  float: left;\n  height: 100%;\n  overflow-y: auto;\n  position: fixed;\n  transition: all 200ms ease-out;\n  width: 240px;\n}\n.right-bar {\n  background: #ffffff !important;\n  z-index: 99 !important;\n}\n.right-bar h4 {\n  border-bottom: 1px solid #eeeeee;\n  padding-bottom: 10px;\n}\n.contact-list {\n  max-height: 600px;\n}\n.contact-list .list-group-item {\n  border: none;\n}\n.contact-list .list-group-item:hover {\n  background: #ebeff2;\n}\n.contact-list i.offline {\n  color: #f05050 !important;\n}\n.contact-list i.away {\n  color: #ffbd4a;\n}\n.contacts-list .avatar {\n  display: inline-block;\n  float: left;\n  margin-right: 5px;\n  width: 30px;\n}\n.contacts-list .avatar img {\n  border-radius: 50%;\n  width: 100%;\n}\n.contacts-list .list-group-item span.name {\n  color: #707780;\n  display: inline-block;\n  float: left;\n  overflow: hidden;\n  padding-left: 5px;\n  padding-top: 6px;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  width: 130px;\n}\n.contacts-list i {\n  color: #7a8c9a;\n  float: right;\n  font-size: 9px;\n  line-height: 30px;\n}\n.contacts-list i.online {\n  color: #a0d269;\n}\n.contacts-list i.offline {\n  color: #f05050 !important;\n}\n.contacts-list i.away {\n  color: #ffbd4a;\n}\n.app-search {\n  position: relative;\n  margin: 15px 0px 15px 10px;\n}\n.app-search a {\n  position: absolute;\n  top: 5px;\n  right: 20px;\n  color: #c4c4cd;\n}\n.app-search .form-control,\n.app-search .form-control:focus {\n  border: none;\n  font-size: 13px;\n  color: #ffffff;\n  padding-left: 20px;\n  padding-right: 40px;\n  background: rgba(255, 255, 255, 0.1);\n  box-shadow: none;\n  border-radius: 30px;\n  height: 30px;\n  font-weight: 600;\n  width: 180px;\n}\n/* Animation */\n/* Bounce 1 */\n@-webkit-keyframes cd-bounce-1 {\n  0% {\n    opacity: 0;\n    -webkit-transform: scale(0.5);\n  }\n  60% {\n    opacity: 1;\n    -webkit-transform: scale(1.2);\n  }\n  100% {\n    -webkit-transform: scale(1);\n  }\n}\n@-moz-keyframes cd-bounce-1 {\n  0% {\n    opacity: 0;\n    -moz-transform: scale(0.5);\n  }\n  60% {\n    opacity: 1;\n    -moz-transform: scale(1.2);\n  }\n  100% {\n    -moz-transform: scale(1);\n  }\n}\n@-o-keyframes cd-bounce-1 {\n  0% {\n    opacity: 0;\n    -o-transform: scale(0.5);\n  }\n  60% {\n    opacity: 1;\n    -o-transform: scale(1.2);\n  }\n  100% {\n    -o-transform: scale(1);\n  }\n}\n@keyframes cd-bounce-1 {\n  0% {\n    opacity: 0;\n    -webkit-transform: scale(0.5);\n    -moz-transform: scale(0.5);\n    -ms-transform: scale(0.5);\n    -o-transform: scale(0.5);\n    transform: scale(0.5);\n  }\n  60% {\n    opacity: 1;\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    transform: scale(1.2);\n  }\n  100% {\n    opacity: 1;\n    -webkit-transform: scale(1);\n    -moz-transform: scale(1);\n    -ms-transform: scale(1);\n    -o-transform: scale(1);\n    transform: scale(1);\n  }\n}\n/* Bounce 2 */\n@-webkit-keyframes cd-bounce-2 {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateX(-100px);\n  }\n  60% {\n    opacity: 1;\n    -webkit-transform: translateX(20px);\n  }\n  100% {\n    -webkit-transform: translateX(0);\n  }\n}\n@-moz-keyframes cd-bounce-2 {\n  0% {\n    opacity: 0;\n    -moz-transform: translateX(-100px);\n  }\n  60% {\n    opacity: 1;\n    -moz-transform: translateX(20px);\n  }\n  100% {\n    -moz-transform: translateX(0);\n  }\n}\n@-o-keyframes cd-bounce-2 {\n  0% {\n    opacity: 0;\n    -o-transform: translateX(-100px);\n  }\n  60% {\n    opacity: 1;\n    -o-transform: translateX(20px);\n  }\n  100% {\n    opacity: 1;\n    -o-transform: translateX(0);\n  }\n}\n@keyframes cd-bounce-2 {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateX(-100px);\n    -moz-transform: translateX(-100px);\n    -ms-transform: translateX(-100px);\n    -o-transform: translateX(-100px);\n    transform: translateX(-100px);\n  }\n  60% {\n    opacity: 1;\n    -webkit-transform: translateX(20px);\n    -moz-transform: translateX(20px);\n    -ms-transform: translateX(20px);\n    -o-transform: translateX(20px);\n    transform: translateX(20px);\n  }\n  100% {\n    opacity: 1;\n    -webkit-transform: translateX(0);\n    -moz-transform: translateX(0);\n    -ms-transform: translateX(0);\n    -o-transform: translateX(0);\n    transform: translateX(0);\n  }\n}\n/* Dropdown */\n@-webkit-keyframes dropdownOpen {\n  0% {\n    opacity: 0;\n    -webkit-transform: scale(0);\n  }\n  100% {\n    -webkit-transform: scale(1);\n  }\n}\n@-moz-keyframes dropdownOpen {\n  0% {\n    opacity: 0;\n    -moz-transform: scale(0);\n  }\n  100% {\n    -moz-transform: scale(1);\n  }\n}\n@-o-keyframes dropdownOpen {\n  0% {\n    opacity: 0;\n    -o-transform: scale(0);\n  }\n  100% {\n    -o-transform: scale(1);\n  }\n}\n@keyframes dropdownOpen {\n  0% {\n    opacity: 0;\n    -webkit-transform: scale(0);\n    -moz-transform: scale(0);\n    -ms-transform: scale(0);\n    -o-transform: scale(0);\n    transform: scale(0);\n  }\n  100% {\n    opacity: 1;\n    -webkit-transform: scale(1);\n    -moz-transform: scale(1);\n    -ms-transform: scale(1);\n    -o-transform: scale(1);\n    transform: scale(1);\n  }\n}\n/* Progressbar Animated */\n@-webkit-keyframes animationProgress {\n  from {\n    width: 0;\n  }\n}\n@keyframes animationProgress {\n  from {\n    width: 0;\n  }\n}\n/* Portlets loader */\n@-webkit-keyframes loaderAnimate {\n  0% {\n    -webkit-transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(220deg);\n  }\n}\n@-moz-keyframes loaderAnimate {\n  0% {\n    -moz-transform: rotate(0deg);\n  }\n  100% {\n    -moz-transform: rotate(220deg);\n  }\n}\n@-o-keyframes loaderAnimate {\n  0% {\n    -o-transform: rotate(0deg);\n  }\n  100% {\n    -o-transform: rotate(220deg);\n  }\n}\n@keyframes loaderAnimate {\n  0% {\n    transform: rotate(0deg);\n  }\n  100% {\n    transform: rotate(220deg);\n  }\n}\n@-webkit-keyframes loaderAnimate2 {\n  0% {\n    box-shadow: inset #555 0 0 0 8px;\n    -webkit-transform: rotate(-140deg);\n  }\n  50% {\n    box-shadow: inset #555 0 0 0 2px;\n  }\n  100% {\n    box-shadow: inset #555 0 0 0 8px;\n    -webkit-transform: rotate(140deg);\n  }\n}\n@-moz-keyframes loaderAnimate2 {\n  0% {\n    box-shadow: inset #555 0 0 0 8px;\n    -moz-transform: rotate(-140deg);\n  }\n  50% {\n    box-shadow: inset #555 0 0 0 2px;\n  }\n  100% {\n    box-shadow: inset #555 0 0 0 8px;\n    -moz-transform: rotate(140deg);\n  }\n}\n@-o-keyframes loaderAnimate2 {\n  0% {\n    box-shadow: inset #555 0 0 0 8px;\n    -o-transform: rotate(-140deg);\n  }\n  50% {\n    box-shadow: inset #555 0 0 0 2px;\n  }\n  100% {\n    box-shadow: inset #555 0 0 0 8px;\n    -o-transform: rotate(140deg);\n  }\n}\n@keyframes loaderAnimate2 {\n  0% {\n    box-shadow: inset #555 0 0 0 8px;\n    -webkit-transform: rotate(-140deg);\n    -moz-transform: rotate(-140deg);\n    -ms-transform: rotate(-140deg);\n    transform: rotate(-140deg);\n  }\n  50% {\n    box-shadow: inset #555 0 0 0 2px;\n  }\n  100% {\n    box-shadow: inset #555 0 0 0 8px;\n    -webkit-transform: rotate(140deg);\n    -moz-transform: rotate(140deg);\n    -ms-transform: rotate(140deg);\n    transform: rotate(140deg);\n  }\n}\n@keyframes loaderAnimate2 {\n  0% {\n    box-shadow: inset #999 0 0 0 17px;\n    transform: rotate(-140deg);\n  }\n  50% {\n    box-shadow: inset #999 0 0 0 2px;\n  }\n  100% {\n    box-shadow: inset #999 0 0 0 17px;\n    transform: rotate(140deg);\n  }\n}\n/*!\n * Waves v0.6.0\n * http://fian.my.id/Waves\n *\n * Copyright 2014 Alfiana E. Sibuea and other contributors\n * Released under the MIT license\n * https://github.com/fians/Waves/blob/master/LICENSE\n */\n.waves-effect {\n  position: relative;\n  cursor: pointer;\n  display: inline-block;\n  overflow: hidden;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  -webkit-tap-highlight-color: transparent;\n  vertical-align: middle;\n  z-index: 1;\n  will-change: opacity, transform;\n  -webkit-transition: all 0.3s ease-out;\n  -moz-transition: all 0.3s ease-out;\n  -o-transition: all 0.3s ease-out;\n  -ms-transition: all 0.3s ease-out;\n  transition: all 0.3s ease-out;\n}\n.waves-effect .waves-ripple {\n  position: absolute;\n  border-radius: 50%;\n  width: 20px;\n  height: 20px;\n  margin-top: -10px;\n  margin-left: -10px;\n  opacity: 0;\n  background: rgba(0, 0, 0, 0.2);\n  -webkit-transition: all 0.7s ease-out;\n  -moz-transition: all 0.7s ease-out;\n  -o-transition: all 0.7s ease-out;\n  -ms-transition: all 0.7s ease-out;\n  transition: all 0.7s ease-out;\n  -webkit-transition-property: -webkit-transform, opacity;\n  -moz-transition-property: -moz-transform, opacity;\n  -o-transition-property: -o-transform, opacity;\n  transition-property: transform, opacity;\n  -webkit-transform: scale(0);\n  -moz-transform: scale(0);\n  -ms-transform: scale(0);\n  -o-transform: scale(0);\n  transform: scale(0);\n  pointer-events: none;\n}\n.waves-effect.waves-light .waves-ripple {\n  background-color: rgba(255, 255, 255, 0.45);\n}\n.waves-effect.waves-red .waves-ripple {\n  background-color: rgba(244, 67, 54, 0.7);\n}\n.waves-effect.waves-yellow .waves-ripple {\n  background-color: rgba(255, 235, 59, 0.7);\n}\n.waves-effect.waves-orange .waves-ripple {\n  background-color: rgba(255, 152, 0, 0.7);\n}\n.waves-effect.waves-purple .waves-ripple {\n  background-color: rgba(156, 39, 176, 0.7);\n}\n.waves-effect.waves-green .waves-ripple {\n  background-color: rgba(76, 175, 80, 0.7);\n}\n.waves-effect.waves-teal .waves-ripple {\n  background-color: rgba(0, 150, 136, 0.7);\n}\n.waves-notransition {\n  -webkit-transition: none !important;\n  -moz-transition: none !important;\n  -o-transition: none !important;\n  -ms-transition: none !important;\n  transition: none !important;\n}\n.waves-circle {\n  -webkit-transform: translateZ(0);\n  -moz-transform: translateZ(0);\n  -ms-transform: translateZ(0);\n  -o-transform: translateZ(0);\n  transform: translateZ(0);\n  -webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%);\n  text-align: center;\n  width: 2.5em;\n  height: 2.5em;\n  line-height: 2.5em;\n  border-radius: 50%;\n  -webkit-mask-image: none;\n}\n.waves-input-wrapper {\n  border-radius: 0.2em;\n  vertical-align: bottom;\n}\n.waves-input-wrapper .waves-button-input {\n  position: relative;\n  top: 0;\n  left: 0;\n  z-index: 1;\n}\n.waves-block {\n  display: block;\n}\n"
  },
  {
    "path": "static/assets/css/elements.css",
    "content": ""
  },
  {
    "path": "static/assets/css/icons.css",
    "content": "/*\nTemplate Name: UBold Dashboard\nAuthor: CoderThemes\nEmail: coderthemes@gmail.com\nFile: Icons\n*/\n/*!\n *  Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n/* FONT PATH\n * -------------------------- */\n@font-face {\n  font-family: 'FontAwesome';\n  src: url('../fonts/fontawesome-webfont.eot?v=4.4.0');\n  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.4.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.4.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.4.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.4.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n.fa {\n  display: inline-block;\n  font: normal normal normal 14px/1 FontAwesome;\n  font-size: inherit;\n  text-rendering: auto;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n/* makes the font 33% larger relative to the icon container */\n.fa-lg {\n  font-size: 1.33333333em;\n  line-height: 0.75em;\n  vertical-align: -15%;\n}\n.fa-2x {\n  font-size: 2em;\n}\n.fa-3x {\n  font-size: 3em;\n}\n.fa-4x {\n  font-size: 4em;\n}\n.fa-5x {\n  font-size: 5em;\n}\n.fa-fw {\n  width: 1.28571429em;\n  text-align: center;\n}\n.fa-ul {\n  padding-left: 0;\n  margin-left: 2.14285714em;\n  list-style-type: none;\n}\n.fa-ul > li {\n  position: relative;\n}\n.fa-li {\n  position: absolute;\n  left: -2.14285714em;\n  width: 2.14285714em;\n  top: 0.14285714em;\n  text-align: center;\n}\n.fa-li.fa-lg {\n  left: -1.85714286em;\n}\n.fa-border {\n  padding: .2em .25em .15em;\n  border: solid 0.08em #eeeeee;\n  border-radius: .1em;\n}\n.fa-pull-left {\n  float: left;\n}\n.fa-pull-right {\n  float: right;\n}\n.fa.fa-pull-left {\n  margin-right: .3em;\n}\n.fa.fa-pull-right {\n  margin-left: .3em;\n}\n/* Deprecated as of 4.4.0 */\n.pull-right {\n  float: right;\n}\n.pull-left {\n  float: left;\n}\n.fa.pull-left {\n  margin-right: .3em;\n}\n.fa.pull-right {\n  margin-left: .3em;\n}\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n  animation: fa-spin 2s infinite linear;\n}\n.fa-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n  animation: fa-spin 1s infinite steps(8);\n}\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n.fa-rotate-90 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n  -webkit-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n.fa-rotate-180 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n  -webkit-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n.fa-rotate-270 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n  -webkit-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n.fa-flip-horizontal {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);\n  -webkit-transform: scale(-1, 1);\n  -ms-transform: scale(-1, 1);\n  transform: scale(-1, 1);\n}\n.fa-flip-vertical {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n  -webkit-transform: scale(1, -1);\n  -ms-transform: scale(1, -1);\n  transform: scale(1, -1);\n}\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical {\n  filter: none;\n}\n.fa-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n.fa-stack-1x,\n.fa-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n.fa-stack-1x {\n  line-height: inherit;\n}\n.fa-stack-2x {\n  font-size: 2em;\n}\n.fa-inverse {\n  color: #ffffff;\n}\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n.fa-glass:before {\n  content: \"\\f000\";\n}\n.fa-music:before {\n  content: \"\\f001\";\n}\n.fa-search:before {\n  content: \"\\f002\";\n}\n.fa-envelope-o:before {\n  content: \"\\f003\";\n}\n.fa-heart:before {\n  content: \"\\f004\";\n}\n.fa-star:before {\n  content: \"\\f005\";\n}\n.fa-star-o:before {\n  content: \"\\f006\";\n}\n.fa-user:before {\n  content: \"\\f007\";\n}\n.fa-film:before {\n  content: \"\\f008\";\n}\n.fa-th-large:before {\n  content: \"\\f009\";\n}\n.fa-th:before {\n  content: \"\\f00a\";\n}\n.fa-th-list:before {\n  content: \"\\f00b\";\n}\n.fa-check:before {\n  content: \"\\f00c\";\n}\n.fa-remove:before,\n.fa-close:before,\n.fa-times:before {\n  content: \"\\f00d\";\n}\n.fa-search-plus:before {\n  content: \"\\f00e\";\n}\n.fa-search-minus:before {\n  content: \"\\f010\";\n}\n.fa-power-off:before {\n  content: \"\\f011\";\n}\n.fa-signal:before {\n  content: \"\\f012\";\n}\n.fa-gear:before,\n.fa-cog:before {\n  content: \"\\f013\";\n}\n.fa-trash-o:before {\n  content: \"\\f014\";\n}\n.fa-home:before {\n  content: \"\\f015\";\n}\n.fa-file-o:before {\n  content: \"\\f016\";\n}\n.fa-clock-o:before {\n  content: \"\\f017\";\n}\n.fa-road:before {\n  content: \"\\f018\";\n}\n.fa-download:before {\n  content: \"\\f019\";\n}\n.fa-arrow-circle-o-down:before {\n  content: \"\\f01a\";\n}\n.fa-arrow-circle-o-up:before {\n  content: \"\\f01b\";\n}\n.fa-inbox:before {\n  content: \"\\f01c\";\n}\n.fa-play-circle-o:before {\n  content: \"\\f01d\";\n}\n.fa-rotate-right:before,\n.fa-repeat:before {\n  content: \"\\f01e\";\n}\n.fa-refresh:before {\n  content: \"\\f021\";\n}\n.fa-list-alt:before {\n  content: \"\\f022\";\n}\n.fa-lock:before {\n  content: \"\\f023\";\n}\n.fa-flag:before {\n  content: \"\\f024\";\n}\n.fa-headphones:before {\n  content: \"\\f025\";\n}\n.fa-volume-off:before {\n  content: \"\\f026\";\n}\n.fa-volume-down:before {\n  content: \"\\f027\";\n}\n.fa-volume-up:before {\n  content: \"\\f028\";\n}\n.fa-qrcode:before {\n  content: \"\\f029\";\n}\n.fa-barcode:before {\n  content: \"\\f02a\";\n}\n.fa-tag:before {\n  content: \"\\f02b\";\n}\n.fa-tags:before {\n  content: \"\\f02c\";\n}\n.fa-book:before {\n  content: \"\\f02d\";\n}\n.fa-bookmark:before {\n  content: \"\\f02e\";\n}\n.fa-print:before {\n  content: \"\\f02f\";\n}\n.fa-camera:before {\n  content: \"\\f030\";\n}\n.fa-font:before {\n  content: \"\\f031\";\n}\n.fa-bold:before {\n  content: \"\\f032\";\n}\n.fa-italic:before {\n  content: \"\\f033\";\n}\n.fa-text-height:before {\n  content: \"\\f034\";\n}\n.fa-text-width:before {\n  content: \"\\f035\";\n}\n.fa-align-left:before {\n  content: \"\\f036\";\n}\n.fa-align-center:before {\n  content: \"\\f037\";\n}\n.fa-align-right:before {\n  content: \"\\f038\";\n}\n.fa-align-justify:before {\n  content: \"\\f039\";\n}\n.fa-list:before {\n  content: \"\\f03a\";\n}\n.fa-dedent:before,\n.fa-outdent:before {\n  content: \"\\f03b\";\n}\n.fa-indent:before {\n  content: \"\\f03c\";\n}\n.fa-video-camera:before {\n  content: \"\\f03d\";\n}\n.fa-photo:before,\n.fa-image:before,\n.fa-picture-o:before {\n  content: \"\\f03e\";\n}\n.fa-pencil:before {\n  content: \"\\f040\";\n}\n.fa-map-marker:before {\n  content: \"\\f041\";\n}\n.fa-adjust:before {\n  content: \"\\f042\";\n}\n.fa-tint:before {\n  content: \"\\f043\";\n}\n.fa-edit:before,\n.fa-pencil-square-o:before {\n  content: \"\\f044\";\n}\n.fa-share-square-o:before {\n  content: \"\\f045\";\n}\n.fa-check-square-o:before {\n  content: \"\\f046\";\n}\n.fa-arrows:before {\n  content: \"\\f047\";\n}\n.fa-step-backward:before {\n  content: \"\\f048\";\n}\n.fa-fast-backward:before {\n  content: \"\\f049\";\n}\n.fa-backward:before {\n  content: \"\\f04a\";\n}\n.fa-play:before {\n  content: \"\\f04b\";\n}\n.fa-pause:before {\n  content: \"\\f04c\";\n}\n.fa-stop:before {\n  content: \"\\f04d\";\n}\n.fa-forward:before {\n  content: \"\\f04e\";\n}\n.fa-fast-forward:before {\n  content: \"\\f050\";\n}\n.fa-step-forward:before {\n  content: \"\\f051\";\n}\n.fa-eject:before {\n  content: \"\\f052\";\n}\n.fa-chevron-left:before {\n  content: \"\\f053\";\n}\n.fa-chevron-right:before {\n  content: \"\\f054\";\n}\n.fa-plus-circle:before {\n  content: \"\\f055\";\n}\n.fa-minus-circle:before {\n  content: \"\\f056\";\n}\n.fa-times-circle:before {\n  content: \"\\f057\";\n}\n.fa-check-circle:before {\n  content: \"\\f058\";\n}\n.fa-question-circle:before {\n  content: \"\\f059\";\n}\n.fa-info-circle:before {\n  content: \"\\f05a\";\n}\n.fa-crosshairs:before {\n  content: \"\\f05b\";\n}\n.fa-times-circle-o:before {\n  content: \"\\f05c\";\n}\n.fa-check-circle-o:before {\n  content: \"\\f05d\";\n}\n.fa-ban:before {\n  content: \"\\f05e\";\n}\n.fa-arrow-left:before {\n  content: \"\\f060\";\n}\n.fa-arrow-right:before {\n  content: \"\\f061\";\n}\n.fa-arrow-up:before {\n  content: \"\\f062\";\n}\n.fa-arrow-down:before {\n  content: \"\\f063\";\n}\n.fa-mail-forward:before,\n.fa-share:before {\n  content: \"\\f064\";\n}\n.fa-expand:before {\n  content: \"\\f065\";\n}\n.fa-compress:before {\n  content: \"\\f066\";\n}\n.fa-plus:before {\n  content: \"\\f067\";\n}\n.fa-minus:before {\n  content: \"\\f068\";\n}\n.fa-asterisk:before {\n  content: \"\\f069\";\n}\n.fa-exclamation-circle:before {\n  content: \"\\f06a\";\n}\n.fa-gift:before {\n  content: \"\\f06b\";\n}\n.fa-leaf:before {\n  content: \"\\f06c\";\n}\n.fa-fire:before {\n  content: \"\\f06d\";\n}\n.fa-eye:before {\n  content: \"\\f06e\";\n}\n.fa-eye-slash:before {\n  content: \"\\f070\";\n}\n.fa-warning:before,\n.fa-exclamation-triangle:before {\n  content: \"\\f071\";\n}\n.fa-plane:before {\n  content: \"\\f072\";\n}\n.fa-calendar:before {\n  content: \"\\f073\";\n}\n.fa-random:before {\n  content: \"\\f074\";\n}\n.fa-comment:before {\n  content: \"\\f075\";\n}\n.fa-magnet:before {\n  content: \"\\f076\";\n}\n.fa-chevron-up:before {\n  content: \"\\f077\";\n}\n.fa-chevron-down:before {\n  content: \"\\f078\";\n}\n.fa-retweet:before {\n  content: \"\\f079\";\n}\n.fa-shopping-cart:before {\n  content: \"\\f07a\";\n}\n.fa-folder:before {\n  content: \"\\f07b\";\n}\n.fa-folder-open:before {\n  content: \"\\f07c\";\n}\n.fa-arrows-v:before {\n  content: \"\\f07d\";\n}\n.fa-arrows-h:before {\n  content: \"\\f07e\";\n}\n.fa-bar-chart-o:before,\n.fa-bar-chart:before {\n  content: \"\\f080\";\n}\n.fa-twitter-square:before {\n  content: \"\\f081\";\n}\n.fa-facebook-square:before {\n  content: \"\\f082\";\n}\n.fa-camera-retro:before {\n  content: \"\\f083\";\n}\n.fa-key:before {\n  content: \"\\f084\";\n}\n.fa-gears:before,\n.fa-cogs:before {\n  content: \"\\f085\";\n}\n.fa-comments:before {\n  content: \"\\f086\";\n}\n.fa-thumbs-o-up:before {\n  content: \"\\f087\";\n}\n.fa-thumbs-o-down:before {\n  content: \"\\f088\";\n}\n.fa-star-half:before {\n  content: \"\\f089\";\n}\n.fa-heart-o:before {\n  content: \"\\f08a\";\n}\n.fa-sign-out:before {\n  content: \"\\f08b\";\n}\n.fa-linkedin-square:before {\n  content: \"\\f08c\";\n}\n.fa-thumb-tack:before {\n  content: \"\\f08d\";\n}\n.fa-external-link:before {\n  content: \"\\f08e\";\n}\n.fa-sign-in:before {\n  content: \"\\f090\";\n}\n.fa-trophy:before {\n  content: \"\\f091\";\n}\n.fa-github-square:before {\n  content: \"\\f092\";\n}\n.fa-upload:before {\n  content: \"\\f093\";\n}\n.fa-lemon-o:before {\n  content: \"\\f094\";\n}\n.fa-phone:before {\n  content: \"\\f095\";\n}\n.fa-square-o:before {\n  content: \"\\f096\";\n}\n.fa-bookmark-o:before {\n  content: \"\\f097\";\n}\n.fa-phone-square:before {\n  content: \"\\f098\";\n}\n.fa-twitter:before {\n  content: \"\\f099\";\n}\n.fa-facebook-f:before,\n.fa-facebook:before {\n  content: \"\\f09a\";\n}\n.fa-github:before {\n  content: \"\\f09b\";\n}\n.fa-unlock:before {\n  content: \"\\f09c\";\n}\n.fa-credit-card:before {\n  content: \"\\f09d\";\n}\n.fa-feed:before,\n.fa-rss:before {\n  content: \"\\f09e\";\n}\n.fa-hdd-o:before {\n  content: \"\\f0a0\";\n}\n.fa-bullhorn:before {\n  content: \"\\f0a1\";\n}\n.fa-bell:before {\n  content: \"\\f0f3\";\n}\n.fa-certificate:before {\n  content: \"\\f0a3\";\n}\n.fa-hand-o-right:before {\n  content: \"\\f0a4\";\n}\n.fa-hand-o-left:before {\n  content: \"\\f0a5\";\n}\n.fa-hand-o-up:before {\n  content: \"\\f0a6\";\n}\n.fa-hand-o-down:before {\n  content: \"\\f0a7\";\n}\n.fa-arrow-circle-left:before {\n  content: \"\\f0a8\";\n}\n.fa-arrow-circle-right:before {\n  content: \"\\f0a9\";\n}\n.fa-arrow-circle-up:before {\n  content: \"\\f0aa\";\n}\n.fa-arrow-circle-down:before {\n  content: \"\\f0ab\";\n}\n.fa-globe:before {\n  content: \"\\f0ac\";\n}\n.fa-wrench:before {\n  content: \"\\f0ad\";\n}\n.fa-tasks:before {\n  content: \"\\f0ae\";\n}\n.fa-filter:before {\n  content: \"\\f0b0\";\n}\n.fa-briefcase:before {\n  content: \"\\f0b1\";\n}\n.fa-arrows-alt:before {\n  content: \"\\f0b2\";\n}\n.fa-group:before,\n.fa-users:before {\n  content: \"\\f0c0\";\n}\n.fa-chain:before,\n.fa-link:before {\n  content: \"\\f0c1\";\n}\n.fa-cloud:before {\n  content: \"\\f0c2\";\n}\n.fa-flask:before {\n  content: \"\\f0c3\";\n}\n.fa-cut:before,\n.fa-scissors:before {\n  content: \"\\f0c4\";\n}\n.fa-copy:before,\n.fa-files-o:before {\n  content: \"\\f0c5\";\n}\n.fa-paperclip:before {\n  content: \"\\f0c6\";\n}\n.fa-save:before,\n.fa-floppy-o:before {\n  content: \"\\f0c7\";\n}\n.fa-square:before {\n  content: \"\\f0c8\";\n}\n.fa-navicon:before,\n.fa-reorder:before,\n.fa-bars:before {\n  content: \"\\f0c9\";\n}\n.fa-list-ul:before {\n  content: \"\\f0ca\";\n}\n.fa-list-ol:before {\n  content: \"\\f0cb\";\n}\n.fa-strikethrough:before {\n  content: \"\\f0cc\";\n}\n.fa-underline:before {\n  content: \"\\f0cd\";\n}\n.fa-table:before {\n  content: \"\\f0ce\";\n}\n.fa-magic:before {\n  content: \"\\f0d0\";\n}\n.fa-truck:before {\n  content: \"\\f0d1\";\n}\n.fa-pinterest:before {\n  content: \"\\f0d2\";\n}\n.fa-pinterest-square:before {\n  content: \"\\f0d3\";\n}\n.fa-google-plus-square:before {\n  content: \"\\f0d4\";\n}\n.fa-google-plus:before {\n  content: \"\\f0d5\";\n}\n.fa-money:before {\n  content: \"\\f0d6\";\n}\n.fa-caret-down:before {\n  content: \"\\f0d7\";\n}\n.fa-caret-up:before {\n  content: \"\\f0d8\";\n}\n.fa-caret-left:before {\n  content: \"\\f0d9\";\n}\n.fa-caret-right:before {\n  content: \"\\f0da\";\n}\n.fa-columns:before {\n  content: \"\\f0db\";\n}\n.fa-unsorted:before,\n.fa-sort:before {\n  content: \"\\f0dc\";\n}\n.fa-sort-down:before,\n.fa-sort-desc:before {\n  content: \"\\f0dd\";\n}\n.fa-sort-up:before,\n.fa-sort-asc:before {\n  content: \"\\f0de\";\n}\n.fa-envelope:before {\n  content: \"\\f0e0\";\n}\n.fa-linkedin:before {\n  content: \"\\f0e1\";\n}\n.fa-rotate-left:before,\n.fa-undo:before {\n  content: \"\\f0e2\";\n}\n.fa-legal:before,\n.fa-gavel:before {\n  content: \"\\f0e3\";\n}\n.fa-dashboard:before,\n.fa-tachometer:before {\n  content: \"\\f0e4\";\n}\n.fa-comment-o:before {\n  content: \"\\f0e5\";\n}\n.fa-comments-o:before {\n  content: \"\\f0e6\";\n}\n.fa-flash:before,\n.fa-bolt:before {\n  content: \"\\f0e7\";\n}\n.fa-sitemap:before {\n  content: \"\\f0e8\";\n}\n.fa-umbrella:before {\n  content: \"\\f0e9\";\n}\n.fa-paste:before,\n.fa-clipboard:before {\n  content: \"\\f0ea\";\n}\n.fa-lightbulb-o:before {\n  content: \"\\f0eb\";\n}\n.fa-exchange:before {\n  content: \"\\f0ec\";\n}\n.fa-cloud-download:before {\n  content: \"\\f0ed\";\n}\n.fa-cloud-upload:before {\n  content: \"\\f0ee\";\n}\n.fa-user-md:before {\n  content: \"\\f0f0\";\n}\n.fa-stethoscope:before {\n  content: \"\\f0f1\";\n}\n.fa-suitcase:before {\n  content: \"\\f0f2\";\n}\n.fa-bell-o:before {\n  content: \"\\f0a2\";\n}\n.fa-coffee:before {\n  content: \"\\f0f4\";\n}\n.fa-cutlery:before {\n  content: \"\\f0f5\";\n}\n.fa-file-text-o:before {\n  content: \"\\f0f6\";\n}\n.fa-building-o:before {\n  content: \"\\f0f7\";\n}\n.fa-hospital-o:before {\n  content: \"\\f0f8\";\n}\n.fa-ambulance:before {\n  content: \"\\f0f9\";\n}\n.fa-medkit:before {\n  content: \"\\f0fa\";\n}\n.fa-fighter-jet:before {\n  content: \"\\f0fb\";\n}\n.fa-beer:before {\n  content: \"\\f0fc\";\n}\n.fa-h-square:before {\n  content: \"\\f0fd\";\n}\n.fa-plus-square:before {\n  content: \"\\f0fe\";\n}\n.fa-angle-double-left:before {\n  content: \"\\f100\";\n}\n.fa-angle-double-right:before {\n  content: \"\\f101\";\n}\n.fa-angle-double-up:before {\n  content: \"\\f102\";\n}\n.fa-angle-double-down:before {\n  content: \"\\f103\";\n}\n.fa-angle-left:before {\n  content: \"\\f104\";\n}\n.fa-angle-right:before {\n  content: \"\\f105\";\n}\n.fa-angle-up:before {\n  content: \"\\f106\";\n}\n.fa-angle-down:before {\n  content: \"\\f107\";\n}\n.fa-desktop:before {\n  content: \"\\f108\";\n}\n.fa-laptop:before {\n  content: \"\\f109\";\n}\n.fa-tablet:before {\n  content: \"\\f10a\";\n}\n.fa-mobile-phone:before,\n.fa-mobile:before {\n  content: \"\\f10b\";\n}\n.fa-circle-o:before {\n  content: \"\\f10c\";\n}\n.fa-quote-left:before {\n  content: \"\\f10d\";\n}\n.fa-quote-right:before {\n  content: \"\\f10e\";\n}\n.fa-spinner:before {\n  content: \"\\f110\";\n}\n.fa-circle:before {\n  content: \"\\f111\";\n}\n.fa-mail-reply:before,\n.fa-reply:before {\n  content: \"\\f112\";\n}\n.fa-github-alt:before {\n  content: \"\\f113\";\n}\n.fa-folder-o:before {\n  content: \"\\f114\";\n}\n.fa-folder-open-o:before {\n  content: \"\\f115\";\n}\n.fa-smile-o:before {\n  content: \"\\f118\";\n}\n.fa-frown-o:before {\n  content: \"\\f119\";\n}\n.fa-meh-o:before {\n  content: \"\\f11a\";\n}\n.fa-gamepad:before {\n  content: \"\\f11b\";\n}\n.fa-keyboard-o:before {\n  content: \"\\f11c\";\n}\n.fa-flag-o:before {\n  content: \"\\f11d\";\n}\n.fa-flag-checkered:before {\n  content: \"\\f11e\";\n}\n.fa-terminal:before {\n  content: \"\\f120\";\n}\n.fa-code:before {\n  content: \"\\f121\";\n}\n.fa-mail-reply-all:before,\n.fa-reply-all:before {\n  content: \"\\f122\";\n}\n.fa-star-half-empty:before,\n.fa-star-half-full:before,\n.fa-star-half-o:before {\n  content: \"\\f123\";\n}\n.fa-location-arrow:before {\n  content: \"\\f124\";\n}\n.fa-crop:before {\n  content: \"\\f125\";\n}\n.fa-code-fork:before {\n  content: \"\\f126\";\n}\n.fa-unlink:before,\n.fa-chain-broken:before {\n  content: \"\\f127\";\n}\n.fa-question:before {\n  content: \"\\f128\";\n}\n.fa-info:before {\n  content: \"\\f129\";\n}\n.fa-exclamation:before {\n  content: \"\\f12a\";\n}\n.fa-superscript:before {\n  content: \"\\f12b\";\n}\n.fa-subscript:before {\n  content: \"\\f12c\";\n}\n.fa-eraser:before {\n  content: \"\\f12d\";\n}\n.fa-puzzle-piece:before {\n  content: \"\\f12e\";\n}\n.fa-microphone:before {\n  content: \"\\f130\";\n}\n.fa-microphone-slash:before {\n  content: \"\\f131\";\n}\n.fa-shield:before {\n  content: \"\\f132\";\n}\n.fa-calendar-o:before {\n  content: \"\\f133\";\n}\n.fa-fire-extinguisher:before {\n  content: \"\\f134\";\n}\n.fa-rocket:before {\n  content: \"\\f135\";\n}\n.fa-maxcdn:before {\n  content: \"\\f136\";\n}\n.fa-chevron-circle-left:before {\n  content: \"\\f137\";\n}\n.fa-chevron-circle-right:before {\n  content: \"\\f138\";\n}\n.fa-chevron-circle-up:before {\n  content: \"\\f139\";\n}\n.fa-chevron-circle-down:before {\n  content: \"\\f13a\";\n}\n.fa-html5:before {\n  content: \"\\f13b\";\n}\n.fa-css3:before {\n  content: \"\\f13c\";\n}\n.fa-anchor:before {\n  content: \"\\f13d\";\n}\n.fa-unlock-alt:before {\n  content: \"\\f13e\";\n}\n.fa-bullseye:before {\n  content: \"\\f140\";\n}\n.fa-ellipsis-h:before {\n  content: \"\\f141\";\n}\n.fa-ellipsis-v:before {\n  content: \"\\f142\";\n}\n.fa-rss-square:before {\n  content: \"\\f143\";\n}\n.fa-play-circle:before {\n  content: \"\\f144\";\n}\n.fa-ticket:before {\n  content: \"\\f145\";\n}\n.fa-minus-square:before {\n  content: \"\\f146\";\n}\n.fa-minus-square-o:before {\n  content: \"\\f147\";\n}\n.fa-level-up:before {\n  content: \"\\f148\";\n}\n.fa-level-down:before {\n  content: \"\\f149\";\n}\n.fa-check-square:before {\n  content: \"\\f14a\";\n}\n.fa-pencil-square:before {\n  content: \"\\f14b\";\n}\n.fa-external-link-square:before {\n  content: \"\\f14c\";\n}\n.fa-share-square:before {\n  content: \"\\f14d\";\n}\n.fa-compass:before {\n  content: \"\\f14e\";\n}\n.fa-toggle-down:before,\n.fa-caret-square-o-down:before {\n  content: \"\\f150\";\n}\n.fa-toggle-up:before,\n.fa-caret-square-o-up:before {\n  content: \"\\f151\";\n}\n.fa-toggle-right:before,\n.fa-caret-square-o-right:before {\n  content: \"\\f152\";\n}\n.fa-euro:before,\n.fa-eur:before {\n  content: \"\\f153\";\n}\n.fa-gbp:before {\n  content: \"\\f154\";\n}\n.fa-dollar:before,\n.fa-usd:before {\n  content: \"\\f155\";\n}\n.fa-rupee:before,\n.fa-inr:before {\n  content: \"\\f156\";\n}\n.fa-cny:before,\n.fa-rmb:before,\n.fa-yen:before,\n.fa-jpy:before {\n  content: \"\\f157\";\n}\n.fa-ruble:before,\n.fa-rouble:before,\n.fa-rub:before {\n  content: \"\\f158\";\n}\n.fa-won:before,\n.fa-krw:before {\n  content: \"\\f159\";\n}\n.fa-bitcoin:before,\n.fa-btc:before {\n  content: \"\\f15a\";\n}\n.fa-file:before {\n  content: \"\\f15b\";\n}\n.fa-file-text:before {\n  content: \"\\f15c\";\n}\n.fa-sort-alpha-asc:before {\n  content: \"\\f15d\";\n}\n.fa-sort-alpha-desc:before {\n  content: \"\\f15e\";\n}\n.fa-sort-amount-asc:before {\n  content: \"\\f160\";\n}\n.fa-sort-amount-desc:before {\n  content: \"\\f161\";\n}\n.fa-sort-numeric-asc:before {\n  content: \"\\f162\";\n}\n.fa-sort-numeric-desc:before {\n  content: \"\\f163\";\n}\n.fa-thumbs-up:before {\n  content: \"\\f164\";\n}\n.fa-thumbs-down:before {\n  content: \"\\f165\";\n}\n.fa-youtube-square:before {\n  content: \"\\f166\";\n}\n.fa-youtube:before {\n  content: \"\\f167\";\n}\n.fa-xing:before {\n  content: \"\\f168\";\n}\n.fa-xing-square:before {\n  content: \"\\f169\";\n}\n.fa-youtube-play:before {\n  content: \"\\f16a\";\n}\n.fa-dropbox:before {\n  content: \"\\f16b\";\n}\n.fa-stack-overflow:before {\n  content: \"\\f16c\";\n}\n.fa-instagram:before {\n  content: \"\\f16d\";\n}\n.fa-flickr:before {\n  content: \"\\f16e\";\n}\n.fa-adn:before {\n  content: \"\\f170\";\n}\n.fa-bitbucket:before {\n  content: \"\\f171\";\n}\n.fa-bitbucket-square:before {\n  content: \"\\f172\";\n}\n.fa-tumblr:before {\n  content: \"\\f173\";\n}\n.fa-tumblr-square:before {\n  content: \"\\f174\";\n}\n.fa-long-arrow-down:before {\n  content: \"\\f175\";\n}\n.fa-long-arrow-up:before {\n  content: \"\\f176\";\n}\n.fa-long-arrow-left:before {\n  content: \"\\f177\";\n}\n.fa-long-arrow-right:before {\n  content: \"\\f178\";\n}\n.fa-apple:before {\n  content: \"\\f179\";\n}\n.fa-windows:before {\n  content: \"\\f17a\";\n}\n.fa-android:before {\n  content: \"\\f17b\";\n}\n.fa-linux:before {\n  content: \"\\f17c\";\n}\n.fa-dribbble:before {\n  content: \"\\f17d\";\n}\n.fa-skype:before {\n  content: \"\\f17e\";\n}\n.fa-foursquare:before {\n  content: \"\\f180\";\n}\n.fa-trello:before {\n  content: \"\\f181\";\n}\n.fa-female:before {\n  content: \"\\f182\";\n}\n.fa-male:before {\n  content: \"\\f183\";\n}\n.fa-gittip:before,\n.fa-gratipay:before {\n  content: \"\\f184\";\n}\n.fa-sun-o:before {\n  content: \"\\f185\";\n}\n.fa-moon-o:before {\n  content: \"\\f186\";\n}\n.fa-archive:before {\n  content: \"\\f187\";\n}\n.fa-bug:before {\n  content: \"\\f188\";\n}\n.fa-vk:before {\n  content: \"\\f189\";\n}\n.fa-weibo:before {\n  content: \"\\f18a\";\n}\n.fa-renren:before {\n  content: \"\\f18b\";\n}\n.fa-pagelines:before {\n  content: \"\\f18c\";\n}\n.fa-stack-exchange:before {\n  content: \"\\f18d\";\n}\n.fa-arrow-circle-o-right:before {\n  content: \"\\f18e\";\n}\n.fa-arrow-circle-o-left:before {\n  content: \"\\f190\";\n}\n.fa-toggle-left:before,\n.fa-caret-square-o-left:before {\n  content: \"\\f191\";\n}\n.fa-dot-circle-o:before {\n  content: \"\\f192\";\n}\n.fa-wheelchair:before {\n  content: \"\\f193\";\n}\n.fa-vimeo-square:before {\n  content: \"\\f194\";\n}\n.fa-turkish-lira:before,\n.fa-try:before {\n  content: \"\\f195\";\n}\n.fa-plus-square-o:before {\n  content: \"\\f196\";\n}\n.fa-space-shuttle:before {\n  content: \"\\f197\";\n}\n.fa-slack:before {\n  content: \"\\f198\";\n}\n.fa-envelope-square:before {\n  content: \"\\f199\";\n}\n.fa-wordpress:before {\n  content: \"\\f19a\";\n}\n.fa-openid:before {\n  content: \"\\f19b\";\n}\n.fa-institution:before,\n.fa-bank:before,\n.fa-university:before {\n  content: \"\\f19c\";\n}\n.fa-mortar-board:before,\n.fa-graduation-cap:before {\n  content: \"\\f19d\";\n}\n.fa-yahoo:before {\n  content: \"\\f19e\";\n}\n.fa-google:before {\n  content: \"\\f1a0\";\n}\n.fa-reddit:before {\n  content: \"\\f1a1\";\n}\n.fa-reddit-square:before {\n  content: \"\\f1a2\";\n}\n.fa-stumbleupon-circle:before {\n  content: \"\\f1a3\";\n}\n.fa-stumbleupon:before {\n  content: \"\\f1a4\";\n}\n.fa-delicious:before {\n  content: \"\\f1a5\";\n}\n.fa-digg:before {\n  content: \"\\f1a6\";\n}\n.fa-pied-piper:before {\n  content: \"\\f1a7\";\n}\n.fa-pied-piper-alt:before {\n  content: \"\\f1a8\";\n}\n.fa-drupal:before {\n  content: \"\\f1a9\";\n}\n.fa-joomla:before {\n  content: \"\\f1aa\";\n}\n.fa-language:before {\n  content: \"\\f1ab\";\n}\n.fa-fax:before {\n  content: \"\\f1ac\";\n}\n.fa-building:before {\n  content: \"\\f1ad\";\n}\n.fa-child:before {\n  content: \"\\f1ae\";\n}\n.fa-paw:before {\n  content: \"\\f1b0\";\n}\n.fa-spoon:before {\n  content: \"\\f1b1\";\n}\n.fa-cube:before {\n  content: \"\\f1b2\";\n}\n.fa-cubes:before {\n  content: \"\\f1b3\";\n}\n.fa-behance:before {\n  content: \"\\f1b4\";\n}\n.fa-behance-square:before {\n  content: \"\\f1b5\";\n}\n.fa-steam:before {\n  content: \"\\f1b6\";\n}\n.fa-steam-square:before {\n  content: \"\\f1b7\";\n}\n.fa-recycle:before {\n  content: \"\\f1b8\";\n}\n.fa-automobile:before,\n.fa-car:before {\n  content: \"\\f1b9\";\n}\n.fa-cab:before,\n.fa-taxi:before {\n  content: \"\\f1ba\";\n}\n.fa-tree:before {\n  content: \"\\f1bb\";\n}\n.fa-spotify:before {\n  content: \"\\f1bc\";\n}\n.fa-deviantart:before {\n  content: \"\\f1bd\";\n}\n.fa-soundcloud:before {\n  content: \"\\f1be\";\n}\n.fa-database:before {\n  content: \"\\f1c0\";\n}\n.fa-file-pdf-o:before {\n  content: \"\\f1c1\";\n}\n.fa-file-word-o:before {\n  content: \"\\f1c2\";\n}\n.fa-file-excel-o:before {\n  content: \"\\f1c3\";\n}\n.fa-file-powerpoint-o:before {\n  content: \"\\f1c4\";\n}\n.fa-file-photo-o:before,\n.fa-file-picture-o:before,\n.fa-file-image-o:before {\n  content: \"\\f1c5\";\n}\n.fa-file-zip-o:before,\n.fa-file-archive-o:before {\n  content: \"\\f1c6\";\n}\n.fa-file-sound-o:before,\n.fa-file-audio-o:before {\n  content: \"\\f1c7\";\n}\n.fa-file-movie-o:before,\n.fa-file-video-o:before {\n  content: \"\\f1c8\";\n}\n.fa-file-code-o:before {\n  content: \"\\f1c9\";\n}\n.fa-vine:before {\n  content: \"\\f1ca\";\n}\n.fa-codepen:before {\n  content: \"\\f1cb\";\n}\n.fa-jsfiddle:before {\n  content: \"\\f1cc\";\n}\n.fa-life-bouy:before,\n.fa-life-buoy:before,\n.fa-life-saver:before,\n.fa-support:before,\n.fa-life-ring:before {\n  content: \"\\f1cd\";\n}\n.fa-circle-o-notch:before {\n  content: \"\\f1ce\";\n}\n.fa-ra:before,\n.fa-rebel:before {\n  content: \"\\f1d0\";\n}\n.fa-ge:before,\n.fa-empire:before {\n  content: \"\\f1d1\";\n}\n.fa-git-square:before {\n  content: \"\\f1d2\";\n}\n.fa-git:before {\n  content: \"\\f1d3\";\n}\n.fa-y-combinator-square:before,\n.fa-yc-square:before,\n.fa-hacker-news:before {\n  content: \"\\f1d4\";\n}\n.fa-tencent-weibo:before {\n  content: \"\\f1d5\";\n}\n.fa-qq:before {\n  content: \"\\f1d6\";\n}\n.fa-wechat:before,\n.fa-weixin:before {\n  content: \"\\f1d7\";\n}\n.fa-send:before,\n.fa-paper-plane:before {\n  content: \"\\f1d8\";\n}\n.fa-send-o:before,\n.fa-paper-plane-o:before {\n  content: \"\\f1d9\";\n}\n.fa-history:before {\n  content: \"\\f1da\";\n}\n.fa-circle-thin:before {\n  content: \"\\f1db\";\n}\n.fa-header:before {\n  content: \"\\f1dc\";\n}\n.fa-paragraph:before {\n  content: \"\\f1dd\";\n}\n.fa-sliders:before {\n  content: \"\\f1de\";\n}\n.fa-share-alt:before {\n  content: \"\\f1e0\";\n}\n.fa-share-alt-square:before {\n  content: \"\\f1e1\";\n}\n.fa-bomb:before {\n  content: \"\\f1e2\";\n}\n.fa-soccer-ball-o:before,\n.fa-futbol-o:before {\n  content: \"\\f1e3\";\n}\n.fa-tty:before {\n  content: \"\\f1e4\";\n}\n.fa-binoculars:before {\n  content: \"\\f1e5\";\n}\n.fa-plug:before {\n  content: \"\\f1e6\";\n}\n.fa-slideshare:before {\n  content: \"\\f1e7\";\n}\n.fa-twitch:before {\n  content: \"\\f1e8\";\n}\n.fa-yelp:before {\n  content: \"\\f1e9\";\n}\n.fa-newspaper-o:before {\n  content: \"\\f1ea\";\n}\n.fa-wifi:before {\n  content: \"\\f1eb\";\n}\n.fa-calculator:before {\n  content: \"\\f1ec\";\n}\n.fa-paypal:before {\n  content: \"\\f1ed\";\n}\n.fa-google-wallet:before {\n  content: \"\\f1ee\";\n}\n.fa-cc-visa:before {\n  content: \"\\f1f0\";\n}\n.fa-cc-mastercard:before {\n  content: \"\\f1f1\";\n}\n.fa-cc-discover:before {\n  content: \"\\f1f2\";\n}\n.fa-cc-amex:before {\n  content: \"\\f1f3\";\n}\n.fa-cc-paypal:before {\n  content: \"\\f1f4\";\n}\n.fa-cc-stripe:before {\n  content: \"\\f1f5\";\n}\n.fa-bell-slash:before {\n  content: \"\\f1f6\";\n}\n.fa-bell-slash-o:before {\n  content: \"\\f1f7\";\n}\n.fa-trash:before {\n  content: \"\\f1f8\";\n}\n.fa-copyright:before {\n  content: \"\\f1f9\";\n}\n.fa-at:before {\n  content: \"\\f1fa\";\n}\n.fa-eyedropper:before {\n  content: \"\\f1fb\";\n}\n.fa-paint-brush:before {\n  content: \"\\f1fc\";\n}\n.fa-birthday-cake:before {\n  content: \"\\f1fd\";\n}\n.fa-area-chart:before {\n  content: \"\\f1fe\";\n}\n.fa-pie-chart:before {\n  content: \"\\f200\";\n}\n.fa-line-chart:before {\n  content: \"\\f201\";\n}\n.fa-lastfm:before {\n  content: \"\\f202\";\n}\n.fa-lastfm-square:before {\n  content: \"\\f203\";\n}\n.fa-toggle-off:before {\n  content: \"\\f204\";\n}\n.fa-toggle-on:before {\n  content: \"\\f205\";\n}\n.fa-bicycle:before {\n  content: \"\\f206\";\n}\n.fa-bus:before {\n  content: \"\\f207\";\n}\n.fa-ioxhost:before {\n  content: \"\\f208\";\n}\n.fa-angellist:before {\n  content: \"\\f209\";\n}\n.fa-cc:before {\n  content: \"\\f20a\";\n}\n.fa-shekel:before,\n.fa-sheqel:before,\n.fa-ils:before {\n  content: \"\\f20b\";\n}\n.fa-meanpath:before {\n  content: \"\\f20c\";\n}\n.fa-buysellads:before {\n  content: \"\\f20d\";\n}\n.fa-connectdevelop:before {\n  content: \"\\f20e\";\n}\n.fa-dashcube:before {\n  content: \"\\f210\";\n}\n.fa-forumbee:before {\n  content: \"\\f211\";\n}\n.fa-leanpub:before {\n  content: \"\\f212\";\n}\n.fa-sellsy:before {\n  content: \"\\f213\";\n}\n.fa-shirtsinbulk:before {\n  content: \"\\f214\";\n}\n.fa-simplybuilt:before {\n  content: \"\\f215\";\n}\n.fa-skyatlas:before {\n  content: \"\\f216\";\n}\n.fa-cart-plus:before {\n  content: \"\\f217\";\n}\n.fa-cart-arrow-down:before {\n  content: \"\\f218\";\n}\n.fa-diamond:before {\n  content: \"\\f219\";\n}\n.fa-ship:before {\n  content: \"\\f21a\";\n}\n.fa-user-secret:before {\n  content: \"\\f21b\";\n}\n.fa-motorcycle:before {\n  content: \"\\f21c\";\n}\n.fa-street-view:before {\n  content: \"\\f21d\";\n}\n.fa-heartbeat:before {\n  content: \"\\f21e\";\n}\n.fa-venus:before {\n  content: \"\\f221\";\n}\n.fa-mars:before {\n  content: \"\\f222\";\n}\n.fa-mercury:before {\n  content: \"\\f223\";\n}\n.fa-intersex:before,\n.fa-transgender:before {\n  content: \"\\f224\";\n}\n.fa-transgender-alt:before {\n  content: \"\\f225\";\n}\n.fa-venus-double:before {\n  content: \"\\f226\";\n}\n.fa-mars-double:before {\n  content: \"\\f227\";\n}\n.fa-venus-mars:before {\n  content: \"\\f228\";\n}\n.fa-mars-stroke:before {\n  content: \"\\f229\";\n}\n.fa-mars-stroke-v:before {\n  content: \"\\f22a\";\n}\n.fa-mars-stroke-h:before {\n  content: \"\\f22b\";\n}\n.fa-neuter:before {\n  content: \"\\f22c\";\n}\n.fa-genderless:before {\n  content: \"\\f22d\";\n}\n.fa-facebook-official:before {\n  content: \"\\f230\";\n}\n.fa-pinterest-p:before {\n  content: \"\\f231\";\n}\n.fa-whatsapp:before {\n  content: \"\\f232\";\n}\n.fa-server:before {\n  content: \"\\f233\";\n}\n.fa-user-plus:before {\n  content: \"\\f234\";\n}\n.fa-user-times:before {\n  content: \"\\f235\";\n}\n.fa-hotel:before,\n.fa-bed:before {\n  content: \"\\f236\";\n}\n.fa-viacoin:before {\n  content: \"\\f237\";\n}\n.fa-train:before {\n  content: \"\\f238\";\n}\n.fa-subway:before {\n  content: \"\\f239\";\n}\n.fa-medium:before {\n  content: \"\\f23a\";\n}\n.fa-yc:before,\n.fa-y-combinator:before {\n  content: \"\\f23b\";\n}\n.fa-optin-monster:before {\n  content: \"\\f23c\";\n}\n.fa-opencart:before {\n  content: \"\\f23d\";\n}\n.fa-expeditedssl:before {\n  content: \"\\f23e\";\n}\n.fa-battery-4:before,\n.fa-battery-full:before {\n  content: \"\\f240\";\n}\n.fa-battery-3:before,\n.fa-battery-three-quarters:before {\n  content: \"\\f241\";\n}\n.fa-battery-2:before,\n.fa-battery-half:before {\n  content: \"\\f242\";\n}\n.fa-battery-1:before,\n.fa-battery-quarter:before {\n  content: \"\\f243\";\n}\n.fa-battery-0:before,\n.fa-battery-empty:before {\n  content: \"\\f244\";\n}\n.fa-mouse-pointer:before {\n  content: \"\\f245\";\n}\n.fa-i-cursor:before {\n  content: \"\\f246\";\n}\n.fa-object-group:before {\n  content: \"\\f247\";\n}\n.fa-object-ungroup:before {\n  content: \"\\f248\";\n}\n.fa-sticky-note:before {\n  content: \"\\f249\";\n}\n.fa-sticky-note-o:before {\n  content: \"\\f24a\";\n}\n.fa-cc-jcb:before {\n  content: \"\\f24b\";\n}\n.fa-cc-diners-club:before {\n  content: \"\\f24c\";\n}\n.fa-clone:before {\n  content: \"\\f24d\";\n}\n.fa-balance-scale:before {\n  content: \"\\f24e\";\n}\n.fa-hourglass-o:before {\n  content: \"\\f250\";\n}\n.fa-hourglass-1:before,\n.fa-hourglass-start:before {\n  content: \"\\f251\";\n}\n.fa-hourglass-2:before,\n.fa-hourglass-half:before {\n  content: \"\\f252\";\n}\n.fa-hourglass-3:before,\n.fa-hourglass-end:before {\n  content: \"\\f253\";\n}\n.fa-hourglass:before {\n  content: \"\\f254\";\n}\n.fa-hand-grab-o:before,\n.fa-hand-rock-o:before {\n  content: \"\\f255\";\n}\n.fa-hand-stop-o:before,\n.fa-hand-paper-o:before {\n  content: \"\\f256\";\n}\n.fa-hand-scissors-o:before {\n  content: \"\\f257\";\n}\n.fa-hand-lizard-o:before {\n  content: \"\\f258\";\n}\n.fa-hand-spock-o:before {\n  content: \"\\f259\";\n}\n.fa-hand-pointer-o:before {\n  content: \"\\f25a\";\n}\n.fa-hand-peace-o:before {\n  content: \"\\f25b\";\n}\n.fa-trademark:before {\n  content: \"\\f25c\";\n}\n.fa-registered:before {\n  content: \"\\f25d\";\n}\n.fa-creative-commons:before {\n  content: \"\\f25e\";\n}\n.fa-gg:before {\n  content: \"\\f260\";\n}\n.fa-gg-circle:before {\n  content: \"\\f261\";\n}\n.fa-tripadvisor:before {\n  content: \"\\f262\";\n}\n.fa-odnoklassniki:before {\n  content: \"\\f263\";\n}\n.fa-odnoklassniki-square:before {\n  content: \"\\f264\";\n}\n.fa-get-pocket:before {\n  content: \"\\f265\";\n}\n.fa-wikipedia-w:before {\n  content: \"\\f266\";\n}\n.fa-safari:before {\n  content: \"\\f267\";\n}\n.fa-chrome:before {\n  content: \"\\f268\";\n}\n.fa-firefox:before {\n  content: \"\\f269\";\n}\n.fa-opera:before {\n  content: \"\\f26a\";\n}\n.fa-internet-explorer:before {\n  content: \"\\f26b\";\n}\n.fa-tv:before,\n.fa-television:before {\n  content: \"\\f26c\";\n}\n.fa-contao:before {\n  content: \"\\f26d\";\n}\n.fa-500px:before {\n  content: \"\\f26e\";\n}\n.fa-amazon:before {\n  content: \"\\f270\";\n}\n.fa-calendar-plus-o:before {\n  content: \"\\f271\";\n}\n.fa-calendar-minus-o:before {\n  content: \"\\f272\";\n}\n.fa-calendar-times-o:before {\n  content: \"\\f273\";\n}\n.fa-calendar-check-o:before {\n  content: \"\\f274\";\n}\n.fa-industry:before {\n  content: \"\\f275\";\n}\n.fa-map-pin:before {\n  content: \"\\f276\";\n}\n.fa-map-signs:before {\n  content: \"\\f277\";\n}\n.fa-map-o:before {\n  content: \"\\f278\";\n}\n.fa-map:before {\n  content: \"\\f279\";\n}\n.fa-commenting:before {\n  content: \"\\f27a\";\n}\n.fa-commenting-o:before {\n  content: \"\\f27b\";\n}\n.fa-houzz:before {\n  content: \"\\f27c\";\n}\n.fa-vimeo:before {\n  content: \"\\f27d\";\n}\n.fa-black-tie:before {\n  content: \"\\f27e\";\n}\n.fa-fonticons:before {\n  content: \"\\f280\";\n}\n@font-face {\n  font-family: 'themify';\n  src: url('../fonts/themify.eot?-fvbane');\n  src: url('../fonts/themify.eot?#iefix-fvbane') format('embedded-opentype'), url('../fonts/themify.woff?-fvbane') format('woff'), url('../fonts/themify.ttf?-fvbane') format('truetype'), url('../fonts/themify.svg?-fvbane#themify') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n[class^=\"ti-\"],\n[class*=\" ti-\"] {\n  font-family: 'themify';\n  speak: none;\n  font-style: normal;\n  font-weight: normal;\n  font-variant: normal;\n  text-transform: none;\n  line-height: 1;\n  /* Better Font Rendering =========== */\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.ti-wand:before {\n  content: \"\\e600\";\n}\n.ti-volume:before {\n  content: \"\\e601\";\n}\n.ti-user:before {\n  content: \"\\e602\";\n}\n.ti-unlock:before {\n  content: \"\\e603\";\n}\n.ti-unlink:before {\n  content: \"\\e604\";\n}\n.ti-trash:before {\n  content: \"\\e605\";\n}\n.ti-thought:before {\n  content: \"\\e606\";\n}\n.ti-target:before {\n  content: \"\\e607\";\n}\n.ti-tag:before {\n  content: \"\\e608\";\n}\n.ti-tablet:before {\n  content: \"\\e609\";\n}\n.ti-star:before {\n  content: \"\\e60a\";\n}\n.ti-spray:before {\n  content: \"\\e60b\";\n}\n.ti-signal:before {\n  content: \"\\e60c\";\n}\n.ti-shopping-cart:before {\n  content: \"\\e60d\";\n}\n.ti-shopping-cart-full:before {\n  content: \"\\e60e\";\n}\n.ti-settings:before {\n  content: \"\\e60f\";\n}\n.ti-search:before {\n  content: \"\\e610\";\n}\n.ti-zoom-in:before {\n  content: \"\\e611\";\n}\n.ti-zoom-out:before {\n  content: \"\\e612\";\n}\n.ti-cut:before {\n  content: \"\\e613\";\n}\n.ti-ruler:before {\n  content: \"\\e614\";\n}\n.ti-ruler-pencil:before {\n  content: \"\\e615\";\n}\n.ti-ruler-alt:before {\n  content: \"\\e616\";\n}\n.ti-bookmark:before {\n  content: \"\\e617\";\n}\n.ti-bookmark-alt:before {\n  content: \"\\e618\";\n}\n.ti-reload:before {\n  content: \"\\e619\";\n}\n.ti-plus:before {\n  content: \"\\e61a\";\n}\n.ti-pin:before {\n  content: \"\\e61b\";\n}\n.ti-pencil:before {\n  content: \"\\e61c\";\n}\n.ti-pencil-alt:before {\n  content: \"\\e61d\";\n}\n.ti-paint-roller:before {\n  content: \"\\e61e\";\n}\n.ti-paint-bucket:before {\n  content: \"\\e61f\";\n}\n.ti-na:before {\n  content: \"\\e620\";\n}\n.ti-mobile:before {\n  content: \"\\e621\";\n}\n.ti-minus:before {\n  content: \"\\e622\";\n}\n.ti-medall:before {\n  content: \"\\e623\";\n}\n.ti-medall-alt:before {\n  content: \"\\e624\";\n}\n.ti-marker:before {\n  content: \"\\e625\";\n}\n.ti-marker-alt:before {\n  content: \"\\e626\";\n}\n.ti-arrow-up:before {\n  content: \"\\e627\";\n}\n.ti-arrow-right:before {\n  content: \"\\e628\";\n}\n.ti-arrow-left:before {\n  content: \"\\e629\";\n}\n.ti-arrow-down:before {\n  content: \"\\e62a\";\n}\n.ti-lock:before {\n  content: \"\\e62b\";\n}\n.ti-location-arrow:before {\n  content: \"\\e62c\";\n}\n.ti-link:before {\n  content: \"\\e62d\";\n}\n.ti-layout:before {\n  content: \"\\e62e\";\n}\n.ti-layers:before {\n  content: \"\\e62f\";\n}\n.ti-layers-alt:before {\n  content: \"\\e630\";\n}\n.ti-key:before {\n  content: \"\\e631\";\n}\n.ti-import:before {\n  content: \"\\e632\";\n}\n.ti-image:before {\n  content: \"\\e633\";\n}\n.ti-heart:before {\n  content: \"\\e634\";\n}\n.ti-heart-broken:before {\n  content: \"\\e635\";\n}\n.ti-hand-stop:before {\n  content: \"\\e636\";\n}\n.ti-hand-open:before {\n  content: \"\\e637\";\n}\n.ti-hand-drag:before {\n  content: \"\\e638\";\n}\n.ti-folder:before {\n  content: \"\\e639\";\n}\n.ti-flag:before {\n  content: \"\\e63a\";\n}\n.ti-flag-alt:before {\n  content: \"\\e63b\";\n}\n.ti-flag-alt-2:before {\n  content: \"\\e63c\";\n}\n.ti-eye:before {\n  content: \"\\e63d\";\n}\n.ti-export:before {\n  content: \"\\e63e\";\n}\n.ti-exchange-vertical:before {\n  content: \"\\e63f\";\n}\n.ti-desktop:before {\n  content: \"\\e640\";\n}\n.ti-cup:before {\n  content: \"\\e641\";\n}\n.ti-crown:before {\n  content: \"\\e642\";\n}\n.ti-comments:before {\n  content: \"\\e643\";\n}\n.ti-comment:before {\n  content: \"\\e644\";\n}\n.ti-comment-alt:before {\n  content: \"\\e645\";\n}\n.ti-close:before {\n  content: \"\\e646\";\n}\n.ti-clip:before {\n  content: \"\\e647\";\n}\n.ti-angle-up:before {\n  content: \"\\e648\";\n}\n.ti-angle-right:before {\n  content: \"\\e649\";\n}\n.ti-angle-left:before {\n  content: \"\\e64a\";\n}\n.ti-angle-down:before {\n  content: \"\\e64b\";\n}\n.ti-check:before {\n  content: \"\\e64c\";\n}\n.ti-check-box:before {\n  content: \"\\e64d\";\n}\n.ti-camera:before {\n  content: \"\\e64e\";\n}\n.ti-announcement:before {\n  content: \"\\e64f\";\n}\n.ti-brush:before {\n  content: \"\\e650\";\n}\n.ti-briefcase:before {\n  content: \"\\e651\";\n}\n.ti-bolt:before {\n  content: \"\\e652\";\n}\n.ti-bolt-alt:before {\n  content: \"\\e653\";\n}\n.ti-blackboard:before {\n  content: \"\\e654\";\n}\n.ti-bag:before {\n  content: \"\\e655\";\n}\n.ti-move:before {\n  content: \"\\e656\";\n}\n.ti-arrows-vertical:before {\n  content: \"\\e657\";\n}\n.ti-arrows-horizontal:before {\n  content: \"\\e658\";\n}\n.ti-fullscreen:before {\n  content: \"\\e659\";\n}\n.ti-arrow-top-right:before {\n  content: \"\\e65a\";\n}\n.ti-arrow-top-left:before {\n  content: \"\\e65b\";\n}\n.ti-arrow-circle-up:before {\n  content: \"\\e65c\";\n}\n.ti-arrow-circle-right:before {\n  content: \"\\e65d\";\n}\n.ti-arrow-circle-left:before {\n  content: \"\\e65e\";\n}\n.ti-arrow-circle-down:before {\n  content: \"\\e65f\";\n}\n.ti-angle-double-up:before {\n  content: \"\\e660\";\n}\n.ti-angle-double-right:before {\n  content: \"\\e661\";\n}\n.ti-angle-double-left:before {\n  content: \"\\e662\";\n}\n.ti-angle-double-down:before {\n  content: \"\\e663\";\n}\n.ti-zip:before {\n  content: \"\\e664\";\n}\n.ti-world:before {\n  content: \"\\e665\";\n}\n.ti-wheelchair:before {\n  content: \"\\e666\";\n}\n.ti-view-list:before {\n  content: \"\\e667\";\n}\n.ti-view-list-alt:before {\n  content: \"\\e668\";\n}\n.ti-view-grid:before {\n  content: \"\\e669\";\n}\n.ti-uppercase:before {\n  content: \"\\e66a\";\n}\n.ti-upload:before {\n  content: \"\\e66b\";\n}\n.ti-underline:before {\n  content: \"\\e66c\";\n}\n.ti-truck:before {\n  content: \"\\e66d\";\n}\n.ti-timer:before {\n  content: \"\\e66e\";\n}\n.ti-ticket:before {\n  content: \"\\e66f\";\n}\n.ti-thumb-up:before {\n  content: \"\\e670\";\n}\n.ti-thumb-down:before {\n  content: \"\\e671\";\n}\n.ti-text:before {\n  content: \"\\e672\";\n}\n.ti-stats-up:before {\n  content: \"\\e673\";\n}\n.ti-stats-down:before {\n  content: \"\\e674\";\n}\n.ti-split-v:before {\n  content: \"\\e675\";\n}\n.ti-split-h:before {\n  content: \"\\e676\";\n}\n.ti-smallcap:before {\n  content: \"\\e677\";\n}\n.ti-shine:before {\n  content: \"\\e678\";\n}\n.ti-shift-right:before {\n  content: \"\\e679\";\n}\n.ti-shift-left:before {\n  content: \"\\e67a\";\n}\n.ti-shield:before {\n  content: \"\\e67b\";\n}\n.ti-notepad:before {\n  content: \"\\e67c\";\n}\n.ti-server:before {\n  content: \"\\e67d\";\n}\n.ti-quote-right:before {\n  content: \"\\e67e\";\n}\n.ti-quote-left:before {\n  content: \"\\e67f\";\n}\n.ti-pulse:before {\n  content: \"\\e680\";\n}\n.ti-printer:before {\n  content: \"\\e681\";\n}\n.ti-power-off:before {\n  content: \"\\e682\";\n}\n.ti-plug:before {\n  content: \"\\e683\";\n}\n.ti-pie-chart:before {\n  content: \"\\e684\";\n}\n.ti-paragraph:before {\n  content: \"\\e685\";\n}\n.ti-panel:before {\n  content: \"\\e686\";\n}\n.ti-package:before {\n  content: \"\\e687\";\n}\n.ti-music:before {\n  content: \"\\e688\";\n}\n.ti-music-alt:before {\n  content: \"\\e689\";\n}\n.ti-mouse:before {\n  content: \"\\e68a\";\n}\n.ti-mouse-alt:before {\n  content: \"\\e68b\";\n}\n.ti-money:before {\n  content: \"\\e68c\";\n}\n.ti-microphone:before {\n  content: \"\\e68d\";\n}\n.ti-menu:before {\n  content: \"\\e68e\";\n}\n.ti-menu-alt:before {\n  content: \"\\e68f\";\n}\n.ti-map:before {\n  content: \"\\e690\";\n}\n.ti-map-alt:before {\n  content: \"\\e691\";\n}\n.ti-loop:before {\n  content: \"\\e692\";\n}\n.ti-location-pin:before {\n  content: \"\\e693\";\n}\n.ti-list:before {\n  content: \"\\e694\";\n}\n.ti-light-bulb:before {\n  content: \"\\e695\";\n}\n.ti-Italic:before {\n  content: \"\\e696\";\n}\n.ti-info:before {\n  content: \"\\e697\";\n}\n.ti-infinite:before {\n  content: \"\\e698\";\n}\n.ti-id-badge:before {\n  content: \"\\e699\";\n}\n.ti-hummer:before {\n  content: \"\\e69a\";\n}\n.ti-home:before {\n  content: \"\\e69b\";\n}\n.ti-help:before {\n  content: \"\\e69c\";\n}\n.ti-headphone:before {\n  content: \"\\e69d\";\n}\n.ti-harddrives:before {\n  content: \"\\e69e\";\n}\n.ti-harddrive:before {\n  content: \"\\e69f\";\n}\n.ti-gift:before {\n  content: \"\\e6a0\";\n}\n.ti-game:before {\n  content: \"\\e6a1\";\n}\n.ti-filter:before {\n  content: \"\\e6a2\";\n}\n.ti-files:before {\n  content: \"\\e6a3\";\n}\n.ti-file:before {\n  content: \"\\e6a4\";\n}\n.ti-eraser:before {\n  content: \"\\e6a5\";\n}\n.ti-envelope:before {\n  content: \"\\e6a6\";\n}\n.ti-download:before {\n  content: \"\\e6a7\";\n}\n.ti-direction:before {\n  content: \"\\e6a8\";\n}\n.ti-direction-alt:before {\n  content: \"\\e6a9\";\n}\n.ti-dashboard:before {\n  content: \"\\e6aa\";\n}\n.ti-control-stop:before {\n  content: \"\\e6ab\";\n}\n.ti-control-shuffle:before {\n  content: \"\\e6ac\";\n}\n.ti-control-play:before {\n  content: \"\\e6ad\";\n}\n.ti-control-pause:before {\n  content: \"\\e6ae\";\n}\n.ti-control-forward:before {\n  content: \"\\e6af\";\n}\n.ti-control-backward:before {\n  content: \"\\e6b0\";\n}\n.ti-cloud:before {\n  content: \"\\e6b1\";\n}\n.ti-cloud-up:before {\n  content: \"\\e6b2\";\n}\n.ti-cloud-down:before {\n  content: \"\\e6b3\";\n}\n.ti-clipboard:before {\n  content: \"\\e6b4\";\n}\n.ti-car:before {\n  content: \"\\e6b5\";\n}\n.ti-calendar:before {\n  content: \"\\e6b6\";\n}\n.ti-book:before {\n  content: \"\\e6b7\";\n}\n.ti-bell:before {\n  content: \"\\e6b8\";\n}\n.ti-basketball:before {\n  content: \"\\e6b9\";\n}\n.ti-bar-chart:before {\n  content: \"\\e6ba\";\n}\n.ti-bar-chart-alt:before {\n  content: \"\\e6bb\";\n}\n.ti-back-right:before {\n  content: \"\\e6bc\";\n}\n.ti-back-left:before {\n  content: \"\\e6bd\";\n}\n.ti-arrows-corner:before {\n  content: \"\\e6be\";\n}\n.ti-archive:before {\n  content: \"\\e6bf\";\n}\n.ti-anchor:before {\n  content: \"\\e6c0\";\n}\n.ti-align-right:before {\n  content: \"\\e6c1\";\n}\n.ti-align-left:before {\n  content: \"\\e6c2\";\n}\n.ti-align-justify:before {\n  content: \"\\e6c3\";\n}\n.ti-align-center:before {\n  content: \"\\e6c4\";\n}\n.ti-alert:before {\n  content: \"\\e6c5\";\n}\n.ti-alarm-clock:before {\n  content: \"\\e6c6\";\n}\n.ti-agenda:before {\n  content: \"\\e6c7\";\n}\n.ti-write:before {\n  content: \"\\e6c8\";\n}\n.ti-window:before {\n  content: \"\\e6c9\";\n}\n.ti-widgetized:before {\n  content: \"\\e6ca\";\n}\n.ti-widget:before {\n  content: \"\\e6cb\";\n}\n.ti-widget-alt:before {\n  content: \"\\e6cc\";\n}\n.ti-wallet:before {\n  content: \"\\e6cd\";\n}\n.ti-video-clapper:before {\n  content: \"\\e6ce\";\n}\n.ti-video-camera:before {\n  content: \"\\e6cf\";\n}\n.ti-vector:before {\n  content: \"\\e6d0\";\n}\n.ti-themify-logo:before {\n  content: \"\\e6d1\";\n}\n.ti-themify-favicon:before {\n  content: \"\\e6d2\";\n}\n.ti-themify-favicon-alt:before {\n  content: \"\\e6d3\";\n}\n.ti-support:before {\n  content: \"\\e6d4\";\n}\n.ti-stamp:before {\n  content: \"\\e6d5\";\n}\n.ti-split-v-alt:before {\n  content: \"\\e6d6\";\n}\n.ti-slice:before {\n  content: \"\\e6d7\";\n}\n.ti-shortcode:before {\n  content: \"\\e6d8\";\n}\n.ti-shift-right-alt:before {\n  content: \"\\e6d9\";\n}\n.ti-shift-left-alt:before {\n  content: \"\\e6da\";\n}\n.ti-ruler-alt-2:before {\n  content: \"\\e6db\";\n}\n.ti-receipt:before {\n  content: \"\\e6dc\";\n}\n.ti-pin2:before {\n  content: \"\\e6dd\";\n}\n.ti-pin-alt:before {\n  content: \"\\e6de\";\n}\n.ti-pencil-alt2:before {\n  content: \"\\e6df\";\n}\n.ti-palette:before {\n  content: \"\\e6e0\";\n}\n.ti-more:before {\n  content: \"\\e6e1\";\n}\n.ti-more-alt:before {\n  content: \"\\e6e2\";\n}\n.ti-microphone-alt:before {\n  content: \"\\e6e3\";\n}\n.ti-magnet:before {\n  content: \"\\e6e4\";\n}\n.ti-line-double:before {\n  content: \"\\e6e5\";\n}\n.ti-line-dotted:before {\n  content: \"\\e6e6\";\n}\n.ti-line-dashed:before {\n  content: \"\\e6e7\";\n}\n.ti-layout-width-full:before {\n  content: \"\\e6e8\";\n}\n.ti-layout-width-default:before {\n  content: \"\\e6e9\";\n}\n.ti-layout-width-default-alt:before {\n  content: \"\\e6ea\";\n}\n.ti-layout-tab:before {\n  content: \"\\e6eb\";\n}\n.ti-layout-tab-window:before {\n  content: \"\\e6ec\";\n}\n.ti-layout-tab-v:before {\n  content: \"\\e6ed\";\n}\n.ti-layout-tab-min:before {\n  content: \"\\e6ee\";\n}\n.ti-layout-slider:before {\n  content: \"\\e6ef\";\n}\n.ti-layout-slider-alt:before {\n  content: \"\\e6f0\";\n}\n.ti-layout-sidebar-right:before {\n  content: \"\\e6f1\";\n}\n.ti-layout-sidebar-none:before {\n  content: \"\\e6f2\";\n}\n.ti-layout-sidebar-left:before {\n  content: \"\\e6f3\";\n}\n.ti-layout-placeholder:before {\n  content: \"\\e6f4\";\n}\n.ti-layout-menu:before {\n  content: \"\\e6f5\";\n}\n.ti-layout-menu-v:before {\n  content: \"\\e6f6\";\n}\n.ti-layout-menu-separated:before {\n  content: \"\\e6f7\";\n}\n.ti-layout-menu-full:before {\n  content: \"\\e6f8\";\n}\n.ti-layout-media-right-alt:before {\n  content: \"\\e6f9\";\n}\n.ti-layout-media-right:before {\n  content: \"\\e6fa\";\n}\n.ti-layout-media-overlay:before {\n  content: \"\\e6fb\";\n}\n.ti-layout-media-overlay-alt:before {\n  content: \"\\e6fc\";\n}\n.ti-layout-media-overlay-alt-2:before {\n  content: \"\\e6fd\";\n}\n.ti-layout-media-left-alt:before {\n  content: \"\\e6fe\";\n}\n.ti-layout-media-left:before {\n  content: \"\\e6ff\";\n}\n.ti-layout-media-center-alt:before {\n  content: \"\\e700\";\n}\n.ti-layout-media-center:before {\n  content: \"\\e701\";\n}\n.ti-layout-list-thumb:before {\n  content: \"\\e702\";\n}\n.ti-layout-list-thumb-alt:before {\n  content: \"\\e703\";\n}\n.ti-layout-list-post:before {\n  content: \"\\e704\";\n}\n.ti-layout-list-large-image:before {\n  content: \"\\e705\";\n}\n.ti-layout-line-solid:before {\n  content: \"\\e706\";\n}\n.ti-layout-grid4:before {\n  content: \"\\e707\";\n}\n.ti-layout-grid3:before {\n  content: \"\\e708\";\n}\n.ti-layout-grid2:before {\n  content: \"\\e709\";\n}\n.ti-layout-grid2-thumb:before {\n  content: \"\\e70a\";\n}\n.ti-layout-cta-right:before {\n  content: \"\\e70b\";\n}\n.ti-layout-cta-left:before {\n  content: \"\\e70c\";\n}\n.ti-layout-cta-center:before {\n  content: \"\\e70d\";\n}\n.ti-layout-cta-btn-right:before {\n  content: \"\\e70e\";\n}\n.ti-layout-cta-btn-left:before {\n  content: \"\\e70f\";\n}\n.ti-layout-column4:before {\n  content: \"\\e710\";\n}\n.ti-layout-column3:before {\n  content: \"\\e711\";\n}\n.ti-layout-column2:before {\n  content: \"\\e712\";\n}\n.ti-layout-accordion-separated:before {\n  content: \"\\e713\";\n}\n.ti-layout-accordion-merged:before {\n  content: \"\\e714\";\n}\n.ti-layout-accordion-list:before {\n  content: \"\\e715\";\n}\n.ti-ink-pen:before {\n  content: \"\\e716\";\n}\n.ti-info-alt:before {\n  content: \"\\e717\";\n}\n.ti-help-alt:before {\n  content: \"\\e718\";\n}\n.ti-headphone-alt:before {\n  content: \"\\e719\";\n}\n.ti-hand-point-up:before {\n  content: \"\\e71a\";\n}\n.ti-hand-point-right:before {\n  content: \"\\e71b\";\n}\n.ti-hand-point-left:before {\n  content: \"\\e71c\";\n}\n.ti-hand-point-down:before {\n  content: \"\\e71d\";\n}\n.ti-gallery:before {\n  content: \"\\e71e\";\n}\n.ti-face-smile:before {\n  content: \"\\e71f\";\n}\n.ti-face-sad:before {\n  content: \"\\e720\";\n}\n.ti-credit-card:before {\n  content: \"\\e721\";\n}\n.ti-control-skip-forward:before {\n  content: \"\\e722\";\n}\n.ti-control-skip-backward:before {\n  content: \"\\e723\";\n}\n.ti-control-record:before {\n  content: \"\\e724\";\n}\n.ti-control-eject:before {\n  content: \"\\e725\";\n}\n.ti-comments-smiley:before {\n  content: \"\\e726\";\n}\n.ti-brush-alt:before {\n  content: \"\\e727\";\n}\n.ti-youtube:before {\n  content: \"\\e728\";\n}\n.ti-vimeo:before {\n  content: \"\\e729\";\n}\n.ti-twitter:before {\n  content: \"\\e72a\";\n}\n.ti-time:before {\n  content: \"\\e72b\";\n}\n.ti-tumblr:before {\n  content: \"\\e72c\";\n}\n.ti-skype:before {\n  content: \"\\e72d\";\n}\n.ti-share:before {\n  content: \"\\e72e\";\n}\n.ti-share-alt:before {\n  content: \"\\e72f\";\n}\n.ti-rocket:before {\n  content: \"\\e730\";\n}\n.ti-pinterest:before {\n  content: \"\\e731\";\n}\n.ti-new-window:before {\n  content: \"\\e732\";\n}\n.ti-microsoft:before {\n  content: \"\\e733\";\n}\n.ti-list-ol:before {\n  content: \"\\e734\";\n}\n.ti-linkedin:before {\n  content: \"\\e735\";\n}\n.ti-layout-sidebar-2:before {\n  content: \"\\e736\";\n}\n.ti-layout-grid4-alt:before {\n  content: \"\\e737\";\n}\n.ti-layout-grid3-alt:before {\n  content: \"\\e738\";\n}\n.ti-layout-grid2-alt:before {\n  content: \"\\e739\";\n}\n.ti-layout-column4-alt:before {\n  content: \"\\e73a\";\n}\n.ti-layout-column3-alt:before {\n  content: \"\\e73b\";\n}\n.ti-layout-column2-alt:before {\n  content: \"\\e73c\";\n}\n.ti-instagram:before {\n  content: \"\\e73d\";\n}\n.ti-google:before {\n  content: \"\\e73e\";\n}\n.ti-github:before {\n  content: \"\\e73f\";\n}\n.ti-flickr:before {\n  content: \"\\e740\";\n}\n.ti-facebook:before {\n  content: \"\\e741\";\n}\n.ti-dropbox:before {\n  content: \"\\e742\";\n}\n.ti-dribbble:before {\n  content: \"\\e743\";\n}\n.ti-apple:before {\n  content: \"\\e744\";\n}\n.ti-android:before {\n  content: \"\\e745\";\n}\n.ti-save:before {\n  content: \"\\e746\";\n}\n.ti-save-alt:before {\n  content: \"\\e747\";\n}\n.ti-yahoo:before {\n  content: \"\\e748\";\n}\n.ti-wordpress:before {\n  content: \"\\e749\";\n}\n.ti-vimeo-alt:before {\n  content: \"\\e74a\";\n}\n.ti-twitter-alt:before {\n  content: \"\\e74b\";\n}\n.ti-tumblr-alt:before {\n  content: \"\\e74c\";\n}\n.ti-trello:before {\n  content: \"\\e74d\";\n}\n.ti-stack-overflow:before {\n  content: \"\\e74e\";\n}\n.ti-soundcloud:before {\n  content: \"\\e74f\";\n}\n.ti-sharethis:before {\n  content: \"\\e750\";\n}\n.ti-sharethis-alt:before {\n  content: \"\\e751\";\n}\n.ti-reddit:before {\n  content: \"\\e752\";\n}\n.ti-pinterest-alt:before {\n  content: \"\\e753\";\n}\n.ti-microsoft-alt:before {\n  content: \"\\e754\";\n}\n.ti-linux:before {\n  content: \"\\e755\";\n}\n.ti-jsfiddle:before {\n  content: \"\\e756\";\n}\n.ti-joomla:before {\n  content: \"\\e757\";\n}\n.ti-html5:before {\n  content: \"\\e758\";\n}\n.ti-flickr-alt:before {\n  content: \"\\e759\";\n}\n.ti-email:before {\n  content: \"\\e75a\";\n}\n.ti-drupal:before {\n  content: \"\\e75b\";\n}\n.ti-dropbox-alt:before {\n  content: \"\\e75c\";\n}\n.ti-css3:before {\n  content: \"\\e75d\";\n}\n.ti-rss:before {\n  content: \"\\e75e\";\n}\n.ti-rss-alt:before {\n  content: \"\\e75f\";\n}\n/*!\n *  Material Design Iconic Font 1.0.1 by Sergey Kupletsky (@zavoloklom) - http://zavoloklom.github.io/material-design-iconic-font/\n *  License - https://github.com/zavoloklom/material-design-iconic-font/blob/gh-pages/License.md (Attribution-ShareAlike 4.0 International license)\n */\n@font-face {\n  font-family: 'Material Design Iconic Font';\n  src: url('../fonts/Material-Design-Iconic-Font.eot?v=1.0.1');\n  src: url('../fonts/Material-Design-Iconic-Font.eot?#iefix&v=1.0.1') format('embedded-opentype'), url('../fonts/Material-Design-Iconic-Font.woff?v=1.0.1') format('woff'), url('../fonts/Material-Design-Iconic-Font.ttf?v=1.0.1') format('truetype'), url('../fonts/Material-Design-Iconic-Font.svg?v=1.0.1#Material-Design-Iconic-Font') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n[class^=\"md-\"],\n[class*=\" md-\"] {\n  display: inline-block;\n  font: normal normal normal 14px/1 'Material Design Iconic Font';\n  font-size: inherit;\n  speak: none;\n  text-rendering: auto;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.md {\n  line-height: inherit;\n  vertical-align: bottom;\n}\n.md-lg {\n  font-size: 1.5em;\n  line-height: .5em;\n  vertical-align: -35%;\n}\n.md-2x {\n  font-size: 2em;\n}\n.md-3x {\n  font-size: 3em;\n}\n.md-4x {\n  font-size: 4em;\n}\n.md-5x {\n  font-size: 5em;\n}\n.md-border {\n  padding: .2em .25em .15em;\n  border: solid 0.08em grey;\n  border-radius: .1em;\n}\n.md-border-circle {\n  padding: .2em .25em .15em;\n  border: solid 0.08em grey;\n  border-radius: 50%;\n}\n[class^=\"md-\"].pull-left,\n[class*=\" md-\"].pull-left {\n  float: left;\n  margin-right: .3em;\n}\n[class^=\"md-\"].pull-right,\n[class*=\" md-\"].pull-right {\n  float: right;\n  margin-left: .3em;\n}\n.md-spin {\n  -webkit-animation: md-spin 1.5s infinite linear;\n  animation: md-spin 1.5s infinite linear;\n}\n.md-spin-reverse {\n  -webkit-animation: md-spin-reverse 1.5s infinite linear;\n  animation: md-spin-reverse 1.5s infinite linear;\n}\n@-webkit-keyframes md-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@keyframes md-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@-webkit-keyframes md-spin-reverse {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(-359deg);\n    transform: rotate(-359deg);\n  }\n}\n@keyframes md-spin-reverse {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(-359deg);\n    transform: rotate(-359deg);\n  }\n}\n.md-rotate-90 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n  -webkit-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n.md-rotate-180 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n  -webkit-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n.md-rotate-270 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n  -webkit-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n.md-flip-horizontal {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);\n  -webkit-transform: scale(-1, 1);\n  -ms-transform: scale(-1, 1);\n  transform: scale(-1, 1);\n}\n.md-flip-vertical {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n  -webkit-transform: scale(1, -1);\n  -ms-transform: scale(1, -1);\n  transform: scale(1, -1);\n}\n:root .md-rotate-90,\n:root .md-rotate-180,\n:root .md-rotate-270,\n:root .md-flip-horizontal,\n:root .md-flip-vertical {\n  filter: none;\n}\n/* Material Design Iconic Font uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n/* If you do not want use all icons you can disable icon set here */\n.md-3d-rotation:before {\n  content: \"\\f000\";\n}\n.md-accessibility:before {\n  content: \"\\f001\";\n}\n.md-account-balance:before {\n  content: \"\\f002\";\n}\n.md-account-balance-wallet:before {\n  content: \"\\f003\";\n}\n.md-account-box:before {\n  content: \"\\f004\";\n}\n.md-account-child:before {\n  content: \"\\f005\";\n}\n.md-account-circle:before {\n  content: \"\\f006\";\n}\n.md-add-shopping-cart:before {\n  content: \"\\f007\";\n}\n.md-alarm:before {\n  content: \"\\f008\";\n}\n.md-alarm-add:before {\n  content: \"\\f009\";\n}\n.md-alarm-off:before {\n  content: \"\\f00a\";\n}\n.md-alarm-on:before {\n  content: \"\\f00b\";\n}\n.md-android:before {\n  content: \"\\f00c\";\n}\n.md-announcement:before {\n  content: \"\\f00d\";\n}\n.md-aspect-ratio:before {\n  content: \"\\f00e\";\n}\n.md-assessment:before {\n  content: \"\\f00f\";\n}\n.md-assignment:before {\n  content: \"\\f010\";\n}\n.md-assignment-ind:before {\n  content: \"\\f011\";\n}\n.md-assignment-late:before {\n  content: \"\\f012\";\n}\n.md-assignment-return:before {\n  content: \"\\f013\";\n}\n.md-assignment-returned:before {\n  content: \"\\f014\";\n}\n.md-assignment-turned-in:before {\n  content: \"\\f015\";\n}\n.md-autorenew:before {\n  content: \"\\f016\";\n}\n.md-backup:before {\n  content: \"\\f017\";\n}\n.md-book:before {\n  content: \"\\f018\";\n}\n.md-bookmark:before {\n  content: \"\\f019\";\n}\n.md-bookmark-outline:before {\n  content: \"\\f01a\";\n}\n.md-bug-report:before {\n  content: \"\\f01b\";\n}\n.md-cached:before {\n  content: \"\\f01c\";\n}\n.md-class:before {\n  content: \"\\f01d\";\n}\n.md-credit-card:before {\n  content: \"\\f01e\";\n}\n.md-dashboard:before {\n  content: \"\\f01f\";\n}\n.md-delete:before {\n  content: \"\\f020\";\n}\n.md-description:before {\n  content: \"\\f021\";\n}\n.md-dns:before {\n  content: \"\\f022\";\n}\n.md-done:before {\n  content: \"\\f023\";\n}\n.md-done-all:before {\n  content: \"\\f024\";\n}\n.md-event:before {\n  content: \"\\f025\";\n}\n.md-exit-to-app:before {\n  content: \"\\f026\";\n}\n.md-explore:before {\n  content: \"\\f027\";\n}\n.md-extension:before {\n  content: \"\\f028\";\n}\n.md-face-unlock:before {\n  content: \"\\f029\";\n}\n.md-favorite:before {\n  content: \"\\f02a\";\n}\n.md-favorite-outline:before {\n  content: \"\\f02b\";\n}\n.md-find-in-page:before {\n  content: \"\\f02c\";\n}\n.md-find-replace:before {\n  content: \"\\f02d\";\n}\n.md-flip-to-back:before {\n  content: \"\\f02e\";\n}\n.md-flip-to-front:before {\n  content: \"\\f02f\";\n}\n.md-get-app:before {\n  content: \"\\f030\";\n}\n.md-grade:before {\n  content: \"\\f031\";\n}\n.md-group-work:before {\n  content: \"\\f032\";\n}\n.md-help:before {\n  content: \"\\f033\";\n}\n.md-highlight-remove:before {\n  content: \"\\f034\";\n}\n.md-history:before {\n  content: \"\\f035\";\n}\n.md-home:before {\n  content: \"\\f036\";\n}\n.md-https:before {\n  content: \"\\f037\";\n}\n.md-info:before {\n  content: \"\\f038\";\n}\n.md-info-outline:before {\n  content: \"\\f039\";\n}\n.md-input:before {\n  content: \"\\f03a\";\n}\n.md-invert-colors:before {\n  content: \"\\f03b\";\n}\n.md-label:before {\n  content: \"\\f03c\";\n}\n.md-label-outline:before {\n  content: \"\\f03d\";\n}\n.md-language:before {\n  content: \"\\f03e\";\n}\n.md-launch:before {\n  content: \"\\f03f\";\n}\n.md-list:before {\n  content: \"\\f040\";\n}\n.md-lock:before {\n  content: \"\\f041\";\n}\n.md-lock-open:before {\n  content: \"\\f042\";\n}\n.md-lock-outline:before {\n  content: \"\\f043\";\n}\n.md-loyalty:before {\n  content: \"\\f044\";\n}\n.md-markunread-mailbox:before {\n  content: \"\\f045\";\n}\n.md-note-add:before {\n  content: \"\\f046\";\n}\n.md-open-in-browser:before {\n  content: \"\\f047\";\n}\n.md-open-in-new:before {\n  content: \"\\f048\";\n}\n.md-open-with:before {\n  content: \"\\f049\";\n}\n.md-pageview:before {\n  content: \"\\f04a\";\n}\n.md-payment:before {\n  content: \"\\f04b\";\n}\n.md-perm-camera-mic:before {\n  content: \"\\f04c\";\n}\n.md-perm-contact-cal:before {\n  content: \"\\f04d\";\n}\n.md-perm-data-setting:before {\n  content: \"\\f04e\";\n}\n.md-perm-device-info:before {\n  content: \"\\f04f\";\n}\n.md-perm-identity:before {\n  content: \"\\f050\";\n}\n.md-perm-media:before {\n  content: \"\\f051\";\n}\n.md-perm-phone-msg:before {\n  content: \"\\f052\";\n}\n.md-perm-scan-wifi:before {\n  content: \"\\f053\";\n}\n.md-picture-in-picture:before {\n  content: \"\\f054\";\n}\n.md-polymer:before {\n  content: \"\\f055\";\n}\n.md-print:before {\n  content: \"\\f056\";\n}\n.md-query-builder:before {\n  content: \"\\f057\";\n}\n.md-question-answer:before {\n  content: \"\\f058\";\n}\n.md-receipt:before {\n  content: \"\\f059\";\n}\n.md-redeem:before {\n  content: \"\\f05a\";\n}\n.md-report-problem:before {\n  content: \"\\f05b\";\n}\n.md-restore:before {\n  content: \"\\f05c\";\n}\n.md-room:before {\n  content: \"\\f05d\";\n}\n.md-schedule:before {\n  content: \"\\f05e\";\n}\n.md-search:before {\n  content: \"\\f05f\";\n}\n.md-settings:before {\n  content: \"\\f060\";\n}\n.md-settings-applications:before {\n  content: \"\\f061\";\n}\n.md-settings-backup-restore:before {\n  content: \"\\f062\";\n}\n.md-settings-bluetooth:before {\n  content: \"\\f063\";\n}\n.md-settings-cell:before {\n  content: \"\\f064\";\n}\n.md-settings-display:before {\n  content: \"\\f065\";\n}\n.md-settings-ethernet:before {\n  content: \"\\f066\";\n}\n.md-settings-input-antenna:before {\n  content: \"\\f067\";\n}\n.md-settings-input-component:before {\n  content: \"\\f068\";\n}\n.md-settings-input-composite:before {\n  content: \"\\f069\";\n}\n.md-settings-input-hdmi:before {\n  content: \"\\f06a\";\n}\n.md-settings-input-svideo:before {\n  content: \"\\f06b\";\n}\n.md-settings-overscan:before {\n  content: \"\\f06c\";\n}\n.md-settings-phone:before {\n  content: \"\\f06d\";\n}\n.md-settings-power:before {\n  content: \"\\f06e\";\n}\n.md-settings-remote:before {\n  content: \"\\f06f\";\n}\n.md-settings-voice:before {\n  content: \"\\f070\";\n}\n.md-shop:before {\n  content: \"\\f071\";\n}\n.md-shopping-basket:before {\n  content: \"\\f072\";\n}\n.md-shopping-cart:before {\n  content: \"\\f073\";\n}\n.md-shop-two:before {\n  content: \"\\f074\";\n}\n.md-speaker-notes:before {\n  content: \"\\f075\";\n}\n.md-spellcheck:before {\n  content: \"\\f076\";\n}\n.md-star-rate:before {\n  content: \"\\f077\";\n}\n.md-stars:before {\n  content: \"\\f078\";\n}\n.md-store:before {\n  content: \"\\f079\";\n}\n.md-subject:before {\n  content: \"\\f07a\";\n}\n.md-swap-horiz:before {\n  content: \"\\f07b\";\n}\n.md-swap-vert:before {\n  content: \"\\f07c\";\n}\n.md-swap-vert-circle:before {\n  content: \"\\f07d\";\n}\n.md-system-update-tv:before {\n  content: \"\\f07e\";\n}\n.md-tab:before {\n  content: \"\\f07f\";\n}\n.md-tab-unselected:before {\n  content: \"\\f080\";\n}\n.md-theaters:before {\n  content: \"\\f081\";\n}\n.md-thumb-down:before {\n  content: \"\\f082\";\n}\n.md-thumbs-up-down:before {\n  content: \"\\f083\";\n}\n.md-thumb-up:before {\n  content: \"\\f084\";\n}\n.md-toc:before {\n  content: \"\\f085\";\n}\n.md-today:before {\n  content: \"\\f086\";\n}\n.md-track-changes:before {\n  content: \"\\f087\";\n}\n.md-translate:before {\n  content: \"\\f088\";\n}\n.md-trending-down:before {\n  content: \"\\f089\";\n}\n.md-trending-neutral:before {\n  content: \"\\f08a\";\n}\n.md-trending-up:before {\n  content: \"\\f08b\";\n}\n.md-turned-in:before {\n  content: \"\\f08c\";\n}\n.md-turned-in-not:before {\n  content: \"\\f08d\";\n}\n.md-verified-user:before {\n  content: \"\\f08e\";\n}\n.md-view-agenda:before {\n  content: \"\\f08f\";\n}\n.md-view-array:before {\n  content: \"\\f090\";\n}\n.md-view-carousel:before {\n  content: \"\\f091\";\n}\n.md-view-column:before {\n  content: \"\\f092\";\n}\n.md-view-day:before {\n  content: \"\\f093\";\n}\n.md-view-headline:before {\n  content: \"\\f094\";\n}\n.md-view-list:before {\n  content: \"\\f095\";\n}\n.md-view-module:before {\n  content: \"\\f096\";\n}\n.md-view-quilt:before {\n  content: \"\\f097\";\n}\n.md-view-stream:before {\n  content: \"\\f098\";\n}\n.md-view-week:before {\n  content: \"\\f099\";\n}\n.md-visibility:before {\n  content: \"\\f09a\";\n}\n.md-visibility-off:before {\n  content: \"\\f09b\";\n}\n.md-wallet-giftcard:before {\n  content: \"\\f09c\";\n}\n.md-wallet-membership:before {\n  content: \"\\f09d\";\n}\n.md-wallet-travel:before {\n  content: \"\\f09e\";\n}\n.md-work:before {\n  content: \"\\f09f\";\n}\n.md-error:before {\n  content: \"\\f0a0\";\n}\n.md-warning:before {\n  content: \"\\f0a1\";\n}\n.md-album:before {\n  content: \"\\f0a2\";\n}\n.md-av-timer:before {\n  content: \"\\f0a3\";\n}\n.md-closed-caption:before {\n  content: \"\\f0a4\";\n}\n.md-equalizer:before {\n  content: \"\\f0a5\";\n}\n.md-explicit:before {\n  content: \"\\f0a6\";\n}\n.md-fast-forward:before {\n  content: \"\\f0a7\";\n}\n.md-fast-rewind:before {\n  content: \"\\f0a8\";\n}\n.md-games:before {\n  content: \"\\f0a9\";\n}\n.md-hearing:before {\n  content: \"\\f0aa\";\n}\n.md-high-quality:before {\n  content: \"\\f0ab\";\n}\n.md-loop:before {\n  content: \"\\f0ac\";\n}\n.md-mic:before {\n  content: \"\\f0ad\";\n}\n.md-mic-none:before {\n  content: \"\\f0ae\";\n}\n.md-mic-off:before {\n  content: \"\\f0af\";\n}\n.md-movie:before {\n  content: \"\\f0b0\";\n}\n.md-my-library-add:before {\n  content: \"\\f0b1\";\n}\n.md-my-library-books:before {\n  content: \"\\f0b2\";\n}\n.md-my-library-music:before {\n  content: \"\\f0b3\";\n}\n.md-new-releases:before {\n  content: \"\\f0b4\";\n}\n.md-not-interested:before {\n  content: \"\\f0b5\";\n}\n.md-pause:before {\n  content: \"\\f0b6\";\n}\n.md-pause-circle-fill:before {\n  content: \"\\f0b7\";\n}\n.md-pause-circle-outline:before {\n  content: \"\\f0b8\";\n}\n.md-play-arrow:before {\n  content: \"\\f0b9\";\n}\n.md-play-circle-fill:before {\n  content: \"\\f0ba\";\n}\n.md-play-circle-outline:before {\n  content: \"\\f0bb\";\n}\n.md-playlist-add:before {\n  content: \"\\f0bc\";\n}\n.md-play-shopping-bag:before {\n  content: \"\\f0bd\";\n}\n.md-queue:before {\n  content: \"\\f0be\";\n}\n.md-queue-music:before {\n  content: \"\\f0bf\";\n}\n.md-radio:before {\n  content: \"\\f0c0\";\n}\n.md-recent-actors:before {\n  content: \"\\f0c1\";\n}\n.md-repeat:before {\n  content: \"\\f0c2\";\n}\n.md-repeat-one:before {\n  content: \"\\f0c3\";\n}\n.md-replay:before {\n  content: \"\\f0c4\";\n}\n.md-shuffle:before {\n  content: \"\\f0c5\";\n}\n.md-skip-next:before {\n  content: \"\\f0c6\";\n}\n.md-skip-previous:before {\n  content: \"\\f0c7\";\n}\n.md-snooze:before {\n  content: \"\\f0c8\";\n}\n.md-stop:before {\n  content: \"\\f0c9\";\n}\n.md-subtitles:before {\n  content: \"\\f0ca\";\n}\n.md-surround-sound:before {\n  content: \"\\f0cb\";\n}\n.md-videocam:before {\n  content: \"\\f0cc\";\n}\n.md-videocam-off:before {\n  content: \"\\f0cd\";\n}\n.md-video-collection:before {\n  content: \"\\f0ce\";\n}\n.md-volume-down:before {\n  content: \"\\f0cf\";\n}\n.md-volume-mute:before {\n  content: \"\\f0d0\";\n}\n.md-volume-off:before {\n  content: \"\\f0d1\";\n}\n.md-volume-up:before {\n  content: \"\\f0d2\";\n}\n.md-web:before {\n  content: \"\\f0d3\";\n}\n.md-business:before {\n  content: \"\\f0d4\";\n}\n.md-call:before {\n  content: \"\\f0d5\";\n}\n.md-call-end:before {\n  content: \"\\f0d6\";\n}\n.md-call-made:before {\n  content: \"\\f0d7\";\n}\n.md-call-merge:before {\n  content: \"\\f0d8\";\n}\n.md-call-missed:before {\n  content: \"\\f0d9\";\n}\n.md-call-received:before {\n  content: \"\\f0da\";\n}\n.md-call-split:before {\n  content: \"\\f0db\";\n}\n.md-chat:before {\n  content: \"\\f0dc\";\n}\n.md-clear-all:before {\n  content: \"\\f0dd\";\n}\n.md-comment:before {\n  content: \"\\f0de\";\n}\n.md-contacts:before {\n  content: \"\\f0df\";\n}\n.md-dialer-sip:before {\n  content: \"\\f0e0\";\n}\n.md-dialpad:before {\n  content: \"\\f0e1\";\n}\n.md-dnd-on:before {\n  content: \"\\f0e2\";\n}\n.md-email:before {\n  content: \"\\f0e3\";\n}\n.md-forum:before {\n  content: \"\\f0e4\";\n}\n.md-import-export:before {\n  content: \"\\f0e5\";\n}\n.md-invert-colors-off:before {\n  content: \"\\f0e6\";\n}\n.md-invert-colors-on:before {\n  content: \"\\f0e7\";\n}\n.md-live-help:before {\n  content: \"\\f0e8\";\n}\n.md-location-off:before {\n  content: \"\\f0e9\";\n}\n.md-location-on:before {\n  content: \"\\f0ea\";\n}\n.md-message:before {\n  content: \"\\f0eb\";\n}\n.md-messenger:before {\n  content: \"\\f0ec\";\n}\n.md-no-sim:before {\n  content: \"\\f0ed\";\n}\n.md-phone:before {\n  content: \"\\f0ee\";\n}\n.md-portable-wifi-off:before {\n  content: \"\\f0ef\";\n}\n.md-quick-contacts-dialer:before {\n  content: \"\\f0f0\";\n}\n.md-quick-contacts-mail:before {\n  content: \"\\f0f1\";\n}\n.md-ring-volume:before {\n  content: \"\\f0f2\";\n}\n.md-stay-current-landscape:before {\n  content: \"\\f0f3\";\n}\n.md-stay-current-portrait:before {\n  content: \"\\f0f4\";\n}\n.md-stay-primary-landscape:before {\n  content: \"\\f0f5\";\n}\n.md-stay-primary-portrait:before {\n  content: \"\\f0f6\";\n}\n.md-swap-calls:before {\n  content: \"\\f0f7\";\n}\n.md-textsms:before {\n  content: \"\\f0f8\";\n}\n.md-voicemail:before {\n  content: \"\\f0f9\";\n}\n.md-vpn-key:before {\n  content: \"\\f0fa\";\n}\n.md-add:before {\n  content: \"\\f0fb\";\n}\n.md-add-box:before {\n  content: \"\\f0fc\";\n}\n.md-add-circle:before {\n  content: \"\\f0fd\";\n}\n.md-add-circle-outline:before {\n  content: \"\\f0fe\";\n}\n.md-archive:before {\n  content: \"\\f0ff\";\n}\n.md-backspace:before {\n  content: \"\\f100\";\n}\n.md-block:before {\n  content: \"\\f101\";\n}\n.md-clear:before {\n  content: \"\\f102\";\n}\n.md-content-copy:before {\n  content: \"\\f103\";\n}\n.md-content-cut:before {\n  content: \"\\f104\";\n}\n.md-content-paste:before {\n  content: \"\\f105\";\n}\n.md-create:before {\n  content: \"\\f106\";\n}\n.md-drafts:before {\n  content: \"\\f107\";\n}\n.md-filter-list:before {\n  content: \"\\f108\";\n}\n.md-flag:before {\n  content: \"\\f109\";\n}\n.md-forward:before {\n  content: \"\\f10a\";\n}\n.md-gesture:before {\n  content: \"\\f10b\";\n}\n.md-inbox:before {\n  content: \"\\f10c\";\n}\n.md-link:before {\n  content: \"\\f10d\";\n}\n.md-mail:before {\n  content: \"\\f10e\";\n}\n.md-markunread:before {\n  content: \"\\f10f\";\n}\n.md-redo:before {\n  content: \"\\f110\";\n}\n.md-remove:before {\n  content: \"\\f111\";\n}\n.md-remove-circle:before {\n  content: \"\\f112\";\n}\n.md-remove-circle-outline:before {\n  content: \"\\f113\";\n}\n.md-reply:before {\n  content: \"\\f114\";\n}\n.md-reply-all:before {\n  content: \"\\f115\";\n}\n.md-report:before {\n  content: \"\\f116\";\n}\n.md-save:before {\n  content: \"\\f117\";\n}\n.md-select-all:before {\n  content: \"\\f118\";\n}\n.md-send:before {\n  content: \"\\f119\";\n}\n.md-sort:before {\n  content: \"\\f11a\";\n}\n.md-text-format:before {\n  content: \"\\f11b\";\n}\n.md-undo:before {\n  content: \"\\f11c\";\n}\n.md-access-alarm:before {\n  content: \"\\f11d\";\n}\n.md-access-alarms:before {\n  content: \"\\f11e\";\n}\n.md-access-time:before {\n  content: \"\\f11f\";\n}\n.md-add-alarm:before {\n  content: \"\\f120\";\n}\n.md-airplanemode-off:before {\n  content: \"\\f121\";\n}\n.md-airplanemode-on:before {\n  content: \"\\f122\";\n}\n.md-battery-20:before {\n  content: \"\\f123\";\n}\n.md-battery-30:before {\n  content: \"\\f124\";\n}\n.md-battery-50:before {\n  content: \"\\f125\";\n}\n.md-battery-60:before {\n  content: \"\\f126\";\n}\n.md-battery-80:before {\n  content: \"\\f127\";\n}\n.md-battery-90:before {\n  content: \"\\f128\";\n}\n.md-battery-alert:before {\n  content: \"\\f129\";\n}\n.md-battery-charging-20:before {\n  content: \"\\f12a\";\n}\n.md-battery-charging-30:before {\n  content: \"\\f12b\";\n}\n.md-battery-charging-50:before {\n  content: \"\\f12c\";\n}\n.md-battery-charging-60:before {\n  content: \"\\f12d\";\n}\n.md-battery-charging-80:before {\n  content: \"\\f12e\";\n}\n.md-battery-charging-90:before {\n  content: \"\\f12f\";\n}\n.md-battery-charging-full:before {\n  content: \"\\f130\";\n}\n.md-battery-full:before {\n  content: \"\\f131\";\n}\n.md-battery-std:before {\n  content: \"\\f132\";\n}\n.md-battery-unknown:before {\n  content: \"\\f133\";\n}\n.md-bluetooth:before {\n  content: \"\\f134\";\n}\n.md-bluetooth-connected:before {\n  content: \"\\f135\";\n}\n.md-bluetooth-disabled:before {\n  content: \"\\f136\";\n}\n.md-bluetooth-searching:before {\n  content: \"\\f137\";\n}\n.md-brightness-auto:before {\n  content: \"\\f138\";\n}\n.md-brightness-high:before {\n  content: \"\\f139\";\n}\n.md-brightness-low:before {\n  content: \"\\f13a\";\n}\n.md-brightness-medium:before {\n  content: \"\\f13b\";\n}\n.md-data-usage:before {\n  content: \"\\f13c\";\n}\n.md-developer-mode:before {\n  content: \"\\f13d\";\n}\n.md-devices:before {\n  content: \"\\f13e\";\n}\n.md-dvr:before {\n  content: \"\\f13f\";\n}\n.md-gps-fixed:before {\n  content: \"\\f140\";\n}\n.md-gps-not-fixed:before {\n  content: \"\\f141\";\n}\n.md-gps-off:before {\n  content: \"\\f142\";\n}\n.md-location-disabled:before {\n  content: \"\\f143\";\n}\n.md-location-searching:before {\n  content: \"\\f144\";\n}\n.md-multitrack-audio:before {\n  content: \"\\f145\";\n}\n.md-network-cell:before {\n  content: \"\\f146\";\n}\n.md-network-wifi:before {\n  content: \"\\f147\";\n}\n.md-nfc:before {\n  content: \"\\f148\";\n}\n.md-now-wallpaper:before {\n  content: \"\\f149\";\n}\n.md-now-widgets:before {\n  content: \"\\f14a\";\n}\n.md-screen-lock-landscape:before {\n  content: \"\\f14b\";\n}\n.md-screen-lock-portrait:before {\n  content: \"\\f14c\";\n}\n.md-screen-lock-rotation:before {\n  content: \"\\f14d\";\n}\n.md-screen-rotation:before {\n  content: \"\\f14e\";\n}\n.md-sd-storage:before {\n  content: \"\\f14f\";\n}\n.md-settings-system-daydream:before {\n  content: \"\\f150\";\n}\n.md-signal-cellular-0-bar:before {\n  content: \"\\f151\";\n}\n.md-signal-cellular-1-bar:before {\n  content: \"\\f152\";\n}\n.md-signal-cellular-2-bar:before {\n  content: \"\\f153\";\n}\n.md-signal-cellular-3-bar:before {\n  content: \"\\f154\";\n}\n.md-signal-cellular-4-bar:before {\n  content: \"\\f155\";\n}\n.md-signal-cellular-connected-no-internet-0-bar:before {\n  content: \"\\f156\";\n}\n.md-signal-cellular-connected-no-internet-1-bar:before {\n  content: \"\\f157\";\n}\n.md-signal-cellular-connected-no-internet-2-bar:before {\n  content: \"\\f158\";\n}\n.md-signal-cellular-connected-no-internet-3-bar:before {\n  content: \"\\f159\";\n}\n.md-signal-cellular-connected-no-internet-4-bar:before {\n  content: \"\\f15a\";\n}\n.md-signal-cellular-no-sim:before {\n  content: \"\\f15b\";\n}\n.md-signal-cellular-null:before {\n  content: \"\\f15c\";\n}\n.md-signal-cellular-off:before {\n  content: \"\\f15d\";\n}\n.md-signal-wifi-0-bar:before {\n  content: \"\\f15e\";\n}\n.md-signal-wifi-1-bar:before {\n  content: \"\\f15f\";\n}\n.md-signal-wifi-2-bar:before {\n  content: \"\\f160\";\n}\n.md-signal-wifi-3-bar:before {\n  content: \"\\f161\";\n}\n.md-signal-wifi-4-bar:before {\n  content: \"\\f162\";\n}\n.md-signal-wifi-off:before {\n  content: \"\\f163\";\n}\n.md-storage:before {\n  content: \"\\f164\";\n}\n.md-usb:before {\n  content: \"\\f165\";\n}\n.md-wifi-lock:before {\n  content: \"\\f166\";\n}\n.md-wifi-tethering:before {\n  content: \"\\f167\";\n}\n.md-attach-file:before {\n  content: \"\\f168\";\n}\n.md-attach-money:before {\n  content: \"\\f169\";\n}\n.md-border-all:before {\n  content: \"\\f16a\";\n}\n.md-border-bottom:before {\n  content: \"\\f16b\";\n}\n.md-border-clear:before {\n  content: \"\\f16c\";\n}\n.md-border-color:before {\n  content: \"\\f16d\";\n}\n.md-border-horizontal:before {\n  content: \"\\f16e\";\n}\n.md-border-inner:before {\n  content: \"\\f16f\";\n}\n.md-border-left:before {\n  content: \"\\f170\";\n}\n.md-border-outer:before {\n  content: \"\\f171\";\n}\n.md-border-right:before {\n  content: \"\\f172\";\n}\n.md-border-style:before {\n  content: \"\\f173\";\n}\n.md-border-top:before {\n  content: \"\\f174\";\n}\n.md-border-vertical:before {\n  content: \"\\f175\";\n}\n.md-format-align-center:before {\n  content: \"\\f176\";\n}\n.md-format-align-justify:before {\n  content: \"\\f177\";\n}\n.md-format-align-left:before {\n  content: \"\\f178\";\n}\n.md-format-align-right:before {\n  content: \"\\f179\";\n}\n.md-format-bold:before {\n  content: \"\\f17a\";\n}\n.md-format-clear:before {\n  content: \"\\f17b\";\n}\n.md-format-color-fill:before {\n  content: \"\\f17c\";\n}\n.md-format-color-reset:before {\n  content: \"\\f17d\";\n}\n.md-format-color-text:before {\n  content: \"\\f17e\";\n}\n.md-format-indent-decrease:before {\n  content: \"\\f17f\";\n}\n.md-format-indent-increase:before {\n  content: \"\\f180\";\n}\n.md-format-italic:before {\n  content: \"\\f181\";\n}\n.md-format-line-spacing:before {\n  content: \"\\f182\";\n}\n.md-format-list-bulleted:before {\n  content: \"\\f183\";\n}\n.md-format-list-numbered:before {\n  content: \"\\f184\";\n}\n.md-format-paint:before {\n  content: \"\\f185\";\n}\n.md-format-quote:before {\n  content: \"\\f186\";\n}\n.md-format-size:before {\n  content: \"\\f187\";\n}\n.md-format-strikethrough:before {\n  content: \"\\f188\";\n}\n.md-format-textdirection-l-to-r:before {\n  content: \"\\f189\";\n}\n.md-format-textdirection-r-to-l:before {\n  content: \"\\f18a\";\n}\n.md-format-underline:before {\n  content: \"\\f18b\";\n}\n.md-functions:before {\n  content: \"\\f18c\";\n}\n.md-insert-chart:before {\n  content: \"\\f18d\";\n}\n.md-insert-comment:before {\n  content: \"\\f18e\";\n}\n.md-insert-drive-file:before {\n  content: \"\\f18f\";\n}\n.md-insert-emoticon:before {\n  content: \"\\f190\";\n}\n.md-insert-invitation:before {\n  content: \"\\f191\";\n}\n.md-insert-link:before {\n  content: \"\\f192\";\n}\n.md-insert-photo:before {\n  content: \"\\f193\";\n}\n.md-merge-type:before {\n  content: \"\\f194\";\n}\n.md-mode-comment:before {\n  content: \"\\f195\";\n}\n.md-mode-edit:before {\n  content: \"\\f196\";\n}\n.md-publish:before {\n  content: \"\\f197\";\n}\n.md-vertical-align-bottom:before {\n  content: \"\\f198\";\n}\n.md-vertical-align-center:before {\n  content: \"\\f199\";\n}\n.md-vertical-align-top:before {\n  content: \"\\f19a\";\n}\n.md-wrap-text:before {\n  content: \"\\f19b\";\n}\n.md-attachment:before {\n  content: \"\\f19c\";\n}\n.md-cloud:before {\n  content: \"\\f19d\";\n}\n.md-cloud-circle:before {\n  content: \"\\f19e\";\n}\n.md-cloud-done:before {\n  content: \"\\f19f\";\n}\n.md-cloud-download:before {\n  content: \"\\f1a0\";\n}\n.md-cloud-off:before {\n  content: \"\\f1a1\";\n}\n.md-cloud-queue:before {\n  content: \"\\f1a2\";\n}\n.md-cloud-upload:before {\n  content: \"\\f1a3\";\n}\n.md-file-download:before {\n  content: \"\\f1a4\";\n}\n.md-file-upload:before {\n  content: \"\\f1a5\";\n}\n.md-folder:before {\n  content: \"\\f1a6\";\n}\n.md-folder-open:before {\n  content: \"\\f1a7\";\n}\n.md-folder-shared:before {\n  content: \"\\f1a8\";\n}\n.md-cast:before {\n  content: \"\\f1a9\";\n}\n.md-cast-connected:before {\n  content: \"\\f1aa\";\n}\n.md-computer:before {\n  content: \"\\f1ab\";\n}\n.md-desktop-mac:before {\n  content: \"\\f1ac\";\n}\n.md-desktop-windows:before {\n  content: \"\\f1ad\";\n}\n.md-dock:before {\n  content: \"\\f1ae\";\n}\n.md-gamepad:before {\n  content: \"\\f1af\";\n}\n.md-headset:before {\n  content: \"\\f1b0\";\n}\n.md-headset-mic:before {\n  content: \"\\f1b1\";\n}\n.md-keyboard:before {\n  content: \"\\f1b2\";\n}\n.md-keyboard-alt:before {\n  content: \"\\f1b3\";\n}\n.md-keyboard-arrow-down:before {\n  content: \"\\f1b4\";\n}\n.md-keyboard-arrow-left:before {\n  content: \"\\f1b5\";\n}\n.md-keyboard-arrow-right:before {\n  content: \"\\f1b6\";\n}\n.md-keyboard-arrow-up:before {\n  content: \"\\f1b7\";\n}\n.md-keyboard-backspace:before {\n  content: \"\\f1b8\";\n}\n.md-keyboard-capslock:before {\n  content: \"\\f1b9\";\n}\n.md-keyboard-control:before {\n  content: \"\\f1ba\";\n}\n.md-keyboard-hide:before {\n  content: \"\\f1bb\";\n}\n.md-keyboard-return:before {\n  content: \"\\f1bc\";\n}\n.md-keyboard-tab:before {\n  content: \"\\f1bd\";\n}\n.md-keyboard-voice:before {\n  content: \"\\f1be\";\n}\n.md-laptop:before {\n  content: \"\\f1bf\";\n}\n.md-laptop-chromebook:before {\n  content: \"\\f1c0\";\n}\n.md-laptop-mac:before {\n  content: \"\\f1c1\";\n}\n.md-laptop-windows:before {\n  content: \"\\f1c2\";\n}\n.md-memory:before {\n  content: \"\\f1c3\";\n}\n.md-mouse:before {\n  content: \"\\f1c4\";\n}\n.md-phone-android:before {\n  content: \"\\f1c5\";\n}\n.md-phone-iphone:before {\n  content: \"\\f1c6\";\n}\n.md-phonelink:before {\n  content: \"\\f1c7\";\n}\n.md-phonelink-off:before {\n  content: \"\\f1c8\";\n}\n.md-security:before {\n  content: \"\\f1c9\";\n}\n.md-sim-card:before {\n  content: \"\\f1ca\";\n}\n.md-smartphone:before {\n  content: \"\\f1cb\";\n}\n.md-speaker:before {\n  content: \"\\f1cc\";\n}\n.md-tablet:before {\n  content: \"\\f1cd\";\n}\n.md-tablet-android:before {\n  content: \"\\f1ce\";\n}\n.md-tablet-mac:before {\n  content: \"\\f1cf\";\n}\n.md-tv:before {\n  content: \"\\f1d0\";\n}\n.md-watch:before {\n  content: \"\\f1d1\";\n}\n.md-add-to-photos:before {\n  content: \"\\f1d2\";\n}\n.md-adjust:before {\n  content: \"\\f1d3\";\n}\n.md-assistant-photo:before {\n  content: \"\\f1d4\";\n}\n.md-audiotrack:before {\n  content: \"\\f1d5\";\n}\n.md-blur-circular:before {\n  content: \"\\f1d6\";\n}\n.md-blur-linear:before {\n  content: \"\\f1d7\";\n}\n.md-blur-off:before {\n  content: \"\\f1d8\";\n}\n.md-blur-on:before {\n  content: \"\\f1d9\";\n}\n.md-brightness-1:before {\n  content: \"\\f1da\";\n}\n.md-brightness-2:before {\n  content: \"\\f1db\";\n}\n.md-brightness-3:before {\n  content: \"\\f1dc\";\n}\n.md-brightness-4:before {\n  content: \"\\f1dd\";\n}\n.md-brightness-5:before {\n  content: \"\\f1de\";\n}\n.md-brightness-6:before {\n  content: \"\\f1df\";\n}\n.md-brightness-7:before {\n  content: \"\\f1e0\";\n}\n.md-brush:before {\n  content: \"\\f1e1\";\n}\n.md-camera:before {\n  content: \"\\f1e2\";\n}\n.md-camera-alt:before {\n  content: \"\\f1e3\";\n}\n.md-camera-front:before {\n  content: \"\\f1e4\";\n}\n.md-camera-rear:before {\n  content: \"\\f1e5\";\n}\n.md-camera-roll:before {\n  content: \"\\f1e6\";\n}\n.md-center-focus-strong:before {\n  content: \"\\f1e7\";\n}\n.md-center-focus-weak:before {\n  content: \"\\f1e8\";\n}\n.md-collections:before {\n  content: \"\\f1e9\";\n}\n.md-colorize:before {\n  content: \"\\f1ea\";\n}\n.md-color-lens:before {\n  content: \"\\f1eb\";\n}\n.md-compare:before {\n  content: \"\\f1ec\";\n}\n.md-control-point:before {\n  content: \"\\f1ed\";\n}\n.md-control-point-duplicate:before {\n  content: \"\\f1ee\";\n}\n.md-crop:before {\n  content: \"\\f1ef\";\n}\n.md-crop-3-2:before {\n  content: \"\\f1f0\";\n}\n.md-crop-5-4:before {\n  content: \"\\f1f1\";\n}\n.md-crop-7-5:before {\n  content: \"\\f1f2\";\n}\n.md-crop-16-9:before {\n  content: \"\\f1f3\";\n}\n.md-crop-din:before {\n  content: \"\\f1f4\";\n}\n.md-crop-free:before {\n  content: \"\\f1f5\";\n}\n.md-crop-landscape:before {\n  content: \"\\f1f6\";\n}\n.md-crop-original:before {\n  content: \"\\f1f7\";\n}\n.md-crop-portrait:before {\n  content: \"\\f1f8\";\n}\n.md-crop-square:before {\n  content: \"\\f1f9\";\n}\n.md-dehaze:before {\n  content: \"\\f1fa\";\n}\n.md-details:before {\n  content: \"\\f1fb\";\n}\n.md-edit:before {\n  content: \"\\f1fc\";\n}\n.md-exposure:before {\n  content: \"\\f1fd\";\n}\n.md-exposure-minus-1:before {\n  content: \"\\f1fe\";\n}\n.md-exposure-minus-2:before {\n  content: \"\\f1ff\";\n}\n.md-exposure-zero:before {\n  content: \"\\f200\";\n}\n.md-exposure-plus-1:before {\n  content: \"\\f201\";\n}\n.md-exposure-plus-2:before {\n  content: \"\\f202\";\n}\n.md-filter:before {\n  content: \"\\f203\";\n}\n.md-filter-1:before {\n  content: \"\\f204\";\n}\n.md-filter-2:before {\n  content: \"\\f205\";\n}\n.md-filter-3:before {\n  content: \"\\f206\";\n}\n.md-filter-4:before {\n  content: \"\\f207\";\n}\n.md-filter-5:before {\n  content: \"\\f208\";\n}\n.md-filter-6:before {\n  content: \"\\f209\";\n}\n.md-filter-7:before {\n  content: \"\\f20a\";\n}\n.md-filter-8:before {\n  content: \"\\f20b\";\n}\n.md-filter-9:before {\n  content: \"\\f20c\";\n}\n.md-filter-9-plus:before {\n  content: \"\\f20d\";\n}\n.md-filter-b-and-w:before {\n  content: \"\\f20e\";\n}\n.md-filter-center-focus:before {\n  content: \"\\f20f\";\n}\n.md-filter-drama:before {\n  content: \"\\f210\";\n}\n.md-filter-frames:before {\n  content: \"\\f211\";\n}\n.md-filter-hdr:before {\n  content: \"\\f212\";\n}\n.md-filter-none:before {\n  content: \"\\f213\";\n}\n.md-filter-tilt-shift:before {\n  content: \"\\f214\";\n}\n.md-filter-vintage:before {\n  content: \"\\f215\";\n}\n.md-flare:before {\n  content: \"\\f216\";\n}\n.md-flash-auto:before {\n  content: \"\\f217\";\n}\n.md-flash-off:before {\n  content: \"\\f218\";\n}\n.md-flash-on:before {\n  content: \"\\f219\";\n}\n.md-flip:before {\n  content: \"\\f21a\";\n}\n.md-gradient:before {\n  content: \"\\f21b\";\n}\n.md-grain:before {\n  content: \"\\f21c\";\n}\n.md-grid-off:before {\n  content: \"\\f21d\";\n}\n.md-grid-on:before {\n  content: \"\\f21e\";\n}\n.md-hdr-off:before {\n  content: \"\\f21f\";\n}\n.md-hdr-on:before {\n  content: \"\\f220\";\n}\n.md-hdr-strong:before {\n  content: \"\\f221\";\n}\n.md-hdr-weak:before {\n  content: \"\\f222\";\n}\n.md-healing:before {\n  content: \"\\f223\";\n}\n.md-image:before {\n  content: \"\\f224\";\n}\n.md-image-aspect-ratio:before {\n  content: \"\\f225\";\n}\n.md-iso:before {\n  content: \"\\f226\";\n}\n.md-landscape:before {\n  content: \"\\f227\";\n}\n.md-leak-add:before {\n  content: \"\\f228\";\n}\n.md-leak-remove:before {\n  content: \"\\f229\";\n}\n.md-lens:before {\n  content: \"\\f22a\";\n}\n.md-looks:before {\n  content: \"\\f22b\";\n}\n.md-looks-1:before {\n  content: \"\\f22c\";\n}\n.md-looks-2:before {\n  content: \"\\f22d\";\n}\n.md-looks-3:before {\n  content: \"\\f22e\";\n}\n.md-looks-4:before {\n  content: \"\\f22f\";\n}\n.md-looks-5:before {\n  content: \"\\f230\";\n}\n.md-looks-6:before {\n  content: \"\\f231\";\n}\n.md-loupe:before {\n  content: \"\\f232\";\n}\n.md-movie-creation:before {\n  content: \"\\f233\";\n}\n.md-nature:before {\n  content: \"\\f234\";\n}\n.md-nature-people:before {\n  content: \"\\f235\";\n}\n.md-navigate-before:before {\n  content: \"\\f236\";\n}\n.md-navigate-next:before {\n  content: \"\\f237\";\n}\n.md-palette:before {\n  content: \"\\f238\";\n}\n.md-panorama:before {\n  content: \"\\f239\";\n}\n.md-panorama-fisheye:before {\n  content: \"\\f23a\";\n}\n.md-panorama-horizontal:before {\n  content: \"\\f23b\";\n}\n.md-panorama-vertical:before {\n  content: \"\\f23c\";\n}\n.md-panorama-wide-angle:before {\n  content: \"\\f23d\";\n}\n.md-photo:before {\n  content: \"\\f23e\";\n}\n.md-photo-album:before {\n  content: \"\\f23f\";\n}\n.md-photo-camera:before {\n  content: \"\\f240\";\n}\n.md-photo-library:before {\n  content: \"\\f241\";\n}\n.md-portrait:before {\n  content: \"\\f242\";\n}\n.md-remove-red-eye:before {\n  content: \"\\f243\";\n}\n.md-rotate-left:before {\n  content: \"\\f244\";\n}\n.md-rotate-right:before {\n  content: \"\\f245\";\n}\n.md-slideshow:before {\n  content: \"\\f246\";\n}\n.md-straighten:before {\n  content: \"\\f247\";\n}\n.md-style:before {\n  content: \"\\f248\";\n}\n.md-switch-camera:before {\n  content: \"\\f249\";\n}\n.md-switch-video:before {\n  content: \"\\f24a\";\n}\n.md-tag-faces:before {\n  content: \"\\f24b\";\n}\n.md-texture:before {\n  content: \"\\f24c\";\n}\n.md-timelapse:before {\n  content: \"\\f24d\";\n}\n.md-timer:before {\n  content: \"\\f24e\";\n}\n.md-timer-3:before {\n  content: \"\\f24f\";\n}\n.md-timer-10:before {\n  content: \"\\f250\";\n}\n.md-timer-auto:before {\n  content: \"\\f251\";\n}\n.md-timer-off:before {\n  content: \"\\f252\";\n}\n.md-tonality:before {\n  content: \"\\f253\";\n}\n.md-transform:before {\n  content: \"\\f254\";\n}\n.md-tune:before {\n  content: \"\\f255\";\n}\n.md-wb-auto:before {\n  content: \"\\f256\";\n}\n.md-wb-cloudy:before {\n  content: \"\\f257\";\n}\n.md-wb-incandescent:before {\n  content: \"\\f258\";\n}\n.md-wb-irradescent:before {\n  content: \"\\f259\";\n}\n.md-wb-sunny:before {\n  content: \"\\f25a\";\n}\n.md-beenhere:before {\n  content: \"\\f25b\";\n}\n.md-directions:before {\n  content: \"\\f25c\";\n}\n.md-directions-bike:before {\n  content: \"\\f25d\";\n}\n.md-directions-bus:before {\n  content: \"\\f25e\";\n}\n.md-directions-car:before {\n  content: \"\\f25f\";\n}\n.md-directions-ferry:before {\n  content: \"\\f260\";\n}\n.md-directions-subway:before {\n  content: \"\\f261\";\n}\n.md-directions-train:before {\n  content: \"\\f262\";\n}\n.md-directions-transit:before {\n  content: \"\\f263\";\n}\n.md-directions-walk:before {\n  content: \"\\f264\";\n}\n.md-flight:before {\n  content: \"\\f265\";\n}\n.md-hotel:before {\n  content: \"\\f266\";\n}\n.md-layers:before {\n  content: \"\\f267\";\n}\n.md-layers-clear:before {\n  content: \"\\f268\";\n}\n.md-local-airport:before {\n  content: \"\\f269\";\n}\n.md-local-atm:before {\n  content: \"\\f26a\";\n}\n.md-local-attraction:before {\n  content: \"\\f26b\";\n}\n.md-local-bar:before {\n  content: \"\\f26c\";\n}\n.md-local-cafe:before {\n  content: \"\\f26d\";\n}\n.md-local-car-wash:before {\n  content: \"\\f26e\";\n}\n.md-local-convenience-store:before {\n  content: \"\\f26f\";\n}\n.md-local-drink:before {\n  content: \"\\f270\";\n}\n.md-local-florist:before {\n  content: \"\\f271\";\n}\n.md-local-gas-station:before {\n  content: \"\\f272\";\n}\n.md-local-grocery-store:before {\n  content: \"\\f273\";\n}\n.md-local-hospital:before {\n  content: \"\\f274\";\n}\n.md-local-hotel:before {\n  content: \"\\f275\";\n}\n.md-local-laundry-service:before {\n  content: \"\\f276\";\n}\n.md-local-library:before {\n  content: \"\\f277\";\n}\n.md-local-mall:before {\n  content: \"\\f278\";\n}\n.md-local-movies:before {\n  content: \"\\f279\";\n}\n.md-local-offer:before {\n  content: \"\\f27a\";\n}\n.md-local-parking:before {\n  content: \"\\f27b\";\n}\n.md-local-pharmacy:before {\n  content: \"\\f27c\";\n}\n.md-local-phone:before {\n  content: \"\\f27d\";\n}\n.md-local-pizza:before {\n  content: \"\\f27e\";\n}\n.md-local-play:before {\n  content: \"\\f27f\";\n}\n.md-local-post-office:before {\n  content: \"\\f280\";\n}\n.md-local-print-shop:before {\n  content: \"\\f281\";\n}\n.md-local-restaurant:before {\n  content: \"\\f282\";\n}\n.md-local-see:before {\n  content: \"\\f283\";\n}\n.md-local-shipping:before {\n  content: \"\\f284\";\n}\n.md-local-taxi:before {\n  content: \"\\f285\";\n}\n.md-location-history:before {\n  content: \"\\f286\";\n}\n.md-map:before {\n  content: \"\\f287\";\n}\n.md-my-location:before {\n  content: \"\\f288\";\n}\n.md-navigation:before {\n  content: \"\\f289\";\n}\n.md-pin-drop:before {\n  content: \"\\f28a\";\n}\n.md-place:before {\n  content: \"\\f28b\";\n}\n.md-rate-review:before {\n  content: \"\\f28c\";\n}\n.md-restaurant-menu:before {\n  content: \"\\f28d\";\n}\n.md-satellite:before {\n  content: \"\\f28e\";\n}\n.md-store-mall-directory:before {\n  content: \"\\f28f\";\n}\n.md-terrain:before {\n  content: \"\\f290\";\n}\n.md-traffic:before {\n  content: \"\\f291\";\n}\n.md-apps:before {\n  content: \"\\f292\";\n}\n.md-cancel:before {\n  content: \"\\f293\";\n}\n.md-arrow-drop-down-circle:before {\n  content: \"\\f294\";\n}\n.md-arrow-drop-down:before {\n  content: \"\\f295\";\n}\n.md-arrow-drop-up:before {\n  content: \"\\f296\";\n}\n.md-arrow-back:before {\n  content: \"\\f297\";\n}\n.md-arrow-forward:before {\n  content: \"\\f298\";\n}\n.md-check:before {\n  content: \"\\f299\";\n}\n.md-close:before {\n  content: \"\\f29a\";\n}\n.md-chevron-left:before {\n  content: \"\\f29b\";\n}\n.md-chevron-right:before {\n  content: \"\\f29c\";\n}\n.md-expand-less:before {\n  content: \"\\f29d\";\n}\n.md-expand-more:before {\n  content: \"\\f29e\";\n}\n.md-fullscreen:before {\n  content: \"\\f29f\";\n}\n.md-fullscreen-exit:before {\n  content: \"\\f2a0\";\n}\n.md-menu:before {\n  content: \"\\f2a1\";\n}\n.md-more-horiz:before {\n  content: \"\\f2a2\";\n}\n.md-more-vert:before {\n  content: \"\\f2a3\";\n}\n.md-refresh:before {\n  content: \"\\f2a4\";\n}\n.md-unfold-less:before {\n  content: \"\\f2a5\";\n}\n.md-unfold-more:before {\n  content: \"\\f2a6\";\n}\n.md-adb:before {\n  content: \"\\f2a7\";\n}\n.md-bluetooth-audio:before {\n  content: \"\\f2a8\";\n}\n.md-disc-full:before {\n  content: \"\\f2a9\";\n}\n.md-dnd-forwardslash:before {\n  content: \"\\f2aa\";\n}\n.md-do-not-disturb:before {\n  content: \"\\f2ab\";\n}\n.md-drive-eta:before {\n  content: \"\\f2ac\";\n}\n.md-event-available:before {\n  content: \"\\f2ad\";\n}\n.md-event-busy:before {\n  content: \"\\f2ae\";\n}\n.md-event-note:before {\n  content: \"\\f2af\";\n}\n.md-folder-special:before {\n  content: \"\\f2b0\";\n}\n.md-mms:before {\n  content: \"\\f2b1\";\n}\n.md-more:before {\n  content: \"\\f2b2\";\n}\n.md-network-locked:before {\n  content: \"\\f2b3\";\n}\n.md-phone-bluetooth-speaker:before {\n  content: \"\\f2b4\";\n}\n.md-phone-forwarded:before {\n  content: \"\\f2b5\";\n}\n.md-phone-in-talk:before {\n  content: \"\\f2b6\";\n}\n.md-phone-locked:before {\n  content: \"\\f2b7\";\n}\n.md-phone-missed:before {\n  content: \"\\f2b8\";\n}\n.md-phone-paused:before {\n  content: \"\\f2b9\";\n}\n.md-play-download:before {\n  content: \"\\f2ba\";\n}\n.md-play-install:before {\n  content: \"\\f2bb\";\n}\n.md-sd-card:before {\n  content: \"\\f2bc\";\n}\n.md-sim-card-alert:before {\n  content: \"\\f2bd\";\n}\n.md-sms:before {\n  content: \"\\f2be\";\n}\n.md-sms-failed:before {\n  content: \"\\f2bf\";\n}\n.md-sync:before {\n  content: \"\\f2c0\";\n}\n.md-sync-disabled:before {\n  content: \"\\f2c1\";\n}\n.md-sync-problem:before {\n  content: \"\\f2c2\";\n}\n.md-system-update:before {\n  content: \"\\f2c3\";\n}\n.md-tap-and-play:before {\n  content: \"\\f2c4\";\n}\n.md-time-to-leave:before {\n  content: \"\\f2c5\";\n}\n.md-vibration:before {\n  content: \"\\f2c6\";\n}\n.md-voice-chat:before {\n  content: \"\\f2c7\";\n}\n.md-vpn-lock:before {\n  content: \"\\f2c8\";\n}\n.md-cake:before {\n  content: \"\\f2c9\";\n}\n.md-domain:before {\n  content: \"\\f2ca\";\n}\n.md-location-city:before {\n  content: \"\\f2cb\";\n}\n.md-mood:before {\n  content: \"\\f2cc\";\n}\n.md-notifications-none:before {\n  content: \"\\f2cd\";\n}\n.md-notifications:before {\n  content: \"\\f2ce\";\n}\n.md-notifications-off:before {\n  content: \"\\f2cf\";\n}\n.md-notifications-on:before {\n  content: \"\\f2d0\";\n}\n.md-notifications-paused:before {\n  content: \"\\f2d1\";\n}\n.md-pages:before {\n  content: \"\\f2d2\";\n}\n.md-party-mode:before {\n  content: \"\\f2d3\";\n}\n.md-group:before {\n  content: \"\\f2d4\";\n}\n.md-group-add:before {\n  content: \"\\f2d5\";\n}\n.md-people:before {\n  content: \"\\f2d6\";\n}\n.md-people-outline:before {\n  content: \"\\f2d7\";\n}\n.md-person:before {\n  content: \"\\f2d8\";\n}\n.md-person-add:before {\n  content: \"\\f2d9\";\n}\n.md-person-outline:before {\n  content: \"\\f2da\";\n}\n.md-plus-one:before {\n  content: \"\\f2db\";\n}\n.md-poll:before {\n  content: \"\\f2dc\";\n}\n.md-public:before {\n  content: \"\\f2dd\";\n}\n.md-school:before {\n  content: \"\\f2de\";\n}\n.md-share:before {\n  content: \"\\f2df\";\n}\n.md-whatshot:before {\n  content: \"\\f2e0\";\n}\n.md-check-box:before {\n  content: \"\\f2e1\";\n}\n.md-check-box-outline-blank:before {\n  content: \"\\f2e2\";\n}\n.md-radio-button-off:before {\n  content: \"\\f2e3\";\n}\n.md-radio-button-on:before {\n  content: \"\\f2e4\";\n}\n.md-star:before {\n  content: \"\\f2e5\";\n}\n.md-star-half:before {\n  content: \"\\f2e6\";\n}\n.md-star-outline:before {\n  content: \"\\f2e7\";\n}\n@font-face {\n  font-family: 'simple-line-icons';\n  src: url('../fonts/Simple-Line-Icons.eot?-i3a2kk');\n  src: url('../fonts/Simple-Line-Icons.eot?#iefix-i3a2kk') format('embedded-opentype'), url('../fonts/Simple-Line-Icons.ttf?-i3a2kk') format('truetype'), url('../fonts/Simple-Line-Icons.woff2?-i3a2kk') format('woff2'), url('../fonts/Simple-Line-Icons.woff?-i3a2kk') format('woff'), url('../fonts/Simple-Line-Icons.svg?-i3a2kk#simple-line-icons') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n/*\n Use the following CSS code if you want to have a class per icon.\n Instead of a list of all class selectors, you can use the generic [class*=\"icon-\"] selector, but it's slower: \n*/\n.icon-user,\n.icon-people,\n.icon-user-female,\n.icon-user-follow,\n.icon-user-following,\n.icon-user-unfollow,\n.icon-login,\n.icon-logout,\n.icon-emotsmile,\n.icon-phone,\n.icon-call-end,\n.icon-call-in,\n.icon-call-out,\n.icon-map,\n.icon-location-pin,\n.icon-direction,\n.icon-directions,\n.icon-compass,\n.icon-layers,\n.icon-menu,\n.icon-list,\n.icon-options-vertical,\n.icon-options,\n.icon-arrow-down,\n.icon-arrow-left,\n.icon-arrow-right,\n.icon-arrow-up,\n.icon-arrow-up-circle,\n.icon-arrow-left-circle,\n.icon-arrow-right-circle,\n.icon-arrow-down-circle,\n.icon-check,\n.icon-clock,\n.icon-plus,\n.icon-close,\n.icon-trophy,\n.icon-screen-smartphone,\n.icon-screen-desktop,\n.icon-plane,\n.icon-notebook,\n.icon-mustache,\n.icon-mouse,\n.icon-magnet,\n.icon-energy,\n.icon-disc,\n.icon-cursor,\n.icon-cursor-move,\n.icon-crop,\n.icon-chemistry,\n.icon-speedometer,\n.icon-shield,\n.icon-screen-tablet,\n.icon-magic-wand,\n.icon-hourglass,\n.icon-graduation,\n.icon-ghost,\n.icon-game-controller,\n.icon-fire,\n.icon-eyeglass,\n.icon-envelope-open,\n.icon-envelope-letter,\n.icon-bell,\n.icon-badge,\n.icon-anchor,\n.icon-wallet,\n.icon-vector,\n.icon-speech,\n.icon-puzzle,\n.icon-printer,\n.icon-present,\n.icon-playlist,\n.icon-pin,\n.icon-picture,\n.icon-handbag,\n.icon-globe-alt,\n.icon-globe,\n.icon-folder-alt,\n.icon-folder,\n.icon-film,\n.icon-feed,\n.icon-drop,\n.icon-drawar,\n.icon-docs,\n.icon-doc,\n.icon-diamond,\n.icon-cup,\n.icon-calculator,\n.icon-bubbles,\n.icon-briefcase,\n.icon-book-open,\n.icon-basket-loaded,\n.icon-basket,\n.icon-bag,\n.icon-action-undo,\n.icon-action-redo,\n.icon-wrench,\n.icon-umbrella,\n.icon-trash,\n.icon-tag,\n.icon-support,\n.icon-frame,\n.icon-size-fullscreen,\n.icon-size-actual,\n.icon-shuffle,\n.icon-share-alt,\n.icon-share,\n.icon-rocket,\n.icon-question,\n.icon-pie-chart,\n.icon-pencil,\n.icon-note,\n.icon-loop,\n.icon-home,\n.icon-grid,\n.icon-graph,\n.icon-microphone,\n.icon-music-tone-alt,\n.icon-music-tone,\n.icon-earphones-alt,\n.icon-earphones,\n.icon-equalizer,\n.icon-like,\n.icon-dislike,\n.icon-control-start,\n.icon-control-rewind,\n.icon-control-play,\n.icon-control-pause,\n.icon-control-forward,\n.icon-control-end,\n.icon-volume-1,\n.icon-volume-2,\n.icon-volume-off,\n.icon-calender,\n.icon-bulb,\n.icon-chart,\n.icon-ban,\n.icon-bubble,\n.icon-camrecorder,\n.icon-camera,\n.icon-cloud-download,\n.icon-cloud-upload,\n.icon-envelope,\n.icon-eye,\n.icon-flag,\n.icon-heart,\n.icon-info,\n.icon-key,\n.icon-link,\n.icon-lock,\n.icon-lock-open,\n.icon-magnifier,\n.icon-magnifier-add,\n.icon-magnifier-remove,\n.icon-paper-clip,\n.icon-paper-plane,\n.icon-power,\n.icon-refresh,\n.icon-reload,\n.icon-settings,\n.icon-star,\n.icon-symble-female,\n.icon-symbol-male,\n.icon-target,\n.icon-credit-card,\n.icon-paypal,\n.icon-social-tumblr,\n.icon-social-twitter,\n.icon-social-facebook,\n.icon-social-instagram,\n.icon-social-linkedin,\n.icon-social-pintarest,\n.icon-social-github,\n.icon-social-gplus,\n.icon-social-reddit,\n.icon-social-skype,\n.icon-social-dribbble,\n.icon-social-behance,\n.icon-social-foursqare,\n.icon-social-soundcloud,\n.icon-social-spotify,\n.icon-social-stumbleupon,\n.icon-social-youtube,\n.icon-social-dropbox {\n  font-family: 'simple-line-icons';\n  speak: none;\n  font-style: normal;\n  font-weight: normal;\n  font-variant: normal;\n  text-transform: none;\n  line-height: 1;\n  /* Better Font Rendering =========== */\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.icon-user:before {\n  content: \"\\e005\";\n}\n.icon-people:before {\n  content: \"\\e001\";\n}\n.icon-user-female:before {\n  content: \"\\e000\";\n}\n.icon-user-follow:before {\n  content: \"\\e002\";\n}\n.icon-user-following:before {\n  content: \"\\e003\";\n}\n.icon-user-unfollow:before {\n  content: \"\\e004\";\n}\n.icon-login:before {\n  content: \"\\e066\";\n}\n.icon-logout:before {\n  content: \"\\e065\";\n}\n.icon-emotsmile:before {\n  content: \"\\e021\";\n}\n.icon-phone:before {\n  content: \"\\e600\";\n}\n.icon-call-end:before {\n  content: \"\\e048\";\n}\n.icon-call-in:before {\n  content: \"\\e047\";\n}\n.icon-call-out:before {\n  content: \"\\e046\";\n}\n.icon-map:before {\n  content: \"\\e033\";\n}\n.icon-location-pin:before {\n  content: \"\\e096\";\n}\n.icon-direction:before {\n  content: \"\\e042\";\n}\n.icon-directions:before {\n  content: \"\\e041\";\n}\n.icon-compass:before {\n  content: \"\\e045\";\n}\n.icon-layers:before {\n  content: \"\\e034\";\n}\n.icon-menu:before {\n  content: \"\\e601\";\n}\n.icon-list:before {\n  content: \"\\e067\";\n}\n.icon-options-vertical:before {\n  content: \"\\e602\";\n}\n.icon-options:before {\n  content: \"\\e603\";\n}\n.icon-arrow-down:before {\n  content: \"\\e604\";\n}\n.icon-arrow-left:before {\n  content: \"\\e605\";\n}\n.icon-arrow-right:before {\n  content: \"\\e606\";\n}\n.icon-arrow-up:before {\n  content: \"\\e607\";\n}\n.icon-arrow-up-circle:before {\n  content: \"\\e078\";\n}\n.icon-arrow-left-circle:before {\n  content: \"\\e07a\";\n}\n.icon-arrow-right-circle:before {\n  content: \"\\e079\";\n}\n.icon-arrow-down-circle:before {\n  content: \"\\e07b\";\n}\n.icon-check:before {\n  content: \"\\e080\";\n}\n.icon-clock:before {\n  content: \"\\e081\";\n}\n.icon-plus:before {\n  content: \"\\e095\";\n}\n.icon-close:before {\n  content: \"\\e082\";\n}\n.icon-trophy:before {\n  content: \"\\e006\";\n}\n.icon-screen-smartphone:before {\n  content: \"\\e010\";\n}\n.icon-screen-desktop:before {\n  content: \"\\e011\";\n}\n.icon-plane:before {\n  content: \"\\e012\";\n}\n.icon-notebook:before {\n  content: \"\\e013\";\n}\n.icon-mustache:before {\n  content: \"\\e014\";\n}\n.icon-mouse:before {\n  content: \"\\e015\";\n}\n.icon-magnet:before {\n  content: \"\\e016\";\n}\n.icon-energy:before {\n  content: \"\\e020\";\n}\n.icon-disc:before {\n  content: \"\\e022\";\n}\n.icon-cursor:before {\n  content: \"\\e06e\";\n}\n.icon-cursor-move:before {\n  content: \"\\e023\";\n}\n.icon-crop:before {\n  content: \"\\e024\";\n}\n.icon-chemistry:before {\n  content: \"\\e026\";\n}\n.icon-speedometer:before {\n  content: \"\\e007\";\n}\n.icon-shield:before {\n  content: \"\\e00e\";\n}\n.icon-screen-tablet:before {\n  content: \"\\e00f\";\n}\n.icon-magic-wand:before {\n  content: \"\\e017\";\n}\n.icon-hourglass:before {\n  content: \"\\e018\";\n}\n.icon-graduation:before {\n  content: \"\\e019\";\n}\n.icon-ghost:before {\n  content: \"\\e01a\";\n}\n.icon-game-controller:before {\n  content: \"\\e01b\";\n}\n.icon-fire:before {\n  content: \"\\e01c\";\n}\n.icon-eyeglass:before {\n  content: \"\\e01d\";\n}\n.icon-envelope-open:before {\n  content: \"\\e01e\";\n}\n.icon-envelope-letter:before {\n  content: \"\\e01f\";\n}\n.icon-bell:before {\n  content: \"\\e027\";\n}\n.icon-badge:before {\n  content: \"\\e028\";\n}\n.icon-anchor:before {\n  content: \"\\e029\";\n}\n.icon-wallet:before {\n  content: \"\\e02a\";\n}\n.icon-vector:before {\n  content: \"\\e02b\";\n}\n.icon-speech:before {\n  content: \"\\e02c\";\n}\n.icon-puzzle:before {\n  content: \"\\e02d\";\n}\n.icon-printer:before {\n  content: \"\\e02e\";\n}\n.icon-present:before {\n  content: \"\\e02f\";\n}\n.icon-playlist:before {\n  content: \"\\e030\";\n}\n.icon-pin:before {\n  content: \"\\e031\";\n}\n.icon-picture:before {\n  content: \"\\e032\";\n}\n.icon-handbag:before {\n  content: \"\\e035\";\n}\n.icon-globe-alt:before {\n  content: \"\\e036\";\n}\n.icon-globe:before {\n  content: \"\\e037\";\n}\n.icon-folder-alt:before {\n  content: \"\\e039\";\n}\n.icon-folder:before {\n  content: \"\\e089\";\n}\n.icon-film:before {\n  content: \"\\e03a\";\n}\n.icon-feed:before {\n  content: \"\\e03b\";\n}\n.icon-drop:before {\n  content: \"\\e03e\";\n}\n.icon-drawar:before {\n  content: \"\\e03f\";\n}\n.icon-docs:before {\n  content: \"\\e040\";\n}\n.icon-doc:before {\n  content: \"\\e085\";\n}\n.icon-diamond:before {\n  content: \"\\e043\";\n}\n.icon-cup:before {\n  content: \"\\e044\";\n}\n.icon-calculator:before {\n  content: \"\\e049\";\n}\n.icon-bubbles:before {\n  content: \"\\e04a\";\n}\n.icon-briefcase:before {\n  content: \"\\e04b\";\n}\n.icon-book-open:before {\n  content: \"\\e04c\";\n}\n.icon-basket-loaded:before {\n  content: \"\\e04d\";\n}\n.icon-basket:before {\n  content: \"\\e04e\";\n}\n.icon-bag:before {\n  content: \"\\e04f\";\n}\n.icon-action-undo:before {\n  content: \"\\e050\";\n}\n.icon-action-redo:before {\n  content: \"\\e051\";\n}\n.icon-wrench:before {\n  content: \"\\e052\";\n}\n.icon-umbrella:before {\n  content: \"\\e053\";\n}\n.icon-trash:before {\n  content: \"\\e054\";\n}\n.icon-tag:before {\n  content: \"\\e055\";\n}\n.icon-support:before {\n  content: \"\\e056\";\n}\n.icon-frame:before {\n  content: \"\\e038\";\n}\n.icon-size-fullscreen:before {\n  content: \"\\e057\";\n}\n.icon-size-actual:before {\n  content: \"\\e058\";\n}\n.icon-shuffle:before {\n  content: \"\\e059\";\n}\n.icon-share-alt:before {\n  content: \"\\e05a\";\n}\n.icon-share:before {\n  content: \"\\e05b\";\n}\n.icon-rocket:before {\n  content: \"\\e05c\";\n}\n.icon-question:before {\n  content: \"\\e05d\";\n}\n.icon-pie-chart:before {\n  content: \"\\e05e\";\n}\n.icon-pencil:before {\n  content: \"\\e05f\";\n}\n.icon-note:before {\n  content: \"\\e060\";\n}\n.icon-loop:before {\n  content: \"\\e064\";\n}\n.icon-home:before {\n  content: \"\\e069\";\n}\n.icon-grid:before {\n  content: \"\\e06a\";\n}\n.icon-graph:before {\n  content: \"\\e06b\";\n}\n.icon-microphone:before {\n  content: \"\\e063\";\n}\n.icon-music-tone-alt:before {\n  content: \"\\e061\";\n}\n.icon-music-tone:before {\n  content: \"\\e062\";\n}\n.icon-earphones-alt:before {\n  content: \"\\e03c\";\n}\n.icon-earphones:before {\n  content: \"\\e03d\";\n}\n.icon-equalizer:before {\n  content: \"\\e06c\";\n}\n.icon-like:before {\n  content: \"\\e068\";\n}\n.icon-dislike:before {\n  content: \"\\e06d\";\n}\n.icon-control-start:before {\n  content: \"\\e06f\";\n}\n.icon-control-rewind:before {\n  content: \"\\e070\";\n}\n.icon-control-play:before {\n  content: \"\\e071\";\n}\n.icon-control-pause:before {\n  content: \"\\e072\";\n}\n.icon-control-forward:before {\n  content: \"\\e073\";\n}\n.icon-control-end:before {\n  content: \"\\e074\";\n}\n.icon-volume-1:before {\n  content: \"\\e09f\";\n}\n.icon-volume-2:before {\n  content: \"\\e0a0\";\n}\n.icon-volume-off:before {\n  content: \"\\e0a1\";\n}\n.icon-calender:before {\n  content: \"\\e075\";\n}\n.icon-bulb:before {\n  content: \"\\e076\";\n}\n.icon-chart:before {\n  content: \"\\e077\";\n}\n.icon-ban:before {\n  content: \"\\e07c\";\n}\n.icon-bubble:before {\n  content: \"\\e07d\";\n}\n.icon-camrecorder:before {\n  content: \"\\e07e\";\n}\n.icon-camera:before {\n  content: \"\\e07f\";\n}\n.icon-cloud-download:before {\n  content: \"\\e083\";\n}\n.icon-cloud-upload:before {\n  content: \"\\e084\";\n}\n.icon-envelope:before {\n  content: \"\\e086\";\n}\n.icon-eye:before {\n  content: \"\\e087\";\n}\n.icon-flag:before {\n  content: \"\\e088\";\n}\n.icon-heart:before {\n  content: \"\\e08a\";\n}\n.icon-info:before {\n  content: \"\\e08b\";\n}\n.icon-key:before {\n  content: \"\\e08c\";\n}\n.icon-link:before {\n  content: \"\\e08d\";\n}\n.icon-lock:before {\n  content: \"\\e08e\";\n}\n.icon-lock-open:before {\n  content: \"\\e08f\";\n}\n.icon-magnifier:before {\n  content: \"\\e090\";\n}\n.icon-magnifier-add:before {\n  content: \"\\e091\";\n}\n.icon-magnifier-remove:before {\n  content: \"\\e092\";\n}\n.icon-paper-clip:before {\n  content: \"\\e093\";\n}\n.icon-paper-plane:before {\n  content: \"\\e094\";\n}\n.icon-power:before {\n  content: \"\\e097\";\n}\n.icon-refresh:before {\n  content: \"\\e098\";\n}\n.icon-reload:before {\n  content: \"\\e099\";\n}\n.icon-settings:before {\n  content: \"\\e09a\";\n}\n.icon-star:before {\n  content: \"\\e09b\";\n}\n.icon-symble-female:before {\n  content: \"\\e09c\";\n}\n.icon-symbol-male:before {\n  content: \"\\e09d\";\n}\n.icon-target:before {\n  content: \"\\e09e\";\n}\n.icon-credit-card:before {\n  content: \"\\e025\";\n}\n.icon-paypal:before {\n  content: \"\\e608\";\n}\n.icon-social-tumblr:before {\n  content: \"\\e00a\";\n}\n.icon-social-twitter:before {\n  content: \"\\e009\";\n}\n.icon-social-facebook:before {\n  content: \"\\e00b\";\n}\n.icon-social-instagram:before {\n  content: \"\\e609\";\n}\n.icon-social-linkedin:before {\n  content: \"\\e60a\";\n}\n.icon-social-pintarest:before {\n  content: \"\\e60b\";\n}\n.icon-social-github:before {\n  content: \"\\e60c\";\n}\n.icon-social-gplus:before {\n  content: \"\\e60d\";\n}\n.icon-social-reddit:before {\n  content: \"\\e60e\";\n}\n.icon-social-skype:before {\n  content: \"\\e60f\";\n}\n.icon-social-dribbble:before {\n  content: \"\\e00d\";\n}\n.icon-social-behance:before {\n  content: \"\\e610\";\n}\n.icon-social-foursqare:before {\n  content: \"\\e611\";\n}\n.icon-social-soundcloud:before {\n  content: \"\\e612\";\n}\n.icon-social-spotify:before {\n  content: \"\\e613\";\n}\n.icon-social-stumbleupon:before {\n  content: \"\\e614\";\n}\n.icon-social-youtube:before {\n  content: \"\\e008\";\n}\n.icon-social-dropbox:before {\n  content: \"\\e00c\";\n}\n/*!\nIonicons, v1.5.0\nCreated by Ben Sperry for the Ionic Framework, http://ionicons.com/\nhttps://twitter.com/benjsperry  https://twitter.com/ionicframework\nMIT License: https://github.com/driftyco/ionicons\n*/\n@font-face {\n  font-family: \"Ionicons\";\n  src: url(\"../fonts/ionicons.eot?v=1.5.0\");\n  src: url(\"../fonts/ionicons.eot?v=1.5.0#iefix\") format(\"embedded-opentype\"), url(\"../fonts/ionicons.ttf?v=1.5.0\") format(\"truetype\"), url(\"../fonts/ionicons.woff?v=1.5.0\") format(\"woff\"), url(\"../fonts/ionicons.svg?v=1.5.0#Ionicons\") format(\"svg\");\n  font-weight: normal;\n  font-style: normal;\n}\n.ion,\n.ion-loading-a,\n.ion-loading-b,\n.ion-loading-c,\n.ion-loading-d,\n.ion-looping,\n.ion-refreshing,\n.ion-ios7-reloading,\n.ionicons,\n.ion-alert,\n.ion-alert-circled,\n.ion-android-add,\n.ion-android-add-contact,\n.ion-android-alarm,\n.ion-android-archive,\n.ion-android-arrow-back,\n.ion-android-arrow-down-left,\n.ion-android-arrow-down-right,\n.ion-android-arrow-forward,\n.ion-android-arrow-up-left,\n.ion-android-arrow-up-right,\n.ion-android-battery,\n.ion-android-book,\n.ion-android-calendar,\n.ion-android-call,\n.ion-android-camera,\n.ion-android-chat,\n.ion-android-checkmark,\n.ion-android-clock,\n.ion-android-close,\n.ion-android-contact,\n.ion-android-contacts,\n.ion-android-data,\n.ion-android-developer,\n.ion-android-display,\n.ion-android-download,\n.ion-android-drawer,\n.ion-android-dropdown,\n.ion-android-earth,\n.ion-android-folder,\n.ion-android-forums,\n.ion-android-friends,\n.ion-android-hand,\n.ion-android-image,\n.ion-android-inbox,\n.ion-android-information,\n.ion-android-keypad,\n.ion-android-lightbulb,\n.ion-android-locate,\n.ion-android-location,\n.ion-android-mail,\n.ion-android-microphone,\n.ion-android-mixer,\n.ion-android-more,\n.ion-android-note,\n.ion-android-playstore,\n.ion-android-printer,\n.ion-android-promotion,\n.ion-android-reminder,\n.ion-android-remove,\n.ion-android-search,\n.ion-android-send,\n.ion-android-settings,\n.ion-android-share,\n.ion-android-social,\n.ion-android-social-user,\n.ion-android-sort,\n.ion-android-stair-drawer,\n.ion-android-star,\n.ion-android-stopwatch,\n.ion-android-storage,\n.ion-android-system-back,\n.ion-android-system-home,\n.ion-android-system-windows,\n.ion-android-timer,\n.ion-android-trash,\n.ion-android-user-menu,\n.ion-android-volume,\n.ion-android-wifi,\n.ion-aperture,\n.ion-archive,\n.ion-arrow-down-a,\n.ion-arrow-down-b,\n.ion-arrow-down-c,\n.ion-arrow-expand,\n.ion-arrow-graph-down-left,\n.ion-arrow-graph-down-right,\n.ion-arrow-graph-up-left,\n.ion-arrow-graph-up-right,\n.ion-arrow-left-a,\n.ion-arrow-left-b,\n.ion-arrow-left-c,\n.ion-arrow-move,\n.ion-arrow-resize,\n.ion-arrow-return-left,\n.ion-arrow-return-right,\n.ion-arrow-right-a,\n.ion-arrow-right-b,\n.ion-arrow-right-c,\n.ion-arrow-shrink,\n.ion-arrow-swap,\n.ion-arrow-up-a,\n.ion-arrow-up-b,\n.ion-arrow-up-c,\n.ion-asterisk,\n.ion-at,\n.ion-bag,\n.ion-battery-charging,\n.ion-battery-empty,\n.ion-battery-full,\n.ion-battery-half,\n.ion-battery-low,\n.ion-beaker,\n.ion-beer,\n.ion-bluetooth,\n.ion-bonfire,\n.ion-bookmark,\n.ion-briefcase,\n.ion-bug,\n.ion-calculator,\n.ion-calendar,\n.ion-camera,\n.ion-card,\n.ion-cash,\n.ion-chatbox,\n.ion-chatbox-working,\n.ion-chatboxes,\n.ion-chatbubble,\n.ion-chatbubble-working,\n.ion-chatbubbles,\n.ion-checkmark,\n.ion-checkmark-circled,\n.ion-checkmark-round,\n.ion-chevron-down,\n.ion-chevron-left,\n.ion-chevron-right,\n.ion-chevron-up,\n.ion-clipboard,\n.ion-clock,\n.ion-close,\n.ion-close-circled,\n.ion-close-round,\n.ion-closed-captioning,\n.ion-cloud,\n.ion-code,\n.ion-code-download,\n.ion-code-working,\n.ion-coffee,\n.ion-compass,\n.ion-compose,\n.ion-connection-bars,\n.ion-contrast,\n.ion-cube,\n.ion-disc,\n.ion-document,\n.ion-document-text,\n.ion-drag,\n.ion-earth,\n.ion-edit,\n.ion-egg,\n.ion-eject,\n.ion-email,\n.ion-eye,\n.ion-eye-disabled,\n.ion-female,\n.ion-filing,\n.ion-film-marker,\n.ion-fireball,\n.ion-flag,\n.ion-flame,\n.ion-flash,\n.ion-flash-off,\n.ion-flask,\n.ion-folder,\n.ion-fork,\n.ion-fork-repo,\n.ion-forward,\n.ion-funnel,\n.ion-game-controller-a,\n.ion-game-controller-b,\n.ion-gear-a,\n.ion-gear-b,\n.ion-grid,\n.ion-hammer,\n.ion-happy,\n.ion-headphone,\n.ion-heart,\n.ion-heart-broken,\n.ion-help,\n.ion-help-buoy,\n.ion-help-circled,\n.ion-home,\n.ion-icecream,\n.ion-icon-social-google-plus,\n.ion-icon-social-google-plus-outline,\n.ion-image,\n.ion-images,\n.ion-information,\n.ion-information-circled,\n.ion-ionic,\n.ion-ios7-alarm,\n.ion-ios7-alarm-outline,\n.ion-ios7-albums,\n.ion-ios7-albums-outline,\n.ion-ios7-americanfootball,\n.ion-ios7-americanfootball-outline,\n.ion-ios7-analytics,\n.ion-ios7-analytics-outline,\n.ion-ios7-arrow-back,\n.ion-ios7-arrow-down,\n.ion-ios7-arrow-forward,\n.ion-ios7-arrow-left,\n.ion-ios7-arrow-right,\n.ion-ios7-arrow-thin-down,\n.ion-ios7-arrow-thin-left,\n.ion-ios7-arrow-thin-right,\n.ion-ios7-arrow-thin-up,\n.ion-ios7-arrow-up,\n.ion-ios7-at,\n.ion-ios7-at-outline,\n.ion-ios7-barcode,\n.ion-ios7-barcode-outline,\n.ion-ios7-baseball,\n.ion-ios7-baseball-outline,\n.ion-ios7-basketball,\n.ion-ios7-basketball-outline,\n.ion-ios7-bell,\n.ion-ios7-bell-outline,\n.ion-ios7-bolt,\n.ion-ios7-bolt-outline,\n.ion-ios7-bookmarks,\n.ion-ios7-bookmarks-outline,\n.ion-ios7-box,\n.ion-ios7-box-outline,\n.ion-ios7-briefcase,\n.ion-ios7-briefcase-outline,\n.ion-ios7-browsers,\n.ion-ios7-browsers-outline,\n.ion-ios7-calculator,\n.ion-ios7-calculator-outline,\n.ion-ios7-calendar,\n.ion-ios7-calendar-outline,\n.ion-ios7-camera,\n.ion-ios7-camera-outline,\n.ion-ios7-cart,\n.ion-ios7-cart-outline,\n.ion-ios7-chatboxes,\n.ion-ios7-chatboxes-outline,\n.ion-ios7-chatbubble,\n.ion-ios7-chatbubble-outline,\n.ion-ios7-checkmark,\n.ion-ios7-checkmark-empty,\n.ion-ios7-checkmark-outline,\n.ion-ios7-circle-filled,\n.ion-ios7-circle-outline,\n.ion-ios7-clock,\n.ion-ios7-clock-outline,\n.ion-ios7-close,\n.ion-ios7-close-empty,\n.ion-ios7-close-outline,\n.ion-ios7-cloud,\n.ion-ios7-cloud-download,\n.ion-ios7-cloud-download-outline,\n.ion-ios7-cloud-outline,\n.ion-ios7-cloud-upload,\n.ion-ios7-cloud-upload-outline,\n.ion-ios7-cloudy,\n.ion-ios7-cloudy-night,\n.ion-ios7-cloudy-night-outline,\n.ion-ios7-cloudy-outline,\n.ion-ios7-cog,\n.ion-ios7-cog-outline,\n.ion-ios7-compose,\n.ion-ios7-compose-outline,\n.ion-ios7-contact,\n.ion-ios7-contact-outline,\n.ion-ios7-copy,\n.ion-ios7-copy-outline,\n.ion-ios7-download,\n.ion-ios7-download-outline,\n.ion-ios7-drag,\n.ion-ios7-email,\n.ion-ios7-email-outline,\n.ion-ios7-expand,\n.ion-ios7-eye,\n.ion-ios7-eye-outline,\n.ion-ios7-fastforward,\n.ion-ios7-fastforward-outline,\n.ion-ios7-filing,\n.ion-ios7-filing-outline,\n.ion-ios7-film,\n.ion-ios7-film-outline,\n.ion-ios7-flag,\n.ion-ios7-flag-outline,\n.ion-ios7-folder,\n.ion-ios7-folder-outline,\n.ion-ios7-football,\n.ion-ios7-football-outline,\n.ion-ios7-gear,\n.ion-ios7-gear-outline,\n.ion-ios7-glasses,\n.ion-ios7-glasses-outline,\n.ion-ios7-heart,\n.ion-ios7-heart-outline,\n.ion-ios7-help,\n.ion-ios7-help-empty,\n.ion-ios7-help-outline,\n.ion-ios7-home,\n.ion-ios7-home-outline,\n.ion-ios7-infinite,\n.ion-ios7-infinite-outline,\n.ion-ios7-information,\n.ion-ios7-information-empty,\n.ion-ios7-information-outline,\n.ion-ios7-ionic-outline,\n.ion-ios7-keypad,\n.ion-ios7-keypad-outline,\n.ion-ios7-lightbulb,\n.ion-ios7-lightbulb-outline,\n.ion-ios7-location,\n.ion-ios7-location-outline,\n.ion-ios7-locked,\n.ion-ios7-locked-outline,\n.ion-ios7-loop,\n.ion-ios7-loop-strong,\n.ion-ios7-medkit,\n.ion-ios7-medkit-outline,\n.ion-ios7-mic,\n.ion-ios7-mic-off,\n.ion-ios7-mic-outline,\n.ion-ios7-minus,\n.ion-ios7-minus-empty,\n.ion-ios7-minus-outline,\n.ion-ios7-monitor,\n.ion-ios7-monitor-outline,\n.ion-ios7-moon,\n.ion-ios7-moon-outline,\n.ion-ios7-more,\n.ion-ios7-more-outline,\n.ion-ios7-musical-note,\n.ion-ios7-musical-notes,\n.ion-ios7-navigate,\n.ion-ios7-navigate-outline,\n.ion-ios7-paper,\n.ion-ios7-paper-outline,\n.ion-ios7-paperplane,\n.ion-ios7-paperplane-outline,\n.ion-ios7-partlysunny,\n.ion-ios7-partlysunny-outline,\n.ion-ios7-pause,\n.ion-ios7-pause-outline,\n.ion-ios7-paw,\n.ion-ios7-paw-outline,\n.ion-ios7-people,\n.ion-ios7-people-outline,\n.ion-ios7-person,\n.ion-ios7-person-outline,\n.ion-ios7-personadd,\n.ion-ios7-personadd-outline,\n.ion-ios7-photos,\n.ion-ios7-photos-outline,\n.ion-ios7-pie,\n.ion-ios7-pie-outline,\n.ion-ios7-play,\n.ion-ios7-play-outline,\n.ion-ios7-plus,\n.ion-ios7-plus-empty,\n.ion-ios7-plus-outline,\n.ion-ios7-pricetag,\n.ion-ios7-pricetag-outline,\n.ion-ios7-pricetags,\n.ion-ios7-pricetags-outline,\n.ion-ios7-printer,\n.ion-ios7-printer-outline,\n.ion-ios7-pulse,\n.ion-ios7-pulse-strong,\n.ion-ios7-rainy,\n.ion-ios7-rainy-outline,\n.ion-ios7-recording,\n.ion-ios7-recording-outline,\n.ion-ios7-redo,\n.ion-ios7-redo-outline,\n.ion-ios7-refresh,\n.ion-ios7-refresh-empty,\n.ion-ios7-refresh-outline,\n.ion-ios7-reload,\n.ion-ios7-reverse-camera,\n.ion-ios7-reverse-camera-outline,\n.ion-ios7-rewind,\n.ion-ios7-rewind-outline,\n.ion-ios7-search,\n.ion-ios7-search-strong,\n.ion-ios7-settings,\n.ion-ios7-settings-strong,\n.ion-ios7-shrink,\n.ion-ios7-skipbackward,\n.ion-ios7-skipbackward-outline,\n.ion-ios7-skipforward,\n.ion-ios7-skipforward-outline,\n.ion-ios7-snowy,\n.ion-ios7-speedometer,\n.ion-ios7-speedometer-outline,\n.ion-ios7-star,\n.ion-ios7-star-half,\n.ion-ios7-star-outline,\n.ion-ios7-stopwatch,\n.ion-ios7-stopwatch-outline,\n.ion-ios7-sunny,\n.ion-ios7-sunny-outline,\n.ion-ios7-telephone,\n.ion-ios7-telephone-outline,\n.ion-ios7-tennisball,\n.ion-ios7-tennisball-outline,\n.ion-ios7-thunderstorm,\n.ion-ios7-thunderstorm-outline,\n.ion-ios7-time,\n.ion-ios7-time-outline,\n.ion-ios7-timer,\n.ion-ios7-timer-outline,\n.ion-ios7-toggle,\n.ion-ios7-toggle-outline,\n.ion-ios7-trash,\n.ion-ios7-trash-outline,\n.ion-ios7-undo,\n.ion-ios7-undo-outline,\n.ion-ios7-unlocked,\n.ion-ios7-unlocked-outline,\n.ion-ios7-upload,\n.ion-ios7-upload-outline,\n.ion-ios7-videocam,\n.ion-ios7-videocam-outline,\n.ion-ios7-volume-high,\n.ion-ios7-volume-low,\n.ion-ios7-wineglass,\n.ion-ios7-wineglass-outline,\n.ion-ios7-world,\n.ion-ios7-world-outline,\n.ion-ipad,\n.ion-iphone,\n.ion-ipod,\n.ion-jet,\n.ion-key,\n.ion-knife,\n.ion-laptop,\n.ion-leaf,\n.ion-levels,\n.ion-lightbulb,\n.ion-link,\n.ion-load-a,\n.ion-load-b,\n.ion-load-c,\n.ion-load-d,\n.ion-location,\n.ion-locked,\n.ion-log-in,\n.ion-log-out,\n.ion-loop,\n.ion-magnet,\n.ion-male,\n.ion-man,\n.ion-map,\n.ion-medkit,\n.ion-merge,\n.ion-mic-a,\n.ion-mic-b,\n.ion-mic-c,\n.ion-minus,\n.ion-minus-circled,\n.ion-minus-round,\n.ion-model-s,\n.ion-monitor,\n.ion-more,\n.ion-mouse,\n.ion-music-note,\n.ion-navicon,\n.ion-navicon-round,\n.ion-navigate,\n.ion-network,\n.ion-no-smoking,\n.ion-nuclear,\n.ion-outlet,\n.ion-paper-airplane,\n.ion-paperclip,\n.ion-pause,\n.ion-person,\n.ion-person-add,\n.ion-person-stalker,\n.ion-pie-graph,\n.ion-pin,\n.ion-pinpoint,\n.ion-pizza,\n.ion-plane,\n.ion-planet,\n.ion-play,\n.ion-playstation,\n.ion-plus,\n.ion-plus-circled,\n.ion-plus-round,\n.ion-podium,\n.ion-pound,\n.ion-power,\n.ion-pricetag,\n.ion-pricetags,\n.ion-printer,\n.ion-pull-request,\n.ion-qr-scanner,\n.ion-quote,\n.ion-radio-waves,\n.ion-record,\n.ion-refresh,\n.ion-reply,\n.ion-reply-all,\n.ion-ribbon-a,\n.ion-ribbon-b,\n.ion-sad,\n.ion-scissors,\n.ion-search,\n.ion-settings,\n.ion-share,\n.ion-shuffle,\n.ion-skip-backward,\n.ion-skip-forward,\n.ion-social-android,\n.ion-social-android-outline,\n.ion-social-apple,\n.ion-social-apple-outline,\n.ion-social-bitcoin,\n.ion-social-bitcoin-outline,\n.ion-social-buffer,\n.ion-social-buffer-outline,\n.ion-social-designernews,\n.ion-social-designernews-outline,\n.ion-social-dribbble,\n.ion-social-dribbble-outline,\n.ion-social-dropbox,\n.ion-social-dropbox-outline,\n.ion-social-facebook,\n.ion-social-facebook-outline,\n.ion-social-foursquare,\n.ion-social-foursquare-outline,\n.ion-social-freebsd-devil,\n.ion-social-github,\n.ion-social-github-outline,\n.ion-social-google,\n.ion-social-google-outline,\n.ion-social-googleplus,\n.ion-social-googleplus-outline,\n.ion-social-hackernews,\n.ion-social-hackernews-outline,\n.ion-social-instagram,\n.ion-social-instagram-outline,\n.ion-social-linkedin,\n.ion-social-linkedin-outline,\n.ion-social-pinterest,\n.ion-social-pinterest-outline,\n.ion-social-reddit,\n.ion-social-reddit-outline,\n.ion-social-rss,\n.ion-social-rss-outline,\n.ion-social-skype,\n.ion-social-skype-outline,\n.ion-social-tumblr,\n.ion-social-tumblr-outline,\n.ion-social-tux,\n.ion-social-twitter,\n.ion-social-twitter-outline,\n.ion-social-usd,\n.ion-social-usd-outline,\n.ion-social-vimeo,\n.ion-social-vimeo-outline,\n.ion-social-windows,\n.ion-social-windows-outline,\n.ion-social-wordpress,\n.ion-social-wordpress-outline,\n.ion-social-yahoo,\n.ion-social-yahoo-outline,\n.ion-social-youtube,\n.ion-social-youtube-outline,\n.ion-speakerphone,\n.ion-speedometer,\n.ion-spoon,\n.ion-star,\n.ion-stats-bars,\n.ion-steam,\n.ion-stop,\n.ion-thermometer,\n.ion-thumbsdown,\n.ion-thumbsup,\n.ion-toggle,\n.ion-toggle-filled,\n.ion-trash-a,\n.ion-trash-b,\n.ion-trophy,\n.ion-umbrella,\n.ion-university,\n.ion-unlocked,\n.ion-upload,\n.ion-usb,\n.ion-videocamera,\n.ion-volume-high,\n.ion-volume-low,\n.ion-volume-medium,\n.ion-volume-mute,\n.ion-wand,\n.ion-waterdrop,\n.ion-wifi,\n.ion-wineglass,\n.ion-woman,\n.ion-wrench,\n.ion-xbox {\n  display: inline-block;\n  font-family: \"Ionicons\";\n  speak: none;\n  font-style: normal;\n  font-weight: normal;\n  font-variant: normal;\n  text-transform: none;\n  text-rendering: auto;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.ion-spin,\n.ion-loading-a,\n.ion-loading-b,\n.ion-loading-c,\n.ion-loading-d,\n.ion-looping,\n.ion-refreshing,\n.ion-ios7-reloading {\n  -webkit-animation: spin 1s infinite linear;\n  -moz-animation: spin 1s infinite linear;\n  -o-animation: spin 1s infinite linear;\n  animation: spin 1s infinite linear;\n}\n@-moz-keyframes spin {\n  0% {\n    -moz-transform: rotate(0deg);\n  }\n  100% {\n    -moz-transform: rotate(359deg);\n  }\n}\n@-webkit-keyframes spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n  }\n}\n@-o-keyframes spin {\n  0% {\n    -o-transform: rotate(0deg);\n  }\n  100% {\n    -o-transform: rotate(359deg);\n  }\n}\n@-ms-keyframes spin {\n  0% {\n    -ms-transform: rotate(0deg);\n  }\n  100% {\n    -ms-transform: rotate(359deg);\n  }\n}\n@keyframes spin {\n  0% {\n    transform: rotate(0deg);\n  }\n  100% {\n    transform: rotate(359deg);\n  }\n}\n.ion-loading-a {\n  -webkit-animation-timing-function: steps(8, start);\n  -moz-animation-timing-function: steps(8, start);\n  animation-timing-function: steps(8, start);\n}\n.ion-alert:before {\n  content: \"\\f101\";\n}\n.ion-alert-circled:before {\n  content: \"\\f100\";\n}\n.ion-android-add:before {\n  content: \"\\f2c7\";\n}\n.ion-android-add-contact:before {\n  content: \"\\f2c6\";\n}\n.ion-android-alarm:before {\n  content: \"\\f2c8\";\n}\n.ion-android-archive:before {\n  content: \"\\f2c9\";\n}\n.ion-android-arrow-back:before {\n  content: \"\\f2ca\";\n}\n.ion-android-arrow-down-left:before {\n  content: \"\\f2cb\";\n}\n.ion-android-arrow-down-right:before {\n  content: \"\\f2cc\";\n}\n.ion-android-arrow-forward:before {\n  content: \"\\f30f\";\n}\n.ion-android-arrow-up-left:before {\n  content: \"\\f2cd\";\n}\n.ion-android-arrow-up-right:before {\n  content: \"\\f2ce\";\n}\n.ion-android-battery:before {\n  content: \"\\f2cf\";\n}\n.ion-android-book:before {\n  content: \"\\f2d0\";\n}\n.ion-android-calendar:before {\n  content: \"\\f2d1\";\n}\n.ion-android-call:before {\n  content: \"\\f2d2\";\n}\n.ion-android-camera:before {\n  content: \"\\f2d3\";\n}\n.ion-android-chat:before {\n  content: \"\\f2d4\";\n}\n.ion-android-checkmark:before {\n  content: \"\\f2d5\";\n}\n.ion-android-clock:before {\n  content: \"\\f2d6\";\n}\n.ion-android-close:before {\n  content: \"\\f2d7\";\n}\n.ion-android-contact:before {\n  content: \"\\f2d8\";\n}\n.ion-android-contacts:before {\n  content: \"\\f2d9\";\n}\n.ion-android-data:before {\n  content: \"\\f2da\";\n}\n.ion-android-developer:before {\n  content: \"\\f2db\";\n}\n.ion-android-display:before {\n  content: \"\\f2dc\";\n}\n.ion-android-download:before {\n  content: \"\\f2dd\";\n}\n.ion-android-drawer:before {\n  content: \"\\f310\";\n}\n.ion-android-dropdown:before {\n  content: \"\\f2de\";\n}\n.ion-android-earth:before {\n  content: \"\\f2df\";\n}\n.ion-android-folder:before {\n  content: \"\\f2e0\";\n}\n.ion-android-forums:before {\n  content: \"\\f2e1\";\n}\n.ion-android-friends:before {\n  content: \"\\f2e2\";\n}\n.ion-android-hand:before {\n  content: \"\\f2e3\";\n}\n.ion-android-image:before {\n  content: \"\\f2e4\";\n}\n.ion-android-inbox:before {\n  content: \"\\f2e5\";\n}\n.ion-android-information:before {\n  content: \"\\f2e6\";\n}\n.ion-android-keypad:before {\n  content: \"\\f2e7\";\n}\n.ion-android-lightbulb:before {\n  content: \"\\f2e8\";\n}\n.ion-android-locate:before {\n  content: \"\\f2e9\";\n}\n.ion-android-location:before {\n  content: \"\\f2ea\";\n}\n.ion-android-mail:before {\n  content: \"\\f2eb\";\n}\n.ion-android-microphone:before {\n  content: \"\\f2ec\";\n}\n.ion-android-mixer:before {\n  content: \"\\f2ed\";\n}\n.ion-android-more:before {\n  content: \"\\f2ee\";\n}\n.ion-android-note:before {\n  content: \"\\f2ef\";\n}\n.ion-android-playstore:before {\n  content: \"\\f2f0\";\n}\n.ion-android-printer:before {\n  content: \"\\f2f1\";\n}\n.ion-android-promotion:before {\n  content: \"\\f2f2\";\n}\n.ion-android-reminder:before {\n  content: \"\\f2f3\";\n}\n.ion-android-remove:before {\n  content: \"\\f2f4\";\n}\n.ion-android-search:before {\n  content: \"\\f2f5\";\n}\n.ion-android-send:before {\n  content: \"\\f2f6\";\n}\n.ion-android-settings:before {\n  content: \"\\f2f7\";\n}\n.ion-android-share:before {\n  content: \"\\f2f8\";\n}\n.ion-android-social:before {\n  content: \"\\f2fa\";\n}\n.ion-android-social-user:before {\n  content: \"\\f2f9\";\n}\n.ion-android-sort:before {\n  content: \"\\f2fb\";\n}\n.ion-android-stair-drawer:before {\n  content: \"\\f311\";\n}\n.ion-android-star:before {\n  content: \"\\f2fc\";\n}\n.ion-android-stopwatch:before {\n  content: \"\\f2fd\";\n}\n.ion-android-storage:before {\n  content: \"\\f2fe\";\n}\n.ion-android-system-back:before {\n  content: \"\\f2ff\";\n}\n.ion-android-system-home:before {\n  content: \"\\f300\";\n}\n.ion-android-system-windows:before {\n  content: \"\\f301\";\n}\n.ion-android-timer:before {\n  content: \"\\f302\";\n}\n.ion-android-trash:before {\n  content: \"\\f303\";\n}\n.ion-android-user-menu:before {\n  content: \"\\f312\";\n}\n.ion-android-volume:before {\n  content: \"\\f304\";\n}\n.ion-android-wifi:before {\n  content: \"\\f305\";\n}\n.ion-aperture:before {\n  content: \"\\f313\";\n}\n.ion-archive:before {\n  content: \"\\f102\";\n}\n.ion-arrow-down-a:before {\n  content: \"\\f103\";\n}\n.ion-arrow-down-b:before {\n  content: \"\\f104\";\n}\n.ion-arrow-down-c:before {\n  content: \"\\f105\";\n}\n.ion-arrow-expand:before {\n  content: \"\\f25e\";\n}\n.ion-arrow-graph-down-left:before {\n  content: \"\\f25f\";\n}\n.ion-arrow-graph-down-right:before {\n  content: \"\\f260\";\n}\n.ion-arrow-graph-up-left:before {\n  content: \"\\f261\";\n}\n.ion-arrow-graph-up-right:before {\n  content: \"\\f262\";\n}\n.ion-arrow-left-a:before {\n  content: \"\\f106\";\n}\n.ion-arrow-left-b:before {\n  content: \"\\f107\";\n}\n.ion-arrow-left-c:before {\n  content: \"\\f108\";\n}\n.ion-arrow-move:before {\n  content: \"\\f263\";\n}\n.ion-arrow-resize:before {\n  content: \"\\f264\";\n}\n.ion-arrow-return-left:before {\n  content: \"\\f265\";\n}\n.ion-arrow-return-right:before {\n  content: \"\\f266\";\n}\n.ion-arrow-right-a:before {\n  content: \"\\f109\";\n}\n.ion-arrow-right-b:before {\n  content: \"\\f10a\";\n}\n.ion-arrow-right-c:before {\n  content: \"\\f10b\";\n}\n.ion-arrow-shrink:before {\n  content: \"\\f267\";\n}\n.ion-arrow-swap:before {\n  content: \"\\f268\";\n}\n.ion-arrow-up-a:before {\n  content: \"\\f10c\";\n}\n.ion-arrow-up-b:before {\n  content: \"\\f10d\";\n}\n.ion-arrow-up-c:before {\n  content: \"\\f10e\";\n}\n.ion-asterisk:before {\n  content: \"\\f314\";\n}\n.ion-at:before {\n  content: \"\\f10f\";\n}\n.ion-bag:before {\n  content: \"\\f110\";\n}\n.ion-battery-charging:before {\n  content: \"\\f111\";\n}\n.ion-battery-empty:before {\n  content: \"\\f112\";\n}\n.ion-battery-full:before {\n  content: \"\\f113\";\n}\n.ion-battery-half:before {\n  content: \"\\f114\";\n}\n.ion-battery-low:before {\n  content: \"\\f115\";\n}\n.ion-beaker:before {\n  content: \"\\f269\";\n}\n.ion-beer:before {\n  content: \"\\f26a\";\n}\n.ion-bluetooth:before {\n  content: \"\\f116\";\n}\n.ion-bonfire:before {\n  content: \"\\f315\";\n}\n.ion-bookmark:before {\n  content: \"\\f26b\";\n}\n.ion-briefcase:before {\n  content: \"\\f26c\";\n}\n.ion-bug:before {\n  content: \"\\f2be\";\n}\n.ion-calculator:before {\n  content: \"\\f26d\";\n}\n.ion-calendar:before {\n  content: \"\\f117\";\n}\n.ion-camera:before {\n  content: \"\\f118\";\n}\n.ion-card:before {\n  content: \"\\f119\";\n}\n.ion-cash:before {\n  content: \"\\f316\";\n}\n.ion-chatbox:before {\n  content: \"\\f11b\";\n}\n.ion-chatbox-working:before {\n  content: \"\\f11a\";\n}\n.ion-chatboxes:before {\n  content: \"\\f11c\";\n}\n.ion-chatbubble:before {\n  content: \"\\f11e\";\n}\n.ion-chatbubble-working:before {\n  content: \"\\f11d\";\n}\n.ion-chatbubbles:before {\n  content: \"\\f11f\";\n}\n.ion-checkmark:before {\n  content: \"\\f122\";\n}\n.ion-checkmark-circled:before {\n  content: \"\\f120\";\n}\n.ion-checkmark-round:before {\n  content: \"\\f121\";\n}\n.ion-chevron-down:before {\n  content: \"\\f123\";\n}\n.ion-chevron-left:before {\n  content: \"\\f124\";\n}\n.ion-chevron-right:before {\n  content: \"\\f125\";\n}\n.ion-chevron-up:before {\n  content: \"\\f126\";\n}\n.ion-clipboard:before {\n  content: \"\\f127\";\n}\n.ion-clock:before {\n  content: \"\\f26e\";\n}\n.ion-close:before {\n  content: \"\\f12a\";\n}\n.ion-close-circled:before {\n  content: \"\\f128\";\n}\n.ion-close-round:before {\n  content: \"\\f129\";\n}\n.ion-closed-captioning:before {\n  content: \"\\f317\";\n}\n.ion-cloud:before {\n  content: \"\\f12b\";\n}\n.ion-code:before {\n  content: \"\\f271\";\n}\n.ion-code-download:before {\n  content: \"\\f26f\";\n}\n.ion-code-working:before {\n  content: \"\\f270\";\n}\n.ion-coffee:before {\n  content: \"\\f272\";\n}\n.ion-compass:before {\n  content: \"\\f273\";\n}\n.ion-compose:before {\n  content: \"\\f12c\";\n}\n.ion-connection-bars:before {\n  content: \"\\f274\";\n}\n.ion-contrast:before {\n  content: \"\\f275\";\n}\n.ion-cube:before {\n  content: \"\\f318\";\n}\n.ion-disc:before {\n  content: \"\\f12d\";\n}\n.ion-document:before {\n  content: \"\\f12f\";\n}\n.ion-document-text:before {\n  content: \"\\f12e\";\n}\n.ion-drag:before {\n  content: \"\\f130\";\n}\n.ion-earth:before {\n  content: \"\\f276\";\n}\n.ion-edit:before {\n  content: \"\\f2bf\";\n}\n.ion-egg:before {\n  content: \"\\f277\";\n}\n.ion-eject:before {\n  content: \"\\f131\";\n}\n.ion-email:before {\n  content: \"\\f132\";\n}\n.ion-eye:before {\n  content: \"\\f133\";\n}\n.ion-eye-disabled:before {\n  content: \"\\f306\";\n}\n.ion-female:before {\n  content: \"\\f278\";\n}\n.ion-filing:before {\n  content: \"\\f134\";\n}\n.ion-film-marker:before {\n  content: \"\\f135\";\n}\n.ion-fireball:before {\n  content: \"\\f319\";\n}\n.ion-flag:before {\n  content: \"\\f279\";\n}\n.ion-flame:before {\n  content: \"\\f31a\";\n}\n.ion-flash:before {\n  content: \"\\f137\";\n}\n.ion-flash-off:before {\n  content: \"\\f136\";\n}\n.ion-flask:before {\n  content: \"\\f138\";\n}\n.ion-folder:before {\n  content: \"\\f139\";\n}\n.ion-fork:before {\n  content: \"\\f27a\";\n}\n.ion-fork-repo:before {\n  content: \"\\f2c0\";\n}\n.ion-forward:before {\n  content: \"\\f13a\";\n}\n.ion-funnel:before {\n  content: \"\\f31b\";\n}\n.ion-game-controller-a:before {\n  content: \"\\f13b\";\n}\n.ion-game-controller-b:before {\n  content: \"\\f13c\";\n}\n.ion-gear-a:before {\n  content: \"\\f13d\";\n}\n.ion-gear-b:before {\n  content: \"\\f13e\";\n}\n.ion-grid:before {\n  content: \"\\f13f\";\n}\n.ion-hammer:before {\n  content: \"\\f27b\";\n}\n.ion-happy:before {\n  content: \"\\f31c\";\n}\n.ion-headphone:before {\n  content: \"\\f140\";\n}\n.ion-heart:before {\n  content: \"\\f141\";\n}\n.ion-heart-broken:before {\n  content: \"\\f31d\";\n}\n.ion-help:before {\n  content: \"\\f143\";\n}\n.ion-help-buoy:before {\n  content: \"\\f27c\";\n}\n.ion-help-circled:before {\n  content: \"\\f142\";\n}\n.ion-home:before {\n  content: \"\\f144\";\n}\n.ion-icecream:before {\n  content: \"\\f27d\";\n}\n.ion-icon-social-google-plus:before {\n  content: \"\\f146\";\n}\n.ion-icon-social-google-plus-outline:before {\n  content: \"\\f145\";\n}\n.ion-image:before {\n  content: \"\\f147\";\n}\n.ion-images:before {\n  content: \"\\f148\";\n}\n.ion-information:before {\n  content: \"\\f14a\";\n}\n.ion-information-circled:before {\n  content: \"\\f149\";\n}\n.ion-ionic:before {\n  content: \"\\f14b\";\n}\n.ion-ios7-alarm:before {\n  content: \"\\f14d\";\n}\n.ion-ios7-alarm-outline:before {\n  content: \"\\f14c\";\n}\n.ion-ios7-albums:before {\n  content: \"\\f14f\";\n}\n.ion-ios7-albums-outline:before {\n  content: \"\\f14e\";\n}\n.ion-ios7-americanfootball:before {\n  content: \"\\f31f\";\n}\n.ion-ios7-americanfootball-outline:before {\n  content: \"\\f31e\";\n}\n.ion-ios7-analytics:before {\n  content: \"\\f321\";\n}\n.ion-ios7-analytics-outline:before {\n  content: \"\\f320\";\n}\n.ion-ios7-arrow-back:before {\n  content: \"\\f150\";\n}\n.ion-ios7-arrow-down:before {\n  content: \"\\f151\";\n}\n.ion-ios7-arrow-forward:before {\n  content: \"\\f152\";\n}\n.ion-ios7-arrow-left:before {\n  content: \"\\f153\";\n}\n.ion-ios7-arrow-right:before {\n  content: \"\\f154\";\n}\n.ion-ios7-arrow-thin-down:before {\n  content: \"\\f27e\";\n}\n.ion-ios7-arrow-thin-left:before {\n  content: \"\\f27f\";\n}\n.ion-ios7-arrow-thin-right:before {\n  content: \"\\f280\";\n}\n.ion-ios7-arrow-thin-up:before {\n  content: \"\\f281\";\n}\n.ion-ios7-arrow-up:before {\n  content: \"\\f155\";\n}\n.ion-ios7-at:before {\n  content: \"\\f157\";\n}\n.ion-ios7-at-outline:before {\n  content: \"\\f156\";\n}\n.ion-ios7-barcode:before {\n  content: \"\\f323\";\n}\n.ion-ios7-barcode-outline:before {\n  content: \"\\f322\";\n}\n.ion-ios7-baseball:before {\n  content: \"\\f325\";\n}\n.ion-ios7-baseball-outline:before {\n  content: \"\\f324\";\n}\n.ion-ios7-basketball:before {\n  content: \"\\f327\";\n}\n.ion-ios7-basketball-outline:before {\n  content: \"\\f326\";\n}\n.ion-ios7-bell:before {\n  content: \"\\f159\";\n}\n.ion-ios7-bell-outline:before {\n  content: \"\\f158\";\n}\n.ion-ios7-bolt:before {\n  content: \"\\f15b\";\n}\n.ion-ios7-bolt-outline:before {\n  content: \"\\f15a\";\n}\n.ion-ios7-bookmarks:before {\n  content: \"\\f15d\";\n}\n.ion-ios7-bookmarks-outline:before {\n  content: \"\\f15c\";\n}\n.ion-ios7-box:before {\n  content: \"\\f15f\";\n}\n.ion-ios7-box-outline:before {\n  content: \"\\f15e\";\n}\n.ion-ios7-briefcase:before {\n  content: \"\\f283\";\n}\n.ion-ios7-briefcase-outline:before {\n  content: \"\\f282\";\n}\n.ion-ios7-browsers:before {\n  content: \"\\f161\";\n}\n.ion-ios7-browsers-outline:before {\n  content: \"\\f160\";\n}\n.ion-ios7-calculator:before {\n  content: \"\\f285\";\n}\n.ion-ios7-calculator-outline:before {\n  content: \"\\f284\";\n}\n.ion-ios7-calendar:before {\n  content: \"\\f163\";\n}\n.ion-ios7-calendar-outline:before {\n  content: \"\\f162\";\n}\n.ion-ios7-camera:before {\n  content: \"\\f165\";\n}\n.ion-ios7-camera-outline:before {\n  content: \"\\f164\";\n}\n.ion-ios7-cart:before {\n  content: \"\\f167\";\n}\n.ion-ios7-cart-outline:before {\n  content: \"\\f166\";\n}\n.ion-ios7-chatboxes:before {\n  content: \"\\f169\";\n}\n.ion-ios7-chatboxes-outline:before {\n  content: \"\\f168\";\n}\n.ion-ios7-chatbubble:before {\n  content: \"\\f16b\";\n}\n.ion-ios7-chatbubble-outline:before {\n  content: \"\\f16a\";\n}\n.ion-ios7-checkmark:before {\n  content: \"\\f16e\";\n}\n.ion-ios7-checkmark-empty:before {\n  content: \"\\f16c\";\n}\n.ion-ios7-checkmark-outline:before {\n  content: \"\\f16d\";\n}\n.ion-ios7-circle-filled:before {\n  content: \"\\f16f\";\n}\n.ion-ios7-circle-outline:before {\n  content: \"\\f170\";\n}\n.ion-ios7-clock:before {\n  content: \"\\f172\";\n}\n.ion-ios7-clock-outline:before {\n  content: \"\\f171\";\n}\n.ion-ios7-close:before {\n  content: \"\\f2bc\";\n}\n.ion-ios7-close-empty:before {\n  content: \"\\f2bd\";\n}\n.ion-ios7-close-outline:before {\n  content: \"\\f2bb\";\n}\n.ion-ios7-cloud:before {\n  content: \"\\f178\";\n}\n.ion-ios7-cloud-download:before {\n  content: \"\\f174\";\n}\n.ion-ios7-cloud-download-outline:before {\n  content: \"\\f173\";\n}\n.ion-ios7-cloud-outline:before {\n  content: \"\\f175\";\n}\n.ion-ios7-cloud-upload:before {\n  content: \"\\f177\";\n}\n.ion-ios7-cloud-upload-outline:before {\n  content: \"\\f176\";\n}\n.ion-ios7-cloudy:before {\n  content: \"\\f17a\";\n}\n.ion-ios7-cloudy-night:before {\n  content: \"\\f308\";\n}\n.ion-ios7-cloudy-night-outline:before {\n  content: \"\\f307\";\n}\n.ion-ios7-cloudy-outline:before {\n  content: \"\\f179\";\n}\n.ion-ios7-cog:before {\n  content: \"\\f17c\";\n}\n.ion-ios7-cog-outline:before {\n  content: \"\\f17b\";\n}\n.ion-ios7-compose:before {\n  content: \"\\f17e\";\n}\n.ion-ios7-compose-outline:before {\n  content: \"\\f17d\";\n}\n.ion-ios7-contact:before {\n  content: \"\\f180\";\n}\n.ion-ios7-contact-outline:before {\n  content: \"\\f17f\";\n}\n.ion-ios7-copy:before {\n  content: \"\\f182\";\n}\n.ion-ios7-copy-outline:before {\n  content: \"\\f181\";\n}\n.ion-ios7-download:before {\n  content: \"\\f184\";\n}\n.ion-ios7-download-outline:before {\n  content: \"\\f183\";\n}\n.ion-ios7-drag:before {\n  content: \"\\f185\";\n}\n.ion-ios7-email:before {\n  content: \"\\f187\";\n}\n.ion-ios7-email-outline:before {\n  content: \"\\f186\";\n}\n.ion-ios7-expand:before {\n  content: \"\\f30d\";\n}\n.ion-ios7-eye:before {\n  content: \"\\f189\";\n}\n.ion-ios7-eye-outline:before {\n  content: \"\\f188\";\n}\n.ion-ios7-fastforward:before {\n  content: \"\\f18b\";\n}\n.ion-ios7-fastforward-outline:before {\n  content: \"\\f18a\";\n}\n.ion-ios7-filing:before {\n  content: \"\\f18d\";\n}\n.ion-ios7-filing-outline:before {\n  content: \"\\f18c\";\n}\n.ion-ios7-film:before {\n  content: \"\\f18f\";\n}\n.ion-ios7-film-outline:before {\n  content: \"\\f18e\";\n}\n.ion-ios7-flag:before {\n  content: \"\\f191\";\n}\n.ion-ios7-flag-outline:before {\n  content: \"\\f190\";\n}\n.ion-ios7-folder:before {\n  content: \"\\f193\";\n}\n.ion-ios7-folder-outline:before {\n  content: \"\\f192\";\n}\n.ion-ios7-football:before {\n  content: \"\\f329\";\n}\n.ion-ios7-football-outline:before {\n  content: \"\\f328\";\n}\n.ion-ios7-gear:before {\n  content: \"\\f195\";\n}\n.ion-ios7-gear-outline:before {\n  content: \"\\f194\";\n}\n.ion-ios7-glasses:before {\n  content: \"\\f197\";\n}\n.ion-ios7-glasses-outline:before {\n  content: \"\\f196\";\n}\n.ion-ios7-heart:before {\n  content: \"\\f199\";\n}\n.ion-ios7-heart-outline:before {\n  content: \"\\f198\";\n}\n.ion-ios7-help:before {\n  content: \"\\f19c\";\n}\n.ion-ios7-help-empty:before {\n  content: \"\\f19a\";\n}\n.ion-ios7-help-outline:before {\n  content: \"\\f19b\";\n}\n.ion-ios7-home:before {\n  content: \"\\f32b\";\n}\n.ion-ios7-home-outline:before {\n  content: \"\\f32a\";\n}\n.ion-ios7-infinite:before {\n  content: \"\\f19e\";\n}\n.ion-ios7-infinite-outline:before {\n  content: \"\\f19d\";\n}\n.ion-ios7-information:before {\n  content: \"\\f1a1\";\n}\n.ion-ios7-information-empty:before {\n  content: \"\\f19f\";\n}\n.ion-ios7-information-outline:before {\n  content: \"\\f1a0\";\n}\n.ion-ios7-ionic-outline:before {\n  content: \"\\f1a2\";\n}\n.ion-ios7-keypad:before {\n  content: \"\\f1a4\";\n}\n.ion-ios7-keypad-outline:before {\n  content: \"\\f1a3\";\n}\n.ion-ios7-lightbulb:before {\n  content: \"\\f287\";\n}\n.ion-ios7-lightbulb-outline:before {\n  content: \"\\f286\";\n}\n.ion-ios7-location:before {\n  content: \"\\f1a6\";\n}\n.ion-ios7-location-outline:before {\n  content: \"\\f1a5\";\n}\n.ion-ios7-locked:before {\n  content: \"\\f1a8\";\n}\n.ion-ios7-locked-outline:before {\n  content: \"\\f1a7\";\n}\n.ion-ios7-loop:before {\n  content: \"\\f32d\";\n}\n.ion-ios7-loop-strong:before {\n  content: \"\\f32c\";\n}\n.ion-ios7-medkit:before {\n  content: \"\\f289\";\n}\n.ion-ios7-medkit-outline:before {\n  content: \"\\f288\";\n}\n.ion-ios7-mic:before {\n  content: \"\\f1ab\";\n}\n.ion-ios7-mic-off:before {\n  content: \"\\f1a9\";\n}\n.ion-ios7-mic-outline:before {\n  content: \"\\f1aa\";\n}\n.ion-ios7-minus:before {\n  content: \"\\f1ae\";\n}\n.ion-ios7-minus-empty:before {\n  content: \"\\f1ac\";\n}\n.ion-ios7-minus-outline:before {\n  content: \"\\f1ad\";\n}\n.ion-ios7-monitor:before {\n  content: \"\\f1b0\";\n}\n.ion-ios7-monitor-outline:before {\n  content: \"\\f1af\";\n}\n.ion-ios7-moon:before {\n  content: \"\\f1b2\";\n}\n.ion-ios7-moon-outline:before {\n  content: \"\\f1b1\";\n}\n.ion-ios7-more:before {\n  content: \"\\f1b4\";\n}\n.ion-ios7-more-outline:before {\n  content: \"\\f1b3\";\n}\n.ion-ios7-musical-note:before {\n  content: \"\\f1b5\";\n}\n.ion-ios7-musical-notes:before {\n  content: \"\\f1b6\";\n}\n.ion-ios7-navigate:before {\n  content: \"\\f1b8\";\n}\n.ion-ios7-navigate-outline:before {\n  content: \"\\f1b7\";\n}\n.ion-ios7-paper:before {\n  content: \"\\f32f\";\n}\n.ion-ios7-paper-outline:before {\n  content: \"\\f32e\";\n}\n.ion-ios7-paperplane:before {\n  content: \"\\f1ba\";\n}\n.ion-ios7-paperplane-outline:before {\n  content: \"\\f1b9\";\n}\n.ion-ios7-partlysunny:before {\n  content: \"\\f1bc\";\n}\n.ion-ios7-partlysunny-outline:before {\n  content: \"\\f1bb\";\n}\n.ion-ios7-pause:before {\n  content: \"\\f1be\";\n}\n.ion-ios7-pause-outline:before {\n  content: \"\\f1bd\";\n}\n.ion-ios7-paw:before {\n  content: \"\\f331\";\n}\n.ion-ios7-paw-outline:before {\n  content: \"\\f330\";\n}\n.ion-ios7-people:before {\n  content: \"\\f1c0\";\n}\n.ion-ios7-people-outline:before {\n  content: \"\\f1bf\";\n}\n.ion-ios7-person:before {\n  content: \"\\f1c2\";\n}\n.ion-ios7-person-outline:before {\n  content: \"\\f1c1\";\n}\n.ion-ios7-personadd:before {\n  content: \"\\f1c4\";\n}\n.ion-ios7-personadd-outline:before {\n  content: \"\\f1c3\";\n}\n.ion-ios7-photos:before {\n  content: \"\\f1c6\";\n}\n.ion-ios7-photos-outline:before {\n  content: \"\\f1c5\";\n}\n.ion-ios7-pie:before {\n  content: \"\\f28b\";\n}\n.ion-ios7-pie-outline:before {\n  content: \"\\f28a\";\n}\n.ion-ios7-play:before {\n  content: \"\\f1c8\";\n}\n.ion-ios7-play-outline:before {\n  content: \"\\f1c7\";\n}\n.ion-ios7-plus:before {\n  content: \"\\f1cb\";\n}\n.ion-ios7-plus-empty:before {\n  content: \"\\f1c9\";\n}\n.ion-ios7-plus-outline:before {\n  content: \"\\f1ca\";\n}\n.ion-ios7-pricetag:before {\n  content: \"\\f28d\";\n}\n.ion-ios7-pricetag-outline:before {\n  content: \"\\f28c\";\n}\n.ion-ios7-pricetags:before {\n  content: \"\\f333\";\n}\n.ion-ios7-pricetags-outline:before {\n  content: \"\\f332\";\n}\n.ion-ios7-printer:before {\n  content: \"\\f1cd\";\n}\n.ion-ios7-printer-outline:before {\n  content: \"\\f1cc\";\n}\n.ion-ios7-pulse:before {\n  content: \"\\f335\";\n}\n.ion-ios7-pulse-strong:before {\n  content: \"\\f334\";\n}\n.ion-ios7-rainy:before {\n  content: \"\\f1cf\";\n}\n.ion-ios7-rainy-outline:before {\n  content: \"\\f1ce\";\n}\n.ion-ios7-recording:before {\n  content: \"\\f1d1\";\n}\n.ion-ios7-recording-outline:before {\n  content: \"\\f1d0\";\n}\n.ion-ios7-redo:before {\n  content: \"\\f1d3\";\n}\n.ion-ios7-redo-outline:before {\n  content: \"\\f1d2\";\n}\n.ion-ios7-refresh:before {\n  content: \"\\f1d6\";\n}\n.ion-ios7-refresh-empty:before {\n  content: \"\\f1d4\";\n}\n.ion-ios7-refresh-outline:before {\n  content: \"\\f1d5\";\n}\n.ion-ios7-reload:before {\n  content: \"\\f28e\";\n}\n.ion-ios7-reverse-camera:before {\n  content: \"\\f337\";\n}\n.ion-ios7-reverse-camera-outline:before {\n  content: \"\\f336\";\n}\n.ion-ios7-rewind:before {\n  content: \"\\f1d8\";\n}\n.ion-ios7-rewind-outline:before {\n  content: \"\\f1d7\";\n}\n.ion-ios7-search:before {\n  content: \"\\f1da\";\n}\n.ion-ios7-search-strong:before {\n  content: \"\\f1d9\";\n}\n.ion-ios7-settings:before {\n  content: \"\\f339\";\n}\n.ion-ios7-settings-strong:before {\n  content: \"\\f338\";\n}\n.ion-ios7-shrink:before {\n  content: \"\\f30e\";\n}\n.ion-ios7-skipbackward:before {\n  content: \"\\f1dc\";\n}\n.ion-ios7-skipbackward-outline:before {\n  content: \"\\f1db\";\n}\n.ion-ios7-skipforward:before {\n  content: \"\\f1de\";\n}\n.ion-ios7-skipforward-outline:before {\n  content: \"\\f1dd\";\n}\n.ion-ios7-snowy:before {\n  content: \"\\f309\";\n}\n.ion-ios7-speedometer:before {\n  content: \"\\f290\";\n}\n.ion-ios7-speedometer-outline:before {\n  content: \"\\f28f\";\n}\n.ion-ios7-star:before {\n  content: \"\\f1e0\";\n}\n.ion-ios7-star-half:before {\n  content: \"\\f33a\";\n}\n.ion-ios7-star-outline:before {\n  content: \"\\f1df\";\n}\n.ion-ios7-stopwatch:before {\n  content: \"\\f1e2\";\n}\n.ion-ios7-stopwatch-outline:before {\n  content: \"\\f1e1\";\n}\n.ion-ios7-sunny:before {\n  content: \"\\f1e4\";\n}\n.ion-ios7-sunny-outline:before {\n  content: \"\\f1e3\";\n}\n.ion-ios7-telephone:before {\n  content: \"\\f1e6\";\n}\n.ion-ios7-telephone-outline:before {\n  content: \"\\f1e5\";\n}\n.ion-ios7-tennisball:before {\n  content: \"\\f33c\";\n}\n.ion-ios7-tennisball-outline:before {\n  content: \"\\f33b\";\n}\n.ion-ios7-thunderstorm:before {\n  content: \"\\f1e8\";\n}\n.ion-ios7-thunderstorm-outline:before {\n  content: \"\\f1e7\";\n}\n.ion-ios7-time:before {\n  content: \"\\f292\";\n}\n.ion-ios7-time-outline:before {\n  content: \"\\f291\";\n}\n.ion-ios7-timer:before {\n  content: \"\\f1ea\";\n}\n.ion-ios7-timer-outline:before {\n  content: \"\\f1e9\";\n}\n.ion-ios7-toggle:before {\n  content: \"\\f33e\";\n}\n.ion-ios7-toggle-outline:before {\n  content: \"\\f33d\";\n}\n.ion-ios7-trash:before {\n  content: \"\\f1ec\";\n}\n.ion-ios7-trash-outline:before {\n  content: \"\\f1eb\";\n}\n.ion-ios7-undo:before {\n  content: \"\\f1ee\";\n}\n.ion-ios7-undo-outline:before {\n  content: \"\\f1ed\";\n}\n.ion-ios7-unlocked:before {\n  content: \"\\f1f0\";\n}\n.ion-ios7-unlocked-outline:before {\n  content: \"\\f1ef\";\n}\n.ion-ios7-upload:before {\n  content: \"\\f1f2\";\n}\n.ion-ios7-upload-outline:before {\n  content: \"\\f1f1\";\n}\n.ion-ios7-videocam:before {\n  content: \"\\f1f4\";\n}\n.ion-ios7-videocam-outline:before {\n  content: \"\\f1f3\";\n}\n.ion-ios7-volume-high:before {\n  content: \"\\f1f5\";\n}\n.ion-ios7-volume-low:before {\n  content: \"\\f1f6\";\n}\n.ion-ios7-wineglass:before {\n  content: \"\\f294\";\n}\n.ion-ios7-wineglass-outline:before {\n  content: \"\\f293\";\n}\n.ion-ios7-world:before {\n  content: \"\\f1f8\";\n}\n.ion-ios7-world-outline:before {\n  content: \"\\f1f7\";\n}\n.ion-ipad:before {\n  content: \"\\f1f9\";\n}\n.ion-iphone:before {\n  content: \"\\f1fa\";\n}\n.ion-ipod:before {\n  content: \"\\f1fb\";\n}\n.ion-jet:before {\n  content: \"\\f295\";\n}\n.ion-key:before {\n  content: \"\\f296\";\n}\n.ion-knife:before {\n  content: \"\\f297\";\n}\n.ion-laptop:before {\n  content: \"\\f1fc\";\n}\n.ion-leaf:before {\n  content: \"\\f1fd\";\n}\n.ion-levels:before {\n  content: \"\\f298\";\n}\n.ion-lightbulb:before {\n  content: \"\\f299\";\n}\n.ion-link:before {\n  content: \"\\f1fe\";\n}\n.ion-load-a:before {\n  content: \"\\f29a\";\n}\n.ion-load-b:before {\n  content: \"\\f29b\";\n}\n.ion-load-c:before {\n  content: \"\\f29c\";\n}\n.ion-load-d:before {\n  content: \"\\f29d\";\n}\n.ion-location:before {\n  content: \"\\f1ff\";\n}\n.ion-locked:before {\n  content: \"\\f200\";\n}\n.ion-log-in:before {\n  content: \"\\f29e\";\n}\n.ion-log-out:before {\n  content: \"\\f29f\";\n}\n.ion-loop:before {\n  content: \"\\f201\";\n}\n.ion-magnet:before {\n  content: \"\\f2a0\";\n}\n.ion-male:before {\n  content: \"\\f2a1\";\n}\n.ion-man:before {\n  content: \"\\f202\";\n}\n.ion-map:before {\n  content: \"\\f203\";\n}\n.ion-medkit:before {\n  content: \"\\f2a2\";\n}\n.ion-merge:before {\n  content: \"\\f33f\";\n}\n.ion-mic-a:before {\n  content: \"\\f204\";\n}\n.ion-mic-b:before {\n  content: \"\\f205\";\n}\n.ion-mic-c:before {\n  content: \"\\f206\";\n}\n.ion-minus:before {\n  content: \"\\f209\";\n}\n.ion-minus-circled:before {\n  content: \"\\f207\";\n}\n.ion-minus-round:before {\n  content: \"\\f208\";\n}\n.ion-model-s:before {\n  content: \"\\f2c1\";\n}\n.ion-monitor:before {\n  content: \"\\f20a\";\n}\n.ion-more:before {\n  content: \"\\f20b\";\n}\n.ion-mouse:before {\n  content: \"\\f340\";\n}\n.ion-music-note:before {\n  content: \"\\f20c\";\n}\n.ion-navicon:before {\n  content: \"\\f20e\";\n}\n.ion-navicon-round:before {\n  content: \"\\f20d\";\n}\n.ion-navigate:before {\n  content: \"\\f2a3\";\n}\n.ion-network:before {\n  content: \"\\f341\";\n}\n.ion-no-smoking:before {\n  content: \"\\f2c2\";\n}\n.ion-nuclear:before {\n  content: \"\\f2a4\";\n}\n.ion-outlet:before {\n  content: \"\\f342\";\n}\n.ion-paper-airplane:before {\n  content: \"\\f2c3\";\n}\n.ion-paperclip:before {\n  content: \"\\f20f\";\n}\n.ion-pause:before {\n  content: \"\\f210\";\n}\n.ion-person:before {\n  content: \"\\f213\";\n}\n.ion-person-add:before {\n  content: \"\\f211\";\n}\n.ion-person-stalker:before {\n  content: \"\\f212\";\n}\n.ion-pie-graph:before {\n  content: \"\\f2a5\";\n}\n.ion-pin:before {\n  content: \"\\f2a6\";\n}\n.ion-pinpoint:before {\n  content: \"\\f2a7\";\n}\n.ion-pizza:before {\n  content: \"\\f2a8\";\n}\n.ion-plane:before {\n  content: \"\\f214\";\n}\n.ion-planet:before {\n  content: \"\\f343\";\n}\n.ion-play:before {\n  content: \"\\f215\";\n}\n.ion-playstation:before {\n  content: \"\\f30a\";\n}\n.ion-plus:before {\n  content: \"\\f218\";\n}\n.ion-plus-circled:before {\n  content: \"\\f216\";\n}\n.ion-plus-round:before {\n  content: \"\\f217\";\n}\n.ion-podium:before {\n  content: \"\\f344\";\n}\n.ion-pound:before {\n  content: \"\\f219\";\n}\n.ion-power:before {\n  content: \"\\f2a9\";\n}\n.ion-pricetag:before {\n  content: \"\\f2aa\";\n}\n.ion-pricetags:before {\n  content: \"\\f2ab\";\n}\n.ion-printer:before {\n  content: \"\\f21a\";\n}\n.ion-pull-request:before {\n  content: \"\\f345\";\n}\n.ion-qr-scanner:before {\n  content: \"\\f346\";\n}\n.ion-quote:before {\n  content: \"\\f347\";\n}\n.ion-radio-waves:before {\n  content: \"\\f2ac\";\n}\n.ion-record:before {\n  content: \"\\f21b\";\n}\n.ion-refresh:before {\n  content: \"\\f21c\";\n}\n.ion-reply:before {\n  content: \"\\f21e\";\n}\n.ion-reply-all:before {\n  content: \"\\f21d\";\n}\n.ion-ribbon-a:before {\n  content: \"\\f348\";\n}\n.ion-ribbon-b:before {\n  content: \"\\f349\";\n}\n.ion-sad:before {\n  content: \"\\f34a\";\n}\n.ion-scissors:before {\n  content: \"\\f34b\";\n}\n.ion-search:before {\n  content: \"\\f21f\";\n}\n.ion-settings:before {\n  content: \"\\f2ad\";\n}\n.ion-share:before {\n  content: \"\\f220\";\n}\n.ion-shuffle:before {\n  content: \"\\f221\";\n}\n.ion-skip-backward:before {\n  content: \"\\f222\";\n}\n.ion-skip-forward:before {\n  content: \"\\f223\";\n}\n.ion-social-android:before {\n  content: \"\\f225\";\n}\n.ion-social-android-outline:before {\n  content: \"\\f224\";\n}\n.ion-social-apple:before {\n  content: \"\\f227\";\n}\n.ion-social-apple-outline:before {\n  content: \"\\f226\";\n}\n.ion-social-bitcoin:before {\n  content: \"\\f2af\";\n}\n.ion-social-bitcoin-outline:before {\n  content: \"\\f2ae\";\n}\n.ion-social-buffer:before {\n  content: \"\\f229\";\n}\n.ion-social-buffer-outline:before {\n  content: \"\\f228\";\n}\n.ion-social-designernews:before {\n  content: \"\\f22b\";\n}\n.ion-social-designernews-outline:before {\n  content: \"\\f22a\";\n}\n.ion-social-dribbble:before {\n  content: \"\\f22d\";\n}\n.ion-social-dribbble-outline:before {\n  content: \"\\f22c\";\n}\n.ion-social-dropbox:before {\n  content: \"\\f22f\";\n}\n.ion-social-dropbox-outline:before {\n  content: \"\\f22e\";\n}\n.ion-social-facebook:before {\n  content: \"\\f231\";\n}\n.ion-social-facebook-outline:before {\n  content: \"\\f230\";\n}\n.ion-social-foursquare:before {\n  content: \"\\f34d\";\n}\n.ion-social-foursquare-outline:before {\n  content: \"\\f34c\";\n}\n.ion-social-freebsd-devil:before {\n  content: \"\\f2c4\";\n}\n.ion-social-github:before {\n  content: \"\\f233\";\n}\n.ion-social-github-outline:before {\n  content: \"\\f232\";\n}\n.ion-social-google:before {\n  content: \"\\f34f\";\n}\n.ion-social-google-outline:before {\n  content: \"\\f34e\";\n}\n.ion-social-googleplus:before {\n  content: \"\\f235\";\n}\n.ion-social-googleplus-outline:before {\n  content: \"\\f234\";\n}\n.ion-social-hackernews:before {\n  content: \"\\f237\";\n}\n.ion-social-hackernews-outline:before {\n  content: \"\\f236\";\n}\n.ion-social-instagram:before {\n  content: \"\\f351\";\n}\n.ion-social-instagram-outline:before {\n  content: \"\\f350\";\n}\n.ion-social-linkedin:before {\n  content: \"\\f239\";\n}\n.ion-social-linkedin-outline:before {\n  content: \"\\f238\";\n}\n.ion-social-pinterest:before {\n  content: \"\\f2b1\";\n}\n.ion-social-pinterest-outline:before {\n  content: \"\\f2b0\";\n}\n.ion-social-reddit:before {\n  content: \"\\f23b\";\n}\n.ion-social-reddit-outline:before {\n  content: \"\\f23a\";\n}\n.ion-social-rss:before {\n  content: \"\\f23d\";\n}\n.ion-social-rss-outline:before {\n  content: \"\\f23c\";\n}\n.ion-social-skype:before {\n  content: \"\\f23f\";\n}\n.ion-social-skype-outline:before {\n  content: \"\\f23e\";\n}\n.ion-social-tumblr:before {\n  content: \"\\f241\";\n}\n.ion-social-tumblr-outline:before {\n  content: \"\\f240\";\n}\n.ion-social-tux:before {\n  content: \"\\f2c5\";\n}\n.ion-social-twitter:before {\n  content: \"\\f243\";\n}\n.ion-social-twitter-outline:before {\n  content: \"\\f242\";\n}\n.ion-social-usd:before {\n  content: \"\\f353\";\n}\n.ion-social-usd-outline:before {\n  content: \"\\f352\";\n}\n.ion-social-vimeo:before {\n  content: \"\\f245\";\n}\n.ion-social-vimeo-outline:before {\n  content: \"\\f244\";\n}\n.ion-social-windows:before {\n  content: \"\\f247\";\n}\n.ion-social-windows-outline:before {\n  content: \"\\f246\";\n}\n.ion-social-wordpress:before {\n  content: \"\\f249\";\n}\n.ion-social-wordpress-outline:before {\n  content: \"\\f248\";\n}\n.ion-social-yahoo:before {\n  content: \"\\f24b\";\n}\n.ion-social-yahoo-outline:before {\n  content: \"\\f24a\";\n}\n.ion-social-youtube:before {\n  content: \"\\f24d\";\n}\n.ion-social-youtube-outline:before {\n  content: \"\\f24c\";\n}\n.ion-speakerphone:before {\n  content: \"\\f2b2\";\n}\n.ion-speedometer:before {\n  content: \"\\f2b3\";\n}\n.ion-spoon:before {\n  content: \"\\f2b4\";\n}\n.ion-star:before {\n  content: \"\\f24e\";\n}\n.ion-stats-bars:before {\n  content: \"\\f2b5\";\n}\n.ion-steam:before {\n  content: \"\\f30b\";\n}\n.ion-stop:before {\n  content: \"\\f24f\";\n}\n.ion-thermometer:before {\n  content: \"\\f2b6\";\n}\n.ion-thumbsdown:before {\n  content: \"\\f250\";\n}\n.ion-thumbsup:before {\n  content: \"\\f251\";\n}\n.ion-toggle:before {\n  content: \"\\f355\";\n}\n.ion-toggle-filled:before {\n  content: \"\\f354\";\n}\n.ion-trash-a:before {\n  content: \"\\f252\";\n}\n.ion-trash-b:before {\n  content: \"\\f253\";\n}\n.ion-trophy:before {\n  content: \"\\f356\";\n}\n.ion-umbrella:before {\n  content: \"\\f2b7\";\n}\n.ion-university:before {\n  content: \"\\f357\";\n}\n.ion-unlocked:before {\n  content: \"\\f254\";\n}\n.ion-upload:before {\n  content: \"\\f255\";\n}\n.ion-usb:before {\n  content: \"\\f2b8\";\n}\n.ion-videocamera:before {\n  content: \"\\f256\";\n}\n.ion-volume-high:before {\n  content: \"\\f257\";\n}\n.ion-volume-low:before {\n  content: \"\\f258\";\n}\n.ion-volume-medium:before {\n  content: \"\\f259\";\n}\n.ion-volume-mute:before {\n  content: \"\\f25a\";\n}\n.ion-wand:before {\n  content: \"\\f358\";\n}\n.ion-waterdrop:before {\n  content: \"\\f25b\";\n}\n.ion-wifi:before {\n  content: \"\\f25c\";\n}\n.ion-wineglass:before {\n  content: \"\\f2b9\";\n}\n.ion-woman:before {\n  content: \"\\f25d\";\n}\n.ion-wrench:before {\n  content: \"\\f2ba\";\n}\n.ion-xbox:before {\n  content: \"\\f30c\";\n}\n/*!\n *  Weather Icons 2.0\n *  Updated August 1, 2015\n *  Weather themed icons for Bootstrap\n *  Author - Erik Flowers - erik@helloerik.com\n *  Email: erik@helloerik.com\n *  Twitter: http://twitter.com/Erik_UX\n *  ------------------------------------------------------------------------------\n *  Maintained at http://erikflowers.github.io/weather-icons\n *\n *  License\n *  ------------------------------------------------------------------------------\n *  - Font licensed under SIL OFL 1.1 -\n *    http://scripts.sil.org/OFL\n *  - CSS, SCSS and LESS are licensed under MIT License -\n *    http://opensource.org/licenses/mit-license.html\n *  - Documentation licensed under CC BY 3.0 -\n *    http://creativecommons.org/licenses/by/3.0/\n *  - Inspired by and works great as a companion with Font Awesome\n *    \"Font Awesome by Dave Gandy - http://fontawesome.io\"\n */\n@font-face {\n  font-family: 'weathericons';\n  src: url('../fonts/weathericons-regular-webfont.eot');\n  src: url('../fonts/weathericons-regular-webfont.eot?#iefix') format('embedded-opentype'), url('../fonts/weathericons-regular-webfont.woff2') format('woff2'), url('../fonts/weathericons-regular-webfont.woff') format('woff'), url('../fonts/weathericons-regular-webfont.ttf') format('truetype'), url('../fonts/weathericons-regular-webfont.svg#weather_iconsregular') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n.wi {\n  display: inline-block;\n  font-family: 'weathericons';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.wi-fw {\n  text-align: center;\n  width: 1.4em;\n}\n.wi-rotate-90 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n  -webkit-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n.wi-rotate-180 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n  -webkit-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n.wi-rotate-270 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n  -webkit-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n.wi-flip-horizontal {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);\n  -webkit-transform: scale(-1, 1);\n  -ms-transform: scale(-1, 1);\n  transform: scale(-1, 1);\n}\n.wi-flip-vertical {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n  -webkit-transform: scale(1, -1);\n  -ms-transform: scale(1, -1);\n  transform: scale(1, -1);\n}\n.wi-day-sunny:before {\n  content: \"\\f00d\";\n}\n.wi-day-cloudy:before {\n  content: \"\\f002\";\n}\n.wi-day-cloudy-gusts:before {\n  content: \"\\f000\";\n}\n.wi-day-cloudy-windy:before {\n  content: \"\\f001\";\n}\n.wi-day-fog:before {\n  content: \"\\f003\";\n}\n.wi-day-hail:before {\n  content: \"\\f004\";\n}\n.wi-day-haze:before {\n  content: \"\\f0b6\";\n}\n.wi-day-lightning:before {\n  content: \"\\f005\";\n}\n.wi-day-rain:before {\n  content: \"\\f008\";\n}\n.wi-day-rain-mix:before {\n  content: \"\\f006\";\n}\n.wi-day-rain-wind:before {\n  content: \"\\f007\";\n}\n.wi-day-showers:before {\n  content: \"\\f009\";\n}\n.wi-day-sleet:before {\n  content: \"\\f0b2\";\n}\n.wi-day-sleet-storm:before {\n  content: \"\\f068\";\n}\n.wi-day-snow:before {\n  content: \"\\f00a\";\n}\n.wi-day-snow-thunderstorm:before {\n  content: \"\\f06b\";\n}\n.wi-day-snow-wind:before {\n  content: \"\\f065\";\n}\n.wi-day-sprinkle:before {\n  content: \"\\f00b\";\n}\n.wi-day-storm-showers:before {\n  content: \"\\f00e\";\n}\n.wi-day-sunny-overcast:before {\n  content: \"\\f00c\";\n}\n.wi-day-thunderstorm:before {\n  content: \"\\f010\";\n}\n.wi-day-windy:before {\n  content: \"\\f085\";\n}\n.wi-solar-eclipse:before {\n  content: \"\\f06e\";\n}\n.wi-hot:before {\n  content: \"\\f072\";\n}\n.wi-day-cloudy-high:before {\n  content: \"\\f07d\";\n}\n.wi-day-light-wind:before {\n  content: \"\\f0c4\";\n}\n.wi-night-clear:before {\n  content: \"\\f02e\";\n}\n.wi-night-alt-cloudy:before {\n  content: \"\\f086\";\n}\n.wi-night-alt-cloudy-gusts:before {\n  content: \"\\f022\";\n}\n.wi-night-alt-cloudy-windy:before {\n  content: \"\\f023\";\n}\n.wi-night-alt-hail:before {\n  content: \"\\f024\";\n}\n.wi-night-alt-lightning:before {\n  content: \"\\f025\";\n}\n.wi-night-alt-rain:before {\n  content: \"\\f028\";\n}\n.wi-night-alt-rain-mix:before {\n  content: \"\\f026\";\n}\n.wi-night-alt-rain-wind:before {\n  content: \"\\f027\";\n}\n.wi-night-alt-showers:before {\n  content: \"\\f029\";\n}\n.wi-night-alt-sleet:before {\n  content: \"\\f0b4\";\n}\n.wi-night-alt-sleet-storm:before {\n  content: \"\\f06a\";\n}\n.wi-night-alt-snow:before {\n  content: \"\\f02a\";\n}\n.wi-night-alt-snow-thunderstorm:before {\n  content: \"\\f06d\";\n}\n.wi-night-alt-snow-wind:before {\n  content: \"\\f067\";\n}\n.wi-night-alt-sprinkle:before {\n  content: \"\\f02b\";\n}\n.wi-night-alt-storm-showers:before {\n  content: \"\\f02c\";\n}\n.wi-night-alt-thunderstorm:before {\n  content: \"\\f02d\";\n}\n.wi-night-cloudy:before {\n  content: \"\\f031\";\n}\n.wi-night-cloudy-gusts:before {\n  content: \"\\f02f\";\n}\n.wi-night-cloudy-windy:before {\n  content: \"\\f030\";\n}\n.wi-night-fog:before {\n  content: \"\\f04a\";\n}\n.wi-night-hail:before {\n  content: \"\\f032\";\n}\n.wi-night-lightning:before {\n  content: \"\\f033\";\n}\n.wi-night-partly-cloudy:before {\n  content: \"\\f083\";\n}\n.wi-night-rain:before {\n  content: \"\\f036\";\n}\n.wi-night-rain-mix:before {\n  content: \"\\f034\";\n}\n.wi-night-rain-wind:before {\n  content: \"\\f035\";\n}\n.wi-night-showers:before {\n  content: \"\\f037\";\n}\n.wi-night-sleet:before {\n  content: \"\\f0b3\";\n}\n.wi-night-sleet-storm:before {\n  content: \"\\f069\";\n}\n.wi-night-snow:before {\n  content: \"\\f038\";\n}\n.wi-night-snow-thunderstorm:before {\n  content: \"\\f06c\";\n}\n.wi-night-snow-wind:before {\n  content: \"\\f066\";\n}\n.wi-night-sprinkle:before {\n  content: \"\\f039\";\n}\n.wi-night-storm-showers:before {\n  content: \"\\f03a\";\n}\n.wi-night-thunderstorm:before {\n  content: \"\\f03b\";\n}\n.wi-lunar-eclipse:before {\n  content: \"\\f070\";\n}\n.wi-stars:before {\n  content: \"\\f077\";\n}\n.wi-storm-showers:before {\n  content: \"\\f01d\";\n}\n.wi-thunderstorm:before {\n  content: \"\\f01e\";\n}\n.wi-night-alt-cloudy-high:before {\n  content: \"\\f07e\";\n}\n.wi-night-cloudy-high:before {\n  content: \"\\f080\";\n}\n.wi-night-alt-partly-cloudy:before {\n  content: \"\\f081\";\n}\n.wi-cloud:before {\n  content: \"\\f041\";\n}\n.wi-cloudy:before {\n  content: \"\\f013\";\n}\n.wi-cloudy-gusts:before {\n  content: \"\\f011\";\n}\n.wi-cloudy-windy:before {\n  content: \"\\f012\";\n}\n.wi-fog:before {\n  content: \"\\f014\";\n}\n.wi-hail:before {\n  content: \"\\f015\";\n}\n.wi-rain:before {\n  content: \"\\f019\";\n}\n.wi-rain-mix:before {\n  content: \"\\f017\";\n}\n.wi-rain-wind:before {\n  content: \"\\f018\";\n}\n.wi-showers:before {\n  content: \"\\f01a\";\n}\n.wi-sleet:before {\n  content: \"\\f0b5\";\n}\n.wi-snow:before {\n  content: \"\\f01b\";\n}\n.wi-sprinkle:before {\n  content: \"\\f01c\";\n}\n.wi-storm-showers:before {\n  content: \"\\f01d\";\n}\n.wi-thunderstorm:before {\n  content: \"\\f01e\";\n}\n.wi-snow-wind:before {\n  content: \"\\f064\";\n}\n.wi-snow:before {\n  content: \"\\f01b\";\n}\n.wi-smog:before {\n  content: \"\\f074\";\n}\n.wi-smoke:before {\n  content: \"\\f062\";\n}\n.wi-lightning:before {\n  content: \"\\f016\";\n}\n.wi-raindrops:before {\n  content: \"\\f04e\";\n}\n.wi-raindrop:before {\n  content: \"\\f078\";\n}\n.wi-dust:before {\n  content: \"\\f063\";\n}\n.wi-snowflake-cold:before {\n  content: \"\\f076\";\n}\n.wi-windy:before {\n  content: \"\\f021\";\n}\n.wi-strong-wind:before {\n  content: \"\\f050\";\n}\n.wi-sandstorm:before {\n  content: \"\\f082\";\n}\n.wi-earthquake:before {\n  content: \"\\f0c6\";\n}\n.wi-fire:before {\n  content: \"\\f0c7\";\n}\n.wi-flood:before {\n  content: \"\\f07c\";\n}\n.wi-meteor:before {\n  content: \"\\f071\";\n}\n.wi-tsunami:before {\n  content: \"\\f0c5\";\n}\n.wi-volcano:before {\n  content: \"\\f0c8\";\n}\n.wi-hurricane:before {\n  content: \"\\f073\";\n}\n.wi-tornado:before {\n  content: \"\\f056\";\n}\n.wi-small-craft-advisory:before {\n  content: \"\\f0cc\";\n}\n.wi-gale-warning:before {\n  content: \"\\f0cd\";\n}\n.wi-storm-warning:before {\n  content: \"\\f0ce\";\n}\n.wi-hurricane-warning:before {\n  content: \"\\f0cf\";\n}\n.wi-wind-direction:before {\n  content: \"\\f0b1\";\n}\n.wi-alien:before {\n  content: \"\\f075\";\n}\n.wi-celsius:before {\n  content: \"\\f03c\";\n}\n.wi-fahrenheit:before {\n  content: \"\\f045\";\n}\n.wi-degrees:before {\n  content: \"\\f042\";\n}\n.wi-thermometer:before {\n  content: \"\\f055\";\n}\n.wi-thermometer-exterior:before {\n  content: \"\\f053\";\n}\n.wi-thermometer-internal:before {\n  content: \"\\f054\";\n}\n.wi-cloud-down:before {\n  content: \"\\f03d\";\n}\n.wi-cloud-up:before {\n  content: \"\\f040\";\n}\n.wi-cloud-refresh:before {\n  content: \"\\f03e\";\n}\n.wi-horizon:before {\n  content: \"\\f047\";\n}\n.wi-horizon-alt:before {\n  content: \"\\f046\";\n}\n.wi-sunrise:before {\n  content: \"\\f051\";\n}\n.wi-sunset:before {\n  content: \"\\f052\";\n}\n.wi-moonrise:before {\n  content: \"\\f0c9\";\n}\n.wi-moonset:before {\n  content: \"\\f0ca\";\n}\n.wi-refresh:before {\n  content: \"\\f04c\";\n}\n.wi-refresh-alt:before {\n  content: \"\\f04b\";\n}\n.wi-umbrella:before {\n  content: \"\\f084\";\n}\n.wi-barometer:before {\n  content: \"\\f079\";\n}\n.wi-humidity:before {\n  content: \"\\f07a\";\n}\n.wi-na:before {\n  content: \"\\f07b\";\n}\n.wi-train:before {\n  content: \"\\f0cb\";\n}\n.wi-moon-new:before {\n  content: \"\\f095\";\n}\n.wi-moon-waxing-cresent-1:before {\n  content: \"\\f096\";\n}\n.wi-moon-waxing-cresent-2:before {\n  content: \"\\f097\";\n}\n.wi-moon-waxing-cresent-3:before {\n  content: \"\\f098\";\n}\n.wi-moon-waxing-cresent-4:before {\n  content: \"\\f099\";\n}\n.wi-moon-waxing-cresent-5:before {\n  content: \"\\f09a\";\n}\n.wi-moon-waxing-cresent-6:before {\n  content: \"\\f09b\";\n}\n.wi-moon-first-quarter:before {\n  content: \"\\f09c\";\n}\n.wi-moon-waxing-gibbous-1:before {\n  content: \"\\f09d\";\n}\n.wi-moon-waxing-gibbous-2:before {\n  content: \"\\f09e\";\n}\n.wi-moon-waxing-gibbous-3:before {\n  content: \"\\f09f\";\n}\n.wi-moon-waxing-gibbous-4:before {\n  content: \"\\f0a0\";\n}\n.wi-moon-waxing-gibbous-5:before {\n  content: \"\\f0a1\";\n}\n.wi-moon-waxing-gibbous-6:before {\n  content: \"\\f0a2\";\n}\n.wi-moon-full:before {\n  content: \"\\f0a3\";\n}\n.wi-moon-waning-gibbous-1:before {\n  content: \"\\f0a4\";\n}\n.wi-moon-waning-gibbous-2:before {\n  content: \"\\f0a5\";\n}\n.wi-moon-waning-gibbous-3:before {\n  content: \"\\f0a6\";\n}\n.wi-moon-waning-gibbous-4:before {\n  content: \"\\f0a7\";\n}\n.wi-moon-waning-gibbous-5:before {\n  content: \"\\f0a8\";\n}\n.wi-moon-waning-gibbous-6:before {\n  content: \"\\f0a9\";\n}\n.wi-moon-third-quarter:before {\n  content: \"\\f0aa\";\n}\n.wi-moon-waning-crescent-1:before {\n  content: \"\\f0ab\";\n}\n.wi-moon-waning-crescent-2:before {\n  content: \"\\f0ac\";\n}\n.wi-moon-waning-crescent-3:before {\n  content: \"\\f0ad\";\n}\n.wi-moon-waning-crescent-4:before {\n  content: \"\\f0ae\";\n}\n.wi-moon-waning-crescent-5:before {\n  content: \"\\f0af\";\n}\n.wi-moon-waning-crescent-6:before {\n  content: \"\\f0b0\";\n}\n.wi-moon-alt-new:before {\n  content: \"\\f0eb\";\n}\n.wi-moon-alt-waxing-cresent-1:before {\n  content: \"\\f0d0\";\n}\n.wi-moon-alt-waxing-cresent-2:before {\n  content: \"\\f0d1\";\n}\n.wi-moon-alt-waxing-cresent-3:before {\n  content: \"\\f0d2\";\n}\n.wi-moon-alt-waxing-cresent-4:before {\n  content: \"\\f0d3\";\n}\n.wi-moon-alt-waxing-cresent-5:before {\n  content: \"\\f0d4\";\n}\n.wi-moon-alt-waxing-cresent-6:before {\n  content: \"\\f0d5\";\n}\n.wi-moon-alt-first-quarter:before {\n  content: \"\\f0d6\";\n}\n.wi-moon-alt-waxing-gibbous-1:before {\n  content: \"\\f0d7\";\n}\n.wi-moon-alt-waxing-gibbous-2:before {\n  content: \"\\f0d8\";\n}\n.wi-moon-alt-waxing-gibbous-3:before {\n  content: \"\\f0d9\";\n}\n.wi-moon-alt-waxing-gibbous-4:before {\n  content: \"\\f0da\";\n}\n.wi-moon-alt-waxing-gibbous-5:before {\n  content: \"\\f0db\";\n}\n.wi-moon-alt-waxing-gibbous-6:before {\n  content: \"\\f0dc\";\n}\n.wi-moon-alt-full:before {\n  content: \"\\f0dd\";\n}\n.wi-moon-alt-waning-gibbous-1:before {\n  content: \"\\f0de\";\n}\n.wi-moon-alt-waning-gibbous-2:before {\n  content: \"\\f0df\";\n}\n.wi-moon-alt-waning-gibbous-3:before {\n  content: \"\\f0e0\";\n}\n.wi-moon-alt-waning-gibbous-4:before {\n  content: \"\\f0e1\";\n}\n.wi-moon-alt-waning-gibbous-5:before {\n  content: \"\\f0e2\";\n}\n.wi-moon-alt-waning-gibbous-6:before {\n  content: \"\\f0e3\";\n}\n.wi-moon-alt-third-quarter:before {\n  content: \"\\f0e4\";\n}\n.wi-moon-alt-waning-crescent-1:before {\n  content: \"\\f0e5\";\n}\n.wi-moon-alt-waning-crescent-2:before {\n  content: \"\\f0e6\";\n}\n.wi-moon-alt-waning-crescent-3:before {\n  content: \"\\f0e7\";\n}\n.wi-moon-alt-waning-crescent-4:before {\n  content: \"\\f0e8\";\n}\n.wi-moon-alt-waning-crescent-5:before {\n  content: \"\\f0e9\";\n}\n.wi-moon-alt-waning-crescent-6:before {\n  content: \"\\f0ea\";\n}\n.wi-moon-0:before {\n  content: \"\\f095\";\n}\n.wi-moon-1:before {\n  content: \"\\f096\";\n}\n.wi-moon-2:before {\n  content: \"\\f097\";\n}\n.wi-moon-3:before {\n  content: \"\\f098\";\n}\n.wi-moon-4:before {\n  content: \"\\f099\";\n}\n.wi-moon-5:before {\n  content: \"\\f09a\";\n}\n.wi-moon-6:before {\n  content: \"\\f09b\";\n}\n.wi-moon-7:before {\n  content: \"\\f09c\";\n}\n.wi-moon-8:before {\n  content: \"\\f09d\";\n}\n.wi-moon-9:before {\n  content: \"\\f09e\";\n}\n.wi-moon-10:before {\n  content: \"\\f09f\";\n}\n.wi-moon-11:before {\n  content: \"\\f0a0\";\n}\n.wi-moon-12:before {\n  content: \"\\f0a1\";\n}\n.wi-moon-13:before {\n  content: \"\\f0a2\";\n}\n.wi-moon-14:before {\n  content: \"\\f0a3\";\n}\n.wi-moon-15:before {\n  content: \"\\f0a4\";\n}\n.wi-moon-16:before {\n  content: \"\\f0a5\";\n}\n.wi-moon-17:before {\n  content: \"\\f0a6\";\n}\n.wi-moon-18:before {\n  content: \"\\f0a7\";\n}\n.wi-moon-19:before {\n  content: \"\\f0a8\";\n}\n.wi-moon-20:before {\n  content: \"\\f0a9\";\n}\n.wi-moon-21:before {\n  content: \"\\f0aa\";\n}\n.wi-moon-22:before {\n  content: \"\\f0ab\";\n}\n.wi-moon-23:before {\n  content: \"\\f0ac\";\n}\n.wi-moon-24:before {\n  content: \"\\f0ad\";\n}\n.wi-moon-25:before {\n  content: \"\\f0ae\";\n}\n.wi-moon-26:before {\n  content: \"\\f0af\";\n}\n.wi-moon-27:before {\n  content: \"\\f0b0\";\n}\n.wi-time-1:before {\n  content: \"\\f08a\";\n}\n.wi-time-2:before {\n  content: \"\\f08b\";\n}\n.wi-time-3:before {\n  content: \"\\f08c\";\n}\n.wi-time-4:before {\n  content: \"\\f08d\";\n}\n.wi-time-5:before {\n  content: \"\\f08e\";\n}\n.wi-time-6:before {\n  content: \"\\f08f\";\n}\n.wi-time-7:before {\n  content: \"\\f090\";\n}\n.wi-time-8:before {\n  content: \"\\f091\";\n}\n.wi-time-9:before {\n  content: \"\\f092\";\n}\n.wi-time-10:before {\n  content: \"\\f093\";\n}\n.wi-time-11:before {\n  content: \"\\f094\";\n}\n.wi-time-12:before {\n  content: \"\\f089\";\n}\n.wi-direction-up:before {\n  content: \"\\f058\";\n}\n.wi-direction-up-right:before {\n  content: \"\\f057\";\n}\n.wi-direction-right:before {\n  content: \"\\f04d\";\n}\n.wi-direction-down-right:before {\n  content: \"\\f088\";\n}\n.wi-direction-down:before {\n  content: \"\\f044\";\n}\n.wi-direction-down-left:before {\n  content: \"\\f043\";\n}\n.wi-direction-left:before {\n  content: \"\\f048\";\n}\n.wi-direction-up-left:before {\n  content: \"\\f087\";\n}\n.wi-wind-beaufort-0:before {\n  content: \"\\f0b7\";\n}\n.wi-wind-beaufort-1:before {\n  content: \"\\f0b8\";\n}\n.wi-wind-beaufort-2:before {\n  content: \"\\f0b9\";\n}\n.wi-wind-beaufort-3:before {\n  content: \"\\f0ba\";\n}\n.wi-wind-beaufort-4:before {\n  content: \"\\f0bb\";\n}\n.wi-wind-beaufort-5:before {\n  content: \"\\f0bc\";\n}\n.wi-wind-beaufort-6:before {\n  content: \"\\f0bd\";\n}\n.wi-wind-beaufort-7:before {\n  content: \"\\f0be\";\n}\n.wi-wind-beaufort-8:before {\n  content: \"\\f0bf\";\n}\n.wi-wind-beaufort-9:before {\n  content: \"\\f0c0\";\n}\n.wi-wind-beaufort-10:before {\n  content: \"\\f0c1\";\n}\n.wi-wind-beaufort-11:before {\n  content: \"\\f0c2\";\n}\n.wi-wind-beaufort-12:before {\n  content: \"\\f0c3\";\n}\n.wi-yahoo-0:before {\n  content: \"\\f056\";\n}\n.wi-yahoo-1:before {\n  content: \"\\f00e\";\n}\n.wi-yahoo-2:before {\n  content: \"\\f073\";\n}\n.wi-yahoo-3:before {\n  content: \"\\f01e\";\n}\n.wi-yahoo-4:before {\n  content: \"\\f01e\";\n}\n.wi-yahoo-5:before {\n  content: \"\\f017\";\n}\n.wi-yahoo-6:before {\n  content: \"\\f017\";\n}\n.wi-yahoo-7:before {\n  content: \"\\f017\";\n}\n.wi-yahoo-8:before {\n  content: \"\\f015\";\n}\n.wi-yahoo-9:before {\n  content: \"\\f01a\";\n}\n.wi-yahoo-10:before {\n  content: \"\\f015\";\n}\n.wi-yahoo-11:before {\n  content: \"\\f01a\";\n}\n.wi-yahoo-12:before {\n  content: \"\\f01a\";\n}\n.wi-yahoo-13:before {\n  content: \"\\f01b\";\n}\n.wi-yahoo-14:before {\n  content: \"\\f00a\";\n}\n.wi-yahoo-15:before {\n  content: \"\\f064\";\n}\n.wi-yahoo-16:before {\n  content: \"\\f01b\";\n}\n.wi-yahoo-17:before {\n  content: \"\\f015\";\n}\n.wi-yahoo-18:before {\n  content: \"\\f017\";\n}\n.wi-yahoo-19:before {\n  content: \"\\f063\";\n}\n.wi-yahoo-20:before {\n  content: \"\\f014\";\n}\n.wi-yahoo-21:before {\n  content: \"\\f021\";\n}\n.wi-yahoo-22:before {\n  content: \"\\f062\";\n}\n.wi-yahoo-23:before {\n  content: \"\\f050\";\n}\n.wi-yahoo-24:before {\n  content: \"\\f050\";\n}\n.wi-yahoo-25:before {\n  content: \"\\f076\";\n}\n.wi-yahoo-26:before {\n  content: \"\\f013\";\n}\n.wi-yahoo-27:before {\n  content: \"\\f031\";\n}\n.wi-yahoo-28:before {\n  content: \"\\f002\";\n}\n.wi-yahoo-29:before {\n  content: \"\\f031\";\n}\n.wi-yahoo-30:before {\n  content: \"\\f002\";\n}\n.wi-yahoo-31:before {\n  content: \"\\f02e\";\n}\n.wi-yahoo-32:before {\n  content: \"\\f00d\";\n}\n.wi-yahoo-33:before {\n  content: \"\\f083\";\n}\n.wi-yahoo-34:before {\n  content: \"\\f00c\";\n}\n.wi-yahoo-35:before {\n  content: \"\\f017\";\n}\n.wi-yahoo-36:before {\n  content: \"\\f072\";\n}\n.wi-yahoo-37:before {\n  content: \"\\f00e\";\n}\n.wi-yahoo-38:before {\n  content: \"\\f00e\";\n}\n.wi-yahoo-39:before {\n  content: \"\\f00e\";\n}\n.wi-yahoo-40:before {\n  content: \"\\f01a\";\n}\n.wi-yahoo-41:before {\n  content: \"\\f064\";\n}\n.wi-yahoo-42:before {\n  content: \"\\f01b\";\n}\n.wi-yahoo-43:before {\n  content: \"\\f064\";\n}\n.wi-yahoo-44:before {\n  content: \"\\f00c\";\n}\n.wi-yahoo-45:before {\n  content: \"\\f00e\";\n}\n.wi-yahoo-46:before {\n  content: \"\\f01b\";\n}\n.wi-yahoo-47:before {\n  content: \"\\f00e\";\n}\n.wi-yahoo-3200:before {\n  content: \"\\f077\";\n}\n.wi-forecast-io-clear-day:before {\n  content: \"\\f00d\";\n}\n.wi-forecast-io-clear-night:before {\n  content: \"\\f02e\";\n}\n.wi-forecast-io-rain:before {\n  content: \"\\f019\";\n}\n.wi-forecast-io-snow:before {\n  content: \"\\f01b\";\n}\n.wi-forecast-io-sleet:before {\n  content: \"\\f0b5\";\n}\n.wi-forecast-io-wind:before {\n  content: \"\\f050\";\n}\n.wi-forecast-io-fog:before {\n  content: \"\\f014\";\n}\n.wi-forecast-io-cloudy:before {\n  content: \"\\f013\";\n}\n.wi-forecast-io-partly-cloudy-day:before {\n  content: \"\\f002\";\n}\n.wi-forecast-io-partly-cloudy-night:before {\n  content: \"\\f031\";\n}\n.wi-forecast-io-hail:before {\n  content: \"\\f015\";\n}\n.wi-forecast-io-thunderstorm:before {\n  content: \"\\f01e\";\n}\n.wi-forecast-io-tornado:before {\n  content: \"\\f056\";\n}\n.wi-wmo4680-0:before,\n.wi-wmo4680-00:before {\n  content: \"\\f055\";\n}\n.wi-wmo4680-1:before,\n.wi-wmo4680-01:before {\n  content: \"\\f013\";\n}\n.wi-wmo4680-2:before,\n.wi-wmo4680-02:before {\n  content: \"\\f055\";\n}\n.wi-wmo4680-3:before,\n.wi-wmo4680-03:before {\n  content: \"\\f013\";\n}\n.wi-wmo4680-4:before,\n.wi-wmo4680-04:before {\n  content: \"\\f014\";\n}\n.wi-wmo4680-5:before,\n.wi-wmo4680-05:before {\n  content: \"\\f014\";\n}\n.wi-wmo4680-10:before {\n  content: \"\\f014\";\n}\n.wi-wmo4680-11:before {\n  content: \"\\f014\";\n}\n.wi-wmo4680-12:before {\n  content: \"\\f016\";\n}\n.wi-wmo4680-18:before {\n  content: \"\\f050\";\n}\n.wi-wmo4680-20:before {\n  content: \"\\f014\";\n}\n.wi-wmo4680-21:before {\n  content: \"\\f017\";\n}\n.wi-wmo4680-22:before {\n  content: \"\\f017\";\n}\n.wi-wmo4680-23:before {\n  content: \"\\f019\";\n}\n.wi-wmo4680-24:before {\n  content: \"\\f01b\";\n}\n.wi-wmo4680-25:before {\n  content: \"\\f015\";\n}\n.wi-wmo4680-26:before {\n  content: \"\\f01e\";\n}\n.wi-wmo4680-27:before {\n  content: \"\\f063\";\n}\n.wi-wmo4680-28:before {\n  content: \"\\f063\";\n}\n.wi-wmo4680-29:before {\n  content: \"\\f063\";\n}\n.wi-wmo4680-30:before {\n  content: \"\\f014\";\n}\n.wi-wmo4680-31:before {\n  content: \"\\f014\";\n}\n.wi-wmo4680-32:before {\n  content: \"\\f014\";\n}\n.wi-wmo4680-33:before {\n  content: \"\\f014\";\n}\n.wi-wmo4680-34:before {\n  content: \"\\f014\";\n}\n.wi-wmo4680-35:before {\n  content: \"\\f014\";\n}\n.wi-wmo4680-40:before {\n  content: \"\\f017\";\n}\n.wi-wmo4680-41:before {\n  content: \"\\f01c\";\n}\n.wi-wmo4680-42:before {\n  content: \"\\f019\";\n}\n.wi-wmo4680-43:before {\n  content: \"\\f01c\";\n}\n.wi-wmo4680-44:before {\n  content: \"\\f019\";\n}\n.wi-wmo4680-45:before {\n  content: \"\\f015\";\n}\n.wi-wmo4680-46:before {\n  content: \"\\f015\";\n}\n.wi-wmo4680-47:before {\n  content: \"\\f01b\";\n}\n.wi-wmo4680-48:before {\n  content: \"\\f01b\";\n}\n.wi-wmo4680-50:before {\n  content: \"\\f01c\";\n}\n.wi-wmo4680-51:before {\n  content: \"\\f01c\";\n}\n.wi-wmo4680-52:before {\n  content: \"\\f019\";\n}\n.wi-wmo4680-53:before {\n  content: \"\\f019\";\n}\n.wi-wmo4680-54:before {\n  content: \"\\f076\";\n}\n.wi-wmo4680-55:before {\n  content: \"\\f076\";\n}\n.wi-wmo4680-56:before {\n  content: \"\\f076\";\n}\n.wi-wmo4680-57:before {\n  content: \"\\f01c\";\n}\n.wi-wmo4680-58:before {\n  content: \"\\f019\";\n}\n.wi-wmo4680-60:before {\n  content: \"\\f01c\";\n}\n.wi-wmo4680-61:before {\n  content: \"\\f01c\";\n}\n.wi-wmo4680-62:before {\n  content: \"\\f019\";\n}\n.wi-wmo4680-63:before {\n  content: \"\\f019\";\n}\n.wi-wmo4680-64:before {\n  content: \"\\f015\";\n}\n.wi-wmo4680-65:before {\n  content: \"\\f015\";\n}\n.wi-wmo4680-66:before {\n  content: \"\\f015\";\n}\n.wi-wmo4680-67:before {\n  content: \"\\f017\";\n}\n.wi-wmo4680-68:before {\n  content: \"\\f017\";\n}\n.wi-wmo4680-70:before {\n  content: \"\\f01b\";\n}\n.wi-wmo4680-71:before {\n  content: \"\\f01b\";\n}\n.wi-wmo4680-72:before {\n  content: \"\\f01b\";\n}\n.wi-wmo4680-73:before {\n  content: \"\\f01b\";\n}\n.wi-wmo4680-74:before {\n  content: \"\\f076\";\n}\n.wi-wmo4680-75:before {\n  content: \"\\f076\";\n}\n.wi-wmo4680-76:before {\n  content: \"\\f076\";\n}\n.wi-wmo4680-77:before {\n  content: \"\\f01b\";\n}\n.wi-wmo4680-78:before {\n  content: \"\\f076\";\n}\n.wi-wmo4680-80:before {\n  content: \"\\f019\";\n}\n.wi-wmo4680-81:before {\n  content: \"\\f01c\";\n}\n.wi-wmo4680-82:before {\n  content: \"\\f019\";\n}\n.wi-wmo4680-83:before {\n  content: \"\\f019\";\n}\n.wi-wmo4680-84:before {\n  content: \"\\f01d\";\n}\n.wi-wmo4680-85:before {\n  content: \"\\f017\";\n}\n.wi-wmo4680-86:before {\n  content: \"\\f017\";\n}\n.wi-wmo4680-87:before {\n  content: \"\\f017\";\n}\n.wi-wmo4680-89:before {\n  content: \"\\f015\";\n}\n.wi-wmo4680-90:before {\n  content: \"\\f016\";\n}\n.wi-wmo4680-91:before {\n  content: \"\\f01d\";\n}\n.wi-wmo4680-92:before {\n  content: \"\\f01e\";\n}\n.wi-wmo4680-93:before {\n  content: \"\\f01e\";\n}\n.wi-wmo4680-94:before {\n  content: \"\\f016\";\n}\n.wi-wmo4680-95:before {\n  content: \"\\f01e\";\n}\n.wi-wmo4680-96:before {\n  content: \"\\f01e\";\n}\n.wi-wmo4680-99:before {\n  content: \"\\f056\";\n}\n.wi-owm-200:before {\n  content: \"\\f01e\";\n}\n.wi-owm-201:before {\n  content: \"\\f01e\";\n}\n.wi-owm-202:before {\n  content: \"\\f01e\";\n}\n.wi-owm-210:before {\n  content: \"\\f016\";\n}\n.wi-owm-211:before {\n  content: \"\\f016\";\n}\n.wi-owm-212:before {\n  content: \"\\f016\";\n}\n.wi-owm-221:before {\n  content: \"\\f016\";\n}\n.wi-owm-230:before {\n  content: \"\\f01e\";\n}\n.wi-owm-231:before {\n  content: \"\\f01e\";\n}\n.wi-owm-232:before {\n  content: \"\\f01e\";\n}\n.wi-owm-300:before {\n  content: \"\\f01c\";\n}\n.wi-owm-301:before {\n  content: \"\\f01c\";\n}\n.wi-owm-302:before {\n  content: \"\\f019\";\n}\n.wi-owm-310:before {\n  content: \"\\f017\";\n}\n.wi-owm-311:before {\n  content: \"\\f019\";\n}\n.wi-owm-312:before {\n  content: \"\\f019\";\n}\n.wi-owm-313:before {\n  content: \"\\f01a\";\n}\n.wi-owm-314:before {\n  content: \"\\f019\";\n}\n.wi-owm-321:before {\n  content: \"\\f01c\";\n}\n.wi-owm-500:before {\n  content: \"\\f01c\";\n}\n.wi-owm-501:before {\n  content: \"\\f019\";\n}\n.wi-owm-502:before {\n  content: \"\\f019\";\n}\n.wi-owm-503:before {\n  content: \"\\f019\";\n}\n.wi-owm-504:before {\n  content: \"\\f019\";\n}\n.wi-owm-511:before {\n  content: \"\\f017\";\n}\n.wi-owm-520:before {\n  content: \"\\f01a\";\n}\n.wi-owm-521:before {\n  content: \"\\f01a\";\n}\n.wi-owm-522:before {\n  content: \"\\f01a\";\n}\n.wi-owm-531:before {\n  content: \"\\f01d\";\n}\n.wi-owm-600:before {\n  content: \"\\f01b\";\n}\n.wi-owm-601:before {\n  content: \"\\f01b\";\n}\n.wi-owm-602:before {\n  content: \"\\f0b5\";\n}\n.wi-owm-611:before {\n  content: \"\\f017\";\n}\n.wi-owm-612:before {\n  content: \"\\f017\";\n}\n.wi-owm-615:before {\n  content: \"\\f017\";\n}\n.wi-owm-616:before {\n  content: \"\\f017\";\n}\n.wi-owm-620:before {\n  content: \"\\f017\";\n}\n.wi-owm-621:before {\n  content: \"\\f01b\";\n}\n.wi-owm-622:before {\n  content: \"\\f01b\";\n}\n.wi-owm-701:before {\n  content: \"\\f01a\";\n}\n.wi-owm-711:before {\n  content: \"\\f062\";\n}\n.wi-owm-721:before {\n  content: \"\\f0b6\";\n}\n.wi-owm-731:before {\n  content: \"\\f063\";\n}\n.wi-owm-741:before {\n  content: \"\\f014\";\n}\n.wi-owm-761:before {\n  content: \"\\f063\";\n}\n.wi-owm-762:before {\n  content: \"\\f063\";\n}\n.wi-owm-771:before {\n  content: \"\\f011\";\n}\n.wi-owm-781:before {\n  content: \"\\f056\";\n}\n.wi-owm-800:before {\n  content: \"\\f00d\";\n}\n.wi-owm-801:before {\n  content: \"\\f011\";\n}\n.wi-owm-802:before {\n  content: \"\\f011\";\n}\n.wi-owm-803:before {\n  content: \"\\f011\";\n}\n.wi-owm-803:before {\n  content: \"\\f012\";\n}\n.wi-owm-804:before {\n  content: \"\\f013\";\n}\n.wi-owm-900:before {\n  content: \"\\f056\";\n}\n.wi-owm-901:before {\n  content: \"\\f01d\";\n}\n.wi-owm-902:before {\n  content: \"\\f073\";\n}\n.wi-owm-903:before {\n  content: \"\\f076\";\n}\n.wi-owm-904:before {\n  content: \"\\f072\";\n}\n.wi-owm-905:before {\n  content: \"\\f021\";\n}\n.wi-owm-906:before {\n  content: \"\\f015\";\n}\n.wi-owm-957:before {\n  content: \"\\f050\";\n}\n.wi-owm-day-200:before {\n  content: \"\\f010\";\n}\n.wi-owm-day-201:before {\n  content: \"\\f010\";\n}\n.wi-owm-day-202:before {\n  content: \"\\f010\";\n}\n.wi-owm-day-210:before {\n  content: \"\\f005\";\n}\n.wi-owm-day-211:before {\n  content: \"\\f005\";\n}\n.wi-owm-day-212:before {\n  content: \"\\f005\";\n}\n.wi-owm-day-221:before {\n  content: \"\\f005\";\n}\n.wi-owm-day-230:before {\n  content: \"\\f010\";\n}\n.wi-owm-day-231:before {\n  content: \"\\f010\";\n}\n.wi-owm-day-232:before {\n  content: \"\\f010\";\n}\n.wi-owm-day-300:before {\n  content: \"\\f00b\";\n}\n.wi-owm-day-301:before {\n  content: \"\\f00b\";\n}\n.wi-owm-day-302:before {\n  content: \"\\f008\";\n}\n.wi-owm-day-310:before {\n  content: \"\\f008\";\n}\n.wi-owm-day-311:before {\n  content: \"\\f008\";\n}\n.wi-owm-day-312:before {\n  content: \"\\f008\";\n}\n.wi-owm-day-313:before {\n  content: \"\\f008\";\n}\n.wi-owm-day-314:before {\n  content: \"\\f008\";\n}\n.wi-owm-day-321:before {\n  content: \"\\f00b\";\n}\n.wi-owm-day-500:before {\n  content: \"\\f00b\";\n}\n.wi-owm-day-501:before {\n  content: \"\\f008\";\n}\n.wi-owm-day-502:before {\n  content: \"\\f008\";\n}\n.wi-owm-day-503:before {\n  content: \"\\f008\";\n}\n.wi-owm-day-504:before {\n  content: \"\\f008\";\n}\n.wi-owm-day-511:before {\n  content: \"\\f006\";\n}\n.wi-owm-day-520:before {\n  content: \"\\f009\";\n}\n.wi-owm-day-521:before {\n  content: \"\\f009\";\n}\n.wi-owm-day-522:before {\n  content: \"\\f009\";\n}\n.wi-owm-day-531:before {\n  content: \"\\f00e\";\n}\n.wi-owm-day-600:before {\n  content: \"\\f00a\";\n}\n.wi-owm-day-601:before {\n  content: \"\\f0b2\";\n}\n.wi-owm-day-602:before {\n  content: \"\\f00a\";\n}\n.wi-owm-day-611:before {\n  content: \"\\f006\";\n}\n.wi-owm-day-612:before {\n  content: \"\\f006\";\n}\n.wi-owm-day-615:before {\n  content: \"\\f006\";\n}\n.wi-owm-day-616:before {\n  content: \"\\f006\";\n}\n.wi-owm-day-620:before {\n  content: \"\\f006\";\n}\n.wi-owm-day-621:before {\n  content: \"\\f00a\";\n}\n.wi-owm-day-622:before {\n  content: \"\\f00a\";\n}\n.wi-owm-day-701:before {\n  content: \"\\f009\";\n}\n.wi-owm-day-711:before {\n  content: \"\\f062\";\n}\n.wi-owm-day-721:before {\n  content: \"\\f0b6\";\n}\n.wi-owm-day-731:before {\n  content: \"\\f063\";\n}\n.wi-owm-day-741:before {\n  content: \"\\f003\";\n}\n.wi-owm-day-761:before {\n  content: \"\\f063\";\n}\n.wi-owm-day-762:before {\n  content: \"\\f063\";\n}\n.wi-owm-day-781:before {\n  content: \"\\f056\";\n}\n.wi-owm-day-800:before {\n  content: \"\\f00d\";\n}\n.wi-owm-day-801:before {\n  content: \"\\f000\";\n}\n.wi-owm-day-802:before {\n  content: \"\\f000\";\n}\n.wi-owm-day-803:before {\n  content: \"\\f000\";\n}\n.wi-owm-day-804:before {\n  content: \"\\f00c\";\n}\n.wi-owm-day-900:before {\n  content: \"\\f056\";\n}\n.wi-owm-day-902:before {\n  content: \"\\f073\";\n}\n.wi-owm-day-903:before {\n  content: \"\\f076\";\n}\n.wi-owm-day-904:before {\n  content: \"\\f072\";\n}\n.wi-owm-day-906:before {\n  content: \"\\f004\";\n}\n.wi-owm-day-957:before {\n  content: \"\\f050\";\n}\n.wi-owm-night-200:before {\n  content: \"\\f02d\";\n}\n.wi-owm-night-201:before {\n  content: \"\\f02d\";\n}\n.wi-owm-night-202:before {\n  content: \"\\f02d\";\n}\n.wi-owm-night-210:before {\n  content: \"\\f025\";\n}\n.wi-owm-night-211:before {\n  content: \"\\f025\";\n}\n.wi-owm-night-212:before {\n  content: \"\\f025\";\n}\n.wi-owm-night-221:before {\n  content: \"\\f025\";\n}\n.wi-owm-night-230:before {\n  content: \"\\f02d\";\n}\n.wi-owm-night-231:before {\n  content: \"\\f02d\";\n}\n.wi-owm-night-232:before {\n  content: \"\\f02d\";\n}\n.wi-owm-night-300:before {\n  content: \"\\f02b\";\n}\n.wi-owm-night-301:before {\n  content: \"\\f02b\";\n}\n.wi-owm-night-302:before {\n  content: \"\\f028\";\n}\n.wi-owm-night-310:before {\n  content: \"\\f028\";\n}\n.wi-owm-night-311:before {\n  content: \"\\f028\";\n}\n.wi-owm-night-312:before {\n  content: \"\\f028\";\n}\n.wi-owm-night-313:before {\n  content: \"\\f028\";\n}\n.wi-owm-night-314:before {\n  content: \"\\f028\";\n}\n.wi-owm-night-321:before {\n  content: \"\\f02b\";\n}\n.wi-owm-night-500:before {\n  content: \"\\f02b\";\n}\n.wi-owm-night-501:before {\n  content: \"\\f028\";\n}\n.wi-owm-night-502:before {\n  content: \"\\f028\";\n}\n.wi-owm-night-503:before {\n  content: \"\\f028\";\n}\n.wi-owm-night-504:before {\n  content: \"\\f028\";\n}\n.wi-owm-night-511:before {\n  content: \"\\f026\";\n}\n.wi-owm-night-520:before {\n  content: \"\\f029\";\n}\n.wi-owm-night-521:before {\n  content: \"\\f029\";\n}\n.wi-owm-night-522:before {\n  content: \"\\f029\";\n}\n.wi-owm-night-531:before {\n  content: \"\\f02c\";\n}\n.wi-owm-night-600:before {\n  content: \"\\f02a\";\n}\n.wi-owm-night-601:before {\n  content: \"\\f0b4\";\n}\n.wi-owm-night-602:before {\n  content: \"\\f02a\";\n}\n.wi-owm-night-611:before {\n  content: \"\\f026\";\n}\n.wi-owm-night-612:before {\n  content: \"\\f026\";\n}\n.wi-owm-night-615:before {\n  content: \"\\f026\";\n}\n.wi-owm-night-616:before {\n  content: \"\\f026\";\n}\n.wi-owm-night-620:before {\n  content: \"\\f026\";\n}\n.wi-owm-night-621:before {\n  content: \"\\f02a\";\n}\n.wi-owm-night-622:before {\n  content: \"\\f02a\";\n}\n.wi-owm-night-701:before {\n  content: \"\\f029\";\n}\n.wi-owm-night-711:before {\n  content: \"\\f062\";\n}\n.wi-owm-night-721:before {\n  content: \"\\f0b6\";\n}\n.wi-owm-night-731:before {\n  content: \"\\f063\";\n}\n.wi-owm-night-741:before {\n  content: \"\\f04a\";\n}\n.wi-owm-night-761:before {\n  content: \"\\f063\";\n}\n.wi-owm-night-762:before {\n  content: \"\\f063\";\n}\n.wi-owm-night-781:before {\n  content: \"\\f056\";\n}\n.wi-owm-night-800:before {\n  content: \"\\f02e\";\n}\n.wi-owm-night-801:before {\n  content: \"\\f022\";\n}\n.wi-owm-night-802:before {\n  content: \"\\f022\";\n}\n.wi-owm-night-803:before {\n  content: \"\\f022\";\n}\n.wi-owm-night-804:before {\n  content: \"\\f086\";\n}\n.wi-owm-night-900:before {\n  content: \"\\f056\";\n}\n.wi-owm-night-902:before {\n  content: \"\\f073\";\n}\n.wi-owm-night-903:before {\n  content: \"\\f076\";\n}\n.wi-owm-night-904:before {\n  content: \"\\f072\";\n}\n.wi-owm-night-906:before {\n  content: \"\\f024\";\n}\n.wi-owm-night-957:before {\n  content: \"\\f050\";\n}\n"
  },
  {
    "path": "static/assets/css/pages.css",
    "content": "/*\nTemplate Name: UBold Dashboard\nAuthor: CoderThemes\nEmail: coderthemes@gmail.com\nFile: Pages\n*/\n/* =============\n   Calendar\n============= */\n.calendar {\n  float: left;\n  margin-bottom: 0px;\n}\n.fc-view {\n  margin-top: 30px;\n}\n.none-border .modal-footer {\n  border-top: none;\n}\n.fc-toolbar {\n  margin-bottom: 5px;\n  margin-top: 15px;\n}\n.fc-toolbar h2 {\n  font-size: 18px;\n  font-weight: 600;\n  line-height: 30px;\n  text-transform: uppercase;\n}\n.fc-day {\n  background: #ffffff;\n}\n.fc-toolbar .fc-state-active,\n.fc-toolbar .ui-state-active,\n.fc-toolbar button:focus,\n.fc-toolbar button:hover,\n.fc-toolbar .ui-state-hover {\n  z-index: 0;\n}\n.fc-widget-header {\n  border: 1px solid #ebeff2;\n}\n.fc-widget-content {\n  border: 1px solid #ebeff2;\n}\n.fc th.fc-widget-header {\n  background: #ebeff2;\n  font-size: 14px;\n  line-height: 20px;\n  padding: 10px 0px;\n  text-transform: uppercase;\n}\n.fc-button {\n  background: #ffffff;\n  border: 1px solid #ebeff2;\n  color: #555555;\n  text-transform: capitalize;\n}\n.fc-text-arrow {\n  font-family: inherit;\n  font-size: 16px;\n}\n.fc-state-hover {\n  background: #F5F5F5;\n}\n.fc-state-highlight {\n  background: #f0f0f0;\n}\n.fc-cell-overlay {\n  background: #f0f0f0;\n}\n.fc-unthemed .fc-today {\n  background: #ffffff;\n}\n.fc-event {\n  border-radius: 2px;\n  border: none;\n  cursor: move;\n  font-size: 13px;\n  margin: 5px 7px;\n  padding: 5px 5px;\n  text-align: center;\n}\n.external-event {\n  color: #ffffff;\n  cursor: move;\n  margin: 10px 0;\n  padding: 6px 10px;\n}\n.fc-basic-view td.fc-week-number span {\n  padding-right: 5px;\n}\n.fc-basic-view td.fc-day-number {\n  padding-right: 5px;\n}\n/* =============\n   Form Advanced\n============= */\n.bootstrap-tagsinput {\n  box-shadow: none;\n  padding: 3px 7px 6px;\n  border: 1px solid #e3e3e3;\n}\n.bootstrap-tagsinput .label-info {\n  background-color: #5fbeaa !important;\n  display: inline-block;\n  padding: 5px;\n}\n/* Multiple */\n.ms-container {\n  background: transparent url('../images/multiple-arrow.png') no-repeat 50% 50%;\n}\n.ms-container .ms-list {\n  box-shadow: none;\n  border: 1px solid #e3e3e3;\n}\n.ms-container .ms-list.ms-focus {\n  box-shadow: none;\n  border: 1px solid #aaaaaa;\n}\n.ms-container .ms-selectable li.ms-elem-selectable {\n  border: none;\n  padding: 5px 10px;\n}\n.ms-container .ms-selection li.ms-elem-selection {\n  border: none;\n  padding: 5px 10px;\n}\n.select2-container .select2-choice {\n  background-image: none !important;\n  border: none !important;\n  height: auto  !important;\n  padding: 0px !important;\n  line-height: 22px !important;\n  background-color: transparent !important;\n  box-shadow: none !important;\n}\n.select2-container .select2-choice .select2-arrow {\n  background-image: none !important;\n  background: transparent;\n  border: none;\n  width: 14px;\n  top: -2px;\n}\n.select2-container .select2-container-multi.form-control {\n  height: auto;\n}\n.select2-results .select2-highlighted {\n  color: #ffffff;\n  background-color: #5fbeaa;\n}\n.select2-drop-active {\n  border: 1px solid #e3e3e3 !important;\n  padding-top: 5px;\n  -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.15);\n  box-shadow: 0 2px 2px rgba(0, 0, 0, 0.15);\n  -moz-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.15);\n}\n.select2-search input {\n  border: 1px solid #e3e3e3;\n}\n.select2-container-multi {\n  width: 100%;\n}\n.select2-container-multi .select2-choices {\n  border: 1px solid #E3E3E3  !important;\n  box-shadow: none !important;\n  background-image: none  !important;\n  -webkit-border-radius: 4px !important;\n  border-radius: 4px !important;\n  -moz-border-radius: 4px !important;\n  background-clip: padding-box !important;\n  min-height: 38px;\n}\n.select2-container-multi .select2-choices .select2-search-choice {\n  padding: 4px 7px 4px 18px;\n  margin: 5px 0 3px 5px;\n  color: #555555;\n  background: #f5f5f5;\n  border-color: #e5e5e5;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n.select2-container-multi .select2-choices .select2-search-field input {\n  padding: 7px 7px 7px 10px;\n  font-family: inherit;\n}\n/* Bootstrap-select */\n.bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn) {\n  width: 100% !important;\n}\n.bootstrap-select .dropdown-toggle:focus {\n  outline: none !important;\n}\n.bootstrap-select .glyphicon {\n  padding-right: 6px;\n}\n/* Bootstrap filestyle */\n.icon-span-filestyle {\n  padding-right: 5px;\n}\n/* Bootstrap-touchSpin */\n.bootstrap-touchspin .input-group-btn-vertical .btn {\n  padding: 9px 12px;\n}\n.bootstrap-touchspin .input-group-btn-vertical i {\n  top: 4px;\n  left: 8px;\n}\n/* Wysiwig */\n.mce-content-body p {\n  color: #9398a0;\n  font-size: 14px;\n  font-weight: 300;\n}\n.mce-popover .mce-arrow:after {\n  border-bottom-color: red;\n}\n.mce-popover .mce-colorbutton-grid {\n  margin: 0px;\n  border: 1px solid #d7dce5 !important;\n  padding: 4px;\n}\n.mce-reset .mce-window-head {\n  border-bottom: 1px solid #d7dce5;\n}\n.mce-reset .mce-window-head .mce-title {\n  color: #707780;\n  font-size: 16px;\n  font-weight: 400;\n}\n.mce-reset .mce-textbox {\n  border-radius: 0px;\n  box-shadow: none;\n  outline: 0;\n  border-color: #d7dce5;\n  height: 30px;\n  font-weight: 300;\n  line-height: 30px;\n  color: #aaaaaa;\n  font-size: 14px;\n}\n.mce-reset .mce-textbox:focus {\n  box-shadow: none;\n  border-color: #5fbeaa;\n}\n.mce-reset .mce-checkbox .mce-ico {\n  background-image: none;\n  background-color: #ffffff;\n  border-radius: 0px;\n  border: 1px solid #d7dce5;\n}\n.mce-reset .mce-checkbox .mce-label {\n  color: #707780;\n  font-size: 12px;\n  font-weight: 400;\n}\n.mce-container {\n  border-radius: 0px !important;\n  border-width: 0px !important;\n}\n.mce-container .mce-menubar {\n  background-color: #f2f4f7 !important;\n  border: 1px solid #d7dce5 !important;\n  padding: 2px;\n}\n.mce-container .mce-menubar .mce-btn button span {\n  color: #707780;\n  font-size: 14px;\n  font-weight: 400;\n  text-transform: capitalize;\n}\n.mce-container .mce-menubar .mce-btn button .mce-caret {\n  border-top-color: #707780;\n}\n.mce-container .mce-menubar .mce-btn button:hover {\n  background-color: #e8ebf1;\n}\n.mce-container .mce-menubar .mce-btn.mce-active button {\n  background-color: #e8ebf1;\n}\n.mce-container .mce-btn {\n  background-color: #d7dce5;\n  background-image: none;\n  outline: 0;\n  border: 0px;\n  border-radius: 0px;\n}\n.mce-container .mce-btn button {\n  color: #ffffff;\n  font-size: 14px;\n  font-weight: 400;\n  text-shadow: none;\n}\n.mce-container .mce-btn:hover {\n  background-color: #b8c1d1;\n  background-image: none;\n}\n.mce-container .mce-primary {\n  background-color: #5fbeaa;\n  background-image: none;\n  outline: 0;\n  border: 0px;\n  border-radius: 0px;\n}\n.mce-container .mce-primary button {\n  color: #ffffff;\n  font-size: 14px;\n  font-weight: 400;\n  text-shadow: none;\n}\n.mce-container .mce-primary:hover {\n  background-color: #0c7cd5;\n  background-image: none;\n}\n.mce-container .mce-toolbar-grp {\n  background-color: #f2f4f7 !important;\n  border: 1px solid #d7dce5 !important;\n  border-top-width: 0px !important;\n  padding: 6px;\n}\n.mce-container .mce-edit-area {\n  border: 1px solid #d7dce5 !important;\n  border-width: 0px 1px !important;\n}\n.mce-container .mce-statusbar {\n  background-color: #f2f4f7 !important;\n  border: 1px solid #d7dce5 !important;\n}\n.mce-container .mce-statusbar .mce-path .mce-path-item {\n  color: #707780;\n  font-size: 14px;\n  font-weight: 400;\n}\n.mce-container .mce-widget {\n  color: #9398a0;\n  font-size: 14px;\n  font-weight: 400;\n  border-left: 1px solid transparent;\n}\n.mce-container .mce-btn-group {\n  border: 1px solid #e9ecf2 !important;\n}\n.mce-container .mce-btn-group .mce-btn {\n  box-shadow: none;\n  background-image: none;\n  background-color: #ffffff;\n  border-width: 0px;\n  border-radius: 0px !important;\n}\n.mce-container .mce-btn-group .mce-btn:hover,\n.mce-container .mce-btn-group .mce-btn:focus {\n  box-shadow: none;\n  background-image: none;\n  background-color: #ffffff;\n}\n.mce-container .mce-btn-group .mce-btn button span {\n  color: #707780;\n  font-size: 14px;\n  font-weight: 300;\n}\n.mce-container .mce-btn-group .mce-btn button .mce-caret {\n  color: #707780;\n  font-size: 14px;\n}\n.mce-container .mce-ico {\n  color: #707780;\n  font-size: 14px;\n}\n.mce-container .mce-panel {\n  background-image: none;\n}\n.mce-container.mce-menu {\n  border: 1px solid #d7dce5 !important;\n}\n.mce-container.mce-menu .mce-menu-item {\n  background-image: none;\n}\n.mce-container.mce-menu .mce-menu-item .mce-ico {\n  color: #5fbeaa;\n  font-size: 14px;\n}\n.mce-container.mce-menu .mce-menu-item .mce-text {\n  color: #707780;\n  font-size: 14px;\n  font-weight: 400;\n  text-transform: capitalize;\n}\n.mce-container.mce-menu .mce-menu-item .mce-menu-shortcut {\n  color: #aaaaaa;\n  font-size: 12px;\n  font-weight: 300;\n  text-transform: capitalize;\n}\n.mce-container.mce-menu .mce-menu-item:hover,\n.mce-container.mce-menu .mce-menu-item:focus,\n.mce-container.mce-menu .mce-menu-item.mce-selected {\n  background-color: #5fbeaa;\n}\n.mce-container.mce-menu .mce-menu-item:hover .mce-ico,\n.mce-container.mce-menu .mce-menu-item:focus .mce-ico,\n.mce-container.mce-menu .mce-menu-item.mce-selected .mce-ico,\n.mce-container.mce-menu .mce-menu-item:hover .mce-text,\n.mce-container.mce-menu .mce-menu-item:focus .mce-text,\n.mce-container.mce-menu .mce-menu-item.mce-selected .mce-text,\n.mce-container.mce-menu .mce-menu-item:hover .mce-menu-shortcut,\n.mce-container.mce-menu .mce-menu-item:focus .mce-menu-shortcut,\n.mce-container.mce-menu .mce-menu-item.mce-selected .mce-menu-shortcut {\n  color: #ffffff;\n}\n.mce-container.mce-menu .mce-menu-item.mce-disabled .mce-ico,\n.mce-container.mce-menu .mce-menu-item.mce-disabled .mce-text,\n.mce-container.mce-menu .mce-menu-item.mce-disabled .mce-menu-shortcut {\n  color: #aaaaaa;\n}\n.mce-container.mce-menu .mce-menu-item.mce-disabled:hover,\n.mce-container.mce-menu .mce-menu-item.mce-disabled:focus,\n.mce-container.mce-menu .mce-menu-item.mce-disabled.mce-selected {\n  background-color: #d7dce5;\n}\n.mce-container.mce-menu .mce-menu-item.mce-disabled:hover .mce-ico,\n.mce-container.mce-menu .mce-menu-item.mce-disabled:focus .mce-ico,\n.mce-container.mce-menu .mce-menu-item.mce-disabled.mce-selected .mce-ico,\n.mce-container.mce-menu .mce-menu-item.mce-disabled:hover .mce-text,\n.mce-container.mce-menu .mce-menu-item.mce-disabled:focus .mce-text,\n.mce-container.mce-menu .mce-menu-item.mce-disabled.mce-selected .mce-text,\n.mce-container.mce-menu .mce-menu-item.mce-disabled:hover .mce-menu-shortcut,\n.mce-container.mce-menu .mce-menu-item.mce-disabled:focus .mce-menu-shortcut,\n.mce-container.mce-menu .mce-menu-item.mce-disabled.mce-selected .mce-menu-shortcut {\n  color: #ffffff;\n}\n.mce-container.mce-menu .mce-menu-item-sep {\n  background-color: #d7dce5;\n}\n.mce-container.mce-menu .mce-menu-item-sep:hover {\n  background-color: #d7dce5;\n}\n.mce-menubtn button {\n  color: #36404a !important;\n}\n.mce-menu-item-normal.mce-active {\n  background-color: #5fbeaa !important;\n}\n.mce-menu-item-normal.mce-active .mce-text {\n  color: #ffffff !important;\n}\n/* =============\n   Notification\n============= */\n.notifyjs-metro-base {\n  position: relative;\n  min-height: 52px;\n  min-width: 250px;\n  color: #444;\n  border-radius: 3px;\n  -webkit-border-radius: 3px;\n  box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.2);\n  -webkit-animation: dropdownOpen 0.3s ease-out;\n  -o-animation: dropdownOpen 0.3s ease-out;\n  animation: dropdownOpen 0.3s ease-out;\n}\n.notifyjs-metro-base .image {\n  display: table;\n  position: absolute;\n  height: auto;\n  width: auto;\n  left: 25px;\n  top: 50%;\n  font-size: 24px;\n  -moz-transform: translate(-50%, -50%);\n  -ms-transform: translate(-50%, -50%);\n  -o-transform: translate(-50%, -50%);\n  -webkit-transform: translate(-50%, -50%);\n  transform: translate(-50%, -50%);\n}\n.notifyjs-metro-base .text-wrapper {\n  display: inline-block;\n  vertical-align: top;\n  text-align: left;\n  margin: 10px 10px 10px 52px;\n  clear: both;\n}\n.notifyjs-metro-base .title {\n  font-size: 15px;\n  line-height: 20px;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\n.notifyjs-metro-base .text {\n  font-size: 12px;\n  font-weight: normal;\n  max-width: 360px;\n  vertical-align: middle;\n}\n.notifyjs-metro-cool {\n  color: #fafafa !important;\n  background-color: #4A525F;\n  border: 1px solid #4A525F;\n}\n/* =============\n   Bootstrap Range slider\n============= */\n.slider .slider-horizontal {\n  margin: 10px 0;\n}\n.slider .slider-vertical {\n  margin: 0 10px;\n}\n.slider-handle.round {\n  position: absolute;\n  width: 20px;\n  height: 20px;\n  border: 1px solid #EFF2F7;\n  background: #fff;\n  cursor: pointer;\n}\n.slider-default .slider-selection {\n  background-image: none;\n  background-color: #909aa0;\n}\n.slider-primary .slider-selection {\n  background-image: none;\n  background-color: #5d9cec;\n}\n.slider-success .slider-selection {\n  background-image: none;\n  background-color: #81c868;\n}\n.slider-info .slider-selection {\n  background-image: none;\n  background-color: #34d3eb;\n}\n.slider-warning .slider-selection {\n  background-image: none;\n  background-color: #ffbd4a;\n}\n.slider-danger .slider-selection {\n  background-image: none;\n  background-color: #f05050;\n}\n.slider-custom .slider-selection {\n  background-image: none;\n  background-color: #5fbeaa;\n}\n.slider-pink .slider-selection {\n  background-image: none;\n  background-color: #fb6d9d;\n}\n.slider-purple .slider-selection {\n  background-image: none;\n  background-color: #7266ba;\n}\n.slider-inverse .slider-selection {\n  background-image: none;\n  background-color: #4c5667;\n}\n/* =============\n   Charts\n============= */\n.morris-hover.morris-default-style {\n  border-radius: 5px;\n  padding: 10px 12px;\n  color: #666;\n  background: #36404a;\n  border: none;\n  color: #ffffff !important;\n}\n.morris-hover.morris-default-style .morris-hover-point {\n  color: #f4f8fb !important;\n}\n.chart-detail-list li {\n  margin: 0px 10px;\n}\n.chart-detail-list li h5 {\n  font-size: 15px;\n}\n.pieLabel div {\n  font-size: 14px !important;\n}\n.jqstooltip {\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n}\n.chart {\n  position: relative;\n  display: inline-block;\n  width: 110px;\n  height: 110px;\n  margin-top: 20px;\n  margin-bottom: 20px;\n  text-align: center;\n}\n.chart canvas {\n  position: absolute;\n  top: 0;\n  left: 0;\n}\n.chart.chart-widget-pie {\n  margin-top: 5px;\n  margin-bottom: 5px;\n}\n.percent {\n  display: inline-block;\n  line-height: 110px;\n  z-index: 2;\n  font-weight: 600;\n  font-size: 18px;\n  color: #36404a;\n}\n.percent:after {\n  content: '%';\n  margin-left: 0.1em;\n  font-size: .8em;\n}\n#flotTip {\n  padding: 8px 12px;\n  background-color: #36404a;\n  z-index: 100;\n  color: #ffffff;\n  opacity: 0.9;\n  font-size: 13px;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n.legend tr {\n  height: 20px;\n}\n.legendLabel {\n  padding-left: 5px !important;\n  line-height: 10px;\n  padding-right: 10px;\n}\n/* C3 chart */\n.c3-tooltip td > span {\n  background: #36404a;\n}\n.c3-tooltip td {\n  border-left: none;\n}\n.c3-tooltip {\n  -webkit-box-shadow: 0px 0px 8px 0px #777777;\n  box-shadow: 0px 0px 8px 0px #777777;\n  -moz-box-shadow: 0px 0px 8px 0px #777777;\n  opacity: 1;\n}\n.c3-chart-arcs-title {\n  font-size: 18px;\n  font-weight: 600;\n}\n.c3-tooltip tr {\n  border: none !important;\n}\n.c3-tooltip th {\n  background-color: #36404a;\n}\n/* Chartist chart */\n.ct-golden-section:before {\n  float: none;\n}\n.ct-chart {\n  height: 300px;\n}\n.ct-chart .ct-label {\n  fill: #a3afb7;\n  color: #a3afb7;\n  font-size: 12px;\n  line-height: 1;\n}\n.ct-chart.simple-pie-chart-chartist .ct-label {\n  color: #ffffff;\n  fill: #ffffff;\n  font-size: 16px;\n}\n.ct-chart .ct-series.ct-series-a .ct-bar,\n.ct-chart .ct-series.ct-series-a .ct-line,\n.ct-chart .ct-series.ct-series-a .ct-point,\n.ct-chart .ct-series.ct-series-a .ct-slice-donut {\n  stroke: #5d9cec;\n}\n.ct-chart .ct-series.ct-series-b .ct-bar,\n.ct-chart .ct-series.ct-series-b .ct-line,\n.ct-chart .ct-series.ct-series-b .ct-point,\n.ct-chart .ct-series.ct-series-b .ct-slice-donut {\n  stroke: #fb6d9d;\n}\n.ct-chart .ct-series.ct-series-c .ct-bar,\n.ct-chart .ct-series.ct-series-c .ct-line,\n.ct-chart .ct-series.ct-series-c .ct-point,\n.ct-chart .ct-series.ct-series-c .ct-slice-donut {\n  stroke: #34d3eb;\n}\n.ct-chart .ct-series.ct-series-d .ct-bar,\n.ct-chart .ct-series.ct-series-d .ct-line,\n.ct-chart .ct-series.ct-series-d .ct-point,\n.ct-chart .ct-series.ct-series-d .ct-slice-donut {\n  stroke: #5fbeaa;\n}\n.ct-chart .ct-series.ct-series-e .ct-bar,\n.ct-chart .ct-series.ct-series-e .ct-line,\n.ct-chart .ct-series.ct-series-e .ct-point,\n.ct-chart .ct-series.ct-series-e .ct-slice-donut {\n  stroke: #36404a;\n}\n.ct-chart .ct-series.ct-series-f .ct-bar,\n.ct-chart .ct-series.ct-series-f .ct-line,\n.ct-chart .ct-series.ct-series-f .ct-point,\n.ct-chart .ct-series.ct-series-f .ct-slice-donut {\n  stroke: #7266ba;\n}\n.ct-chart .ct-series.ct-series-g .ct-bar,\n.ct-chart .ct-series.ct-series-g .ct-line,\n.ct-chart .ct-series.ct-series-g .ct-point,\n.ct-chart .ct-series.ct-series-g .ct-slice-donut {\n  stroke: #81c868;\n}\n.ct-series-a .ct-area,\n.ct-series-a .ct-slice-pie {\n  fill: #5d9cec;\n}\n.ct-series-b .ct-area,\n.ct-series-b .ct-slice-pie {\n  fill: #fb6d9d;\n}\n.ct-series-c .ct-area,\n.ct-series-c .ct-slice-pie {\n  fill: #34d3eb;\n}\n.ct-series-d .ct-area,\n.ct-series-d .ct-slice-pie {\n  fill: #5fbeaa;\n}\n/* Circliful charts */\n.circliful-chart {\n  margin: 0px auto;\n}\n.circle-text,\n.circle-info,\n.circle-text-half,\n.circle-info-half {\n  font-size: 12px;\n  font-weight: 600;\n}\n/* =============\n   Count Down\n============= */\n.home-wrapper {\n  margin: 10% 0px;\n}\n.home-text {\n  font-weight: 600;\n}\n.u-countdown {\n  margin-top: 40px;\n  text-align: center;\n}\n.u-countdown div {\n  display: inline-block;\n}\n.u-countdown div span {\n  display: block;\n  width: 150px;\n}\n.u-countdown div span:first-child {\n  font-size: 3em;\n  font-weight: 700;\n  height: 48px;\n  line-height: 48px;\n}\n.u-countdown div span:last-child {\n  color: #333333;\n  font-size: 0.9em;\n  height: 25px;\n  line-height: 25px;\n}\n.u-countdown > * {\n  text-align: center;\n}\n.cd-text {\n  font-size: 15px;\n  line-height: 24px;\n  font-style: italic;\n}\n/* =============\n   Timeline\n============= */\n.cd-container {\n  width: 90%;\n  max-width: 1170px;\n  margin: 0 auto;\n}\n.cd-container::after {\n  content: '';\n  display: table;\n  clear: both;\n}\n#cd-timeline {\n  margin-bottom: 2em;\n  margin-top: 2em;\n  padding: 2em 0;\n  position: relative;\n}\n#cd-timeline::before {\n  background: #ffffff;\n  content: '';\n  height: 100%;\n  left: 18px;\n  position: absolute;\n  top: 0;\n  width: 4px;\n}\n@media only screen and (min-width: 1170px) {\n  #cd-timeline {\n    margin-bottom: 3em;\n    margin-top: 3em;\n  }\n  #cd-timeline::before {\n    left: 50%;\n    margin-left: -2px;\n  }\n}\n.cd-timeline-block {\n  margin: 2em 0;\n  position: relative;\n}\n.cd-timeline-block:after {\n  clear: both;\n  content: \"\";\n  display: table;\n}\n.cd-timeline-block:first-child {\n  margin-top: 0;\n}\n.cd-timeline-block:last-child {\n  margin-bottom: 0;\n}\n@media only screen and (min-width: 1170px) {\n  .cd-timeline-block {\n    margin: 4em 0;\n  }\n  .cd-timeline-block:first-child {\n    margin-top: 0;\n  }\n  .cd-timeline-block:last-child {\n    margin-bottom: 0;\n  }\n}\n.cd-timeline-img {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 40px;\n  height: 40px;\n  border-radius: 50%;\n  box-shadow: 0 0 0 4px white, inset 0 2px 0 rgba(0, 0, 0, 0.08), 0 3px 0 4px rgba(0, 0, 0, 0.05);\n  text-align: center;\n  line-height: 40px;\n  font-size: 20px;\n  color: #fff;\n}\n.cd-timeline-img.cd-success {\n  background: #81c868;\n}\n.cd-timeline-img.cd-info {\n  background: #34d3eb;\n}\n.cd-timeline-img.cd-pink {\n  background: #fb6d9d;\n}\n.cd-timeline-img.cd-danger {\n  background: #f05050;\n}\n.cd-timeline-img.cd-primary {\n  background: #5d9cec;\n}\n.cd-timeline-img.cd-warning {\n  background: #ffbd4a;\n}\n@media only screen and (min-width: 1170px) {\n  .cd-timeline-img {\n    width: 60px;\n    height: 60px;\n    line-height: 60px;\n    left: 50%;\n    margin-left: -30px;\n    -webkit-transform: translateZ(0);\n    -webkit-backface-visibility: hidden;\n  }\n  .cssanimations .cd-timeline-img.is-hidden {\n    visibility: hidden;\n  }\n  .cssanimations .cd-timeline-img.bounce-in {\n    visibility: visible;\n    -webkit-animation: cd-bounce-1 0.6s;\n    -moz-animation: cd-bounce-1 0.6s;\n    animation: cd-bounce-1 0.6s;\n  }\n}\n.cd-timeline-content {\n  -moz-box-shadow: 0 5px 5px -5px rgba(0, 0, 0, 0.1);\n  -webkit-box-shadow: 0 5px 5px -5px rgba(0, 0, 0, 0.1);\n  background: white;\n  border-radius: 0;\n  box-shadow: 0 5px 5px -5px rgba(0, 0, 0, 0.1);\n  margin-left: 60px;\n  padding: 1em;\n  position: relative;\n}\n.cd-timeline-content img {\n  display: block;\n  width: 100%;\n}\n.cd-timeline-content:after {\n  clear: both;\n  content: \"\";\n  display: table;\n}\n.cd-timeline-content h2 {\n  margin-top: 0;\n}\n.cd-timeline-content p {\n  color: #666666;\n  font-size: 14px;\n  margin: 10px 0px 10px 0px;\n}\n.cd-timeline-content .cd-read-more {\n  background: #acb7c0;\n  border-radius: 0.25em;\n  color: white;\n  display: inline-block;\n  float: right;\n  font-size: 14px;\n  padding: .8em 1em;\n}\n.cd-timeline-content .cd-date {\n  display: inline-block;\n  font-size: 14px;\n}\n.cd-timeline-content h3 {\n  font-size: 21px;\n  margin: 0px;\n}\n.no-touch .cd-timeline-content .cd-read-more:hover {\n  background-color: #bac4cb;\n}\n.cd-timeline-content .cd-date {\n  float: left;\n  padding: .8em 0;\n  opacity: .7;\n}\n.cd-timeline-content::before {\n  content: '';\n  position: absolute;\n  top: 16px;\n  right: 100%;\n  height: 0;\n  width: 0;\n  border: 7px solid transparent;\n  border-right: 7px solid white;\n}\n@media only screen and (min-width: 1170px) {\n  .cd-timeline-content {\n    margin-left: 0;\n    padding: 1.6em;\n    width: 45%;\n  }\n  .cd-timeline-content::before {\n    top: 24px;\n    left: 100%;\n    border-color: transparent;\n    border-left-color: white;\n  }\n  .cd-timeline-content .cd-read-more {\n    float: left;\n  }\n  .cd-timeline-content .cd-date {\n    position: absolute;\n    width: 100%;\n    left: 122%;\n    top: 6px;\n  }\n  .cd-timeline-block:nth-child(even) .cd-timeline-content {\n    float: right;\n  }\n  .cd-timeline-block:nth-child(even) .cd-timeline-content::before {\n    top: 24px;\n    left: auto;\n    right: 100%;\n    border-color: transparent;\n    border-right-color: white;\n  }\n  .cd-timeline-block:nth-child(even) .cd-timeline-content .cd-read-more {\n    float: right;\n  }\n  .cd-timeline-block:nth-child(even) .cd-timeline-content .cd-date {\n    left: auto;\n    right: 122%;\n    text-align: right;\n  }\n  .cssanimations .cd-timeline-content.is-hidden {\n    visibility: hidden;\n  }\n  .cssanimations .cd-timeline-content.bounce-in {\n    visibility: visible;\n    -webkit-animation: cd-bounce-2 0.6s;\n    -moz-animation: cd-bounce-2 0.6s;\n    animation: cd-bounce-2 0.6s;\n  }\n}\n@media only screen and (min-width: 1170px) {\n  .cssanimations .cd-timeline-block:nth-child(even) .cd-timeline-content.bounce-in {\n    -webkit-animation: cd-bounce-2-inverse 0.6s;\n    -moz-animation: cd-bounce-2-inverse 0.6s;\n    animation: cd-bounce-2-inverse 0.6s;\n  }\n}\n/* Time line 2 */\n.timeline-2 {\n  border-left: 2px solid #98a6ad;\n  position: relative;\n}\n.timeline-2 .time-item:after {\n  background-color: #ffffff;\n  border-color: #98a6ad;\n  border-radius: 10px;\n  border-style: solid;\n  border-width: 2px;\n  bottom: 0;\n  content: '';\n  height: 14px;\n  left: 0;\n  margin-left: -8px;\n  position: absolute;\n  top: 5px;\n  width: 14px;\n}\n.time-item {\n  border-color: #dee5e7;\n  padding-bottom: 1px;\n  position: relative;\n}\n.time-item:before {\n  content: \" \";\n  display: table;\n}\n.time-item:after {\n  background-color: #ffffff;\n  border-color: #98a6ad;\n  border-radius: 10px;\n  border-style: solid;\n  border-width: 2px;\n  bottom: 0;\n  content: '';\n  height: 14px;\n  left: 0;\n  margin-left: -8px;\n  position: absolute;\n  top: 5px;\n  width: 14px;\n}\n.time-item-item:after {\n  content: \" \";\n  display: table;\n}\n.item-info {\n  margin-bottom: 15px;\n  margin-left: 15px;\n}\n.item-info p {\n  margin-bottom: 10px !important;\n}\n/* =============\n   Email\n============= */\n.mails a {\n  color: #797979;\n}\n.mails td {\n  vertical-align: middle !important;\n  position: relative;\n}\n.mails td:last-of-type {\n  width: 100px;\n  padding-right: 20px;\n}\n.mails tr:hover .text-white {\n  display: none;\n}\n.mails .mail-select {\n  padding: 12px 20px;\n  min-width: 134px;\n}\n.mails .checkbox {\n  margin-bottom: 0px;\n  margin-top: 0px;\n  vertical-align: middle;\n  display: inline-block;\n  height: 17px;\n}\n.mails .checkbox label {\n  min-height: 16px;\n}\n.mail-list .list-group-item {\n  background-color: transparent;\n}\n.mail-list .list-group-item:hover {\n  background-color: #f4f8fb;\n}\n.mail-list .list-group-item:focus {\n  background-color: #f4f8fb;\n}\n.mail-list .list-group-item.active {\n  background-color: #5fbeaa;\n  -webkit-border-radius: 3px;\n  border-radius: 3px;\n  -moz-border-radius: 3px;\n  background-clip: padding-box;\n}\n.unread a {\n  font-weight: 600;\n  color: #444444;\n}\n/* =============\n   Gallery\n============= */\n.portfolioFilter a {\n  -moz-box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);\n  -moz-transition: all 0.3s ease-out;\n  -ms-transition: all 0.3s ease-out;\n  -o-transition: all 0.3s ease-out;\n  transition: all 0.3s ease-out;\n  -webkit-box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);\n  -webkit-transition: all 0.3s ease-out;\n  box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);\n  color: #333333;\n  padding: 5px 10px;\n  display: inline-block;\n  margin-bottom: 5px;\n}\n.portfolioFilter a:hover {\n  background-color: #5d9cec;\n  color: #ffffff;\n}\n.portfolioFilter a.current {\n  background-color: #5d9cec;\n  color: #ffffff;\n}\n.thumb {\n  background-color: #ffffff;\n  border-radius: 3px;\n  box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);\n  margin-top: 30px;\n  padding-bottom: 10px;\n  padding-left: 10px;\n  padding-right: 10px;\n  padding-top: 10px;\n  width: 100%;\n}\n.thumb-img {\n  border-radius: 2px;\n  overflow: hidden;\n  width: 100%;\n}\n.gal-detail h4 {\n  margin-top: 16px;\n}\n/* =============\n   Maintenance\n============= */\n.icon-main {\n  font-size: 88px;\n  margin-bottom: 50px;\n}\n.maintenance-page {\n  margin: 10% 0%;\n}\n/* =============\n   Maps\n============= */\n.gmaps,\n.gmaps-panaroma {\n  height: 300px;\n  background: #eeeeee;\n  border-radius: 3px;\n}\n.gmaps-overlay {\n  display: block;\n  text-align: center;\n  color: #ffffff;\n  font-size: 16px;\n  line-height: 40px;\n  background: #5d9cec;\n  border-radius: 4px;\n  padding: 10px 20px;\n}\n.gmaps-overlay_arrow {\n  left: 50%;\n  margin-left: -16px;\n  width: 0;\n  height: 0;\n  position: absolute;\n}\n.gmaps-overlay_arrow.above {\n  bottom: -15px;\n  border-left: 16px solid transparent;\n  border-right: 16px solid transparent;\n  border-top: 16px solid #5d9cec;\n}\n.gmaps-overlay_arrow.below {\n  top: -15px;\n  border-left: 16px solid transparent;\n  border-right: 16px solid transparent;\n  border-bottom: 16px solid #5d9cec;\n}\n.jvectormap-zoomin,\n.jvectormap-zoomout {\n  width: 10px;\n  height: 10px;\n  line-height: 10px;\n}\n.jvectormap-zoomout {\n  top: 40px;\n}\n/* =============\n   Nestable\n============= */\n.custom-dd .dd-list .dd-item .dd-handle {\n  background: #f4f8fb;\n  border: none;\n  padding: 8px 16px;\n  height: auto;\n  font-weight: 600;\n  -webkit-border-radius: 3px;\n  border-radius: 3px;\n  -moz-border-radius: 3px;\n  background-clip: padding-box;\n}\n.custom-dd .dd-list .dd-item .dd-handle:hover {\n  color: #5fbeaa;\n}\n.custom-dd .dd-list .dd-item button {\n  height: auto;\n  font-size: 17px;\n  margin: 8px auto;\n  color: #555555;\n  width: 30px;\n}\n.custom-dd-empty .dd-list .dd3-handle {\n  border: none;\n  background: #f4f8fb;\n  height: 36px;\n  width: 36px;\n}\n.custom-dd-empty .dd-list .dd3-handle:before {\n  color: inherit;\n  top: 7px;\n}\n.custom-dd-empty .dd-list .dd3-handle:hover {\n  color: #5fbeaa;\n}\n.custom-dd-empty .dd-list .dd3-content {\n  height: auto;\n  border: none;\n  padding: 8px 16px 8px 46px;\n  background: #f4f8fb;\n  font-weight: 600;\n}\n.custom-dd-empty .dd-list .dd3-content:hover {\n  color: #5fbeaa;\n}\n.custom-dd-empty .dd-list button {\n  width: 26px;\n  height: 26px;\n  font-size: 16px;\n  font-weight: 600;\n}\n/* =============\n   Pricing\n============= */\n.pricing-plan {\n  padding-bottom: 50px;\n}\n.price_card {\n  -moz-border-radius: 5px;\n  -moz-box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);\n  -webkit-border-radius: 5px;\n  background: #fafafa;\n  border-radius: 5px;\n  box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);\n  margin-bottom: 30px;\n  padding-bottom: 20px;\n  position: relative;\n  webkit-box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);\n}\n.price_card .name {\n  display: block;\n  font-size: 16px;\n  font-weight: 700;\n  padding: 0 0 30px;\n  text-align: center;\n  width: 100%;\n}\n.price_card button {\n  margin-top: 20px;\n}\n.pricing-header {\n  -moz-border-radius-topleft: 5px;\n  -moz-border-radius-topright: 5px;\n  -webkit-border-top-left-radius: 5px;\n  -webkit-border-top-right-radius: 5px;\n  border-top-left-radius: 5px;\n  border-top-right-radius: 5px;\n  color: #ffffff;\n}\n.price {\n  display: block;\n  font-size: 48px;\n  font-weight: 300;\n  padding: 30px 0 10px;\n  text-align: center;\n  width: 100%;\n}\n.price-features {\n  color: #8a8a8a;\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  text-align: center;\n}\n.price-features li {\n  margin: 0 35px;\n  padding: 20px 15px;\n}\n.pricing-item {\n  margin: 0 0 30px;\n  position: relative;\n  text-align: center;\n}\n.pricing-item-inner {\n  -moz-transition: all 0.27s cubic-bezier(0, 0, 0.58, 1);\n  -ms-transition: all 0.27s cubic-bezier(0, 0, 0.58, 1);\n  -o-transition: all 0.27s cubic-bezier(0, 0, 0.58, 1);\n  -webkit-transition: all 0.27s cubic-bezier(0, 0, 0.58, 1);\n  border-radius: 7px;\n  border: 2px solid rgba(151, 160, 175, 0.2);\n  transition: all 0.27s cubic-bezier(0, 0, 0.58, 1);\n  vertical-align: middle;\n}\n.pricing-wrap {\n  -moz-box-sizing: border-box;\n  -webkit-box-sizing: border-box;\n  box-sizing: border-box;\n  overflow: hidden;\n  padding: 30px 20px;\n  position: relative;\n  text-align: center;\n}\n.pricing-icon {\n  font-size: 32px;\n  padding-bottom: 5px;\n  padding-top: 10px;\n  position: relative;\n  z-index: 1;\n}\n.pricing-title {\n  font-size: 16px;\n  font-weight: 700;\n  margin-bottom: 40px;\n  position: relative;\n  text-transform: uppercase;\n  z-index: 1;\n}\n.pr-list {\n  color: #97a0af;\n  font-size: 12px;\n  font-weight: 400;\n  margin: 0 -20px 30px;\n  padding: 0;\n  text-transform: uppercase;\n}\n.pr-list li {\n  list-style: none;\n  padding: 12px 20px;\n}\n.pricing-num {\n  font-size: 40px;\n  font-weight: 700;\n  line-height: 1;\n}\n.pricing-num sup {\n  font-size: 18px;\n  font-weight: 400;\n  left: -3px;\n  margin-left: -7px;\n  position: relative;\n  top: -20px;\n}\n.pr-per {\n  color: #97a0af;\n  font-size: 12px;\n}\n.pr-button {\n  margin-top: 30px;\n}\n/* =============\n   Profile\n============= */\n.bg-picture {\n  margin: -20px -25px 0px -25px;\n  padding: 100px 0px;\n  position: relative;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.profile-info-name {\n  position: relative;\n}\n.profile-tablist li a {\n  display: block;\n  color: #36404a;\n  padding: 10px 20px;\n  font-weight: 600;\n  text-transform: uppercase;\n}\n.profile-tablist li.active {\n  background-color: #5fbeaa;\n}\n.profile-tablist li.active a {\n  color: #ffffff;\n}\n.profile-tab-content {\n  background-color: transparent !important;\n  box-shadow: none !important;\n  margin-top: 40px;\n}\n.user-tabs {\n  background-color: #ffffff;\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  margin-left: -35px;\n  padding-left: 25px;\n}\n.user-tabs .nav.nav-tabs {\n  box-shadow: none !important;\n}\n.user-tabs .nav.nav-tabs a {\n  text-transform: uppercase;\n}\n.user-tabs .pull-right .btn {\n  margin-top: 8px;\n}\n.about-info-p {\n  margin-bottom: 20px;\n}\n.about-info-p p {\n  font-size: 16px;\n}\n/* =============\n   Extra pages\n============= */\n/*  sitemap-wrapper */\n.sitemap-wrapper a {\n  color: #555555;\n}\n.sitemap-wrapper a:hover {\n  color: #5fbeaa;\n}\n.sitemap-wrapper h5 {\n  font-weight: 600;\n  font-size: 16px;\n  line-height: 32px;\n}\n.sitemap-wrapper h5 i {\n  padding-right: 10px;\n}\n.sitemap-wrapper ul {\n  padding-left: 30px;\n}\n.sitemap-wrapper ul li a {\n  font-size: 15px;\n  line-height: 30px;\n}\n/*======= FAQ ======*/\n.faq-box {\n  padding: 24px 0px;\n  border-bottom: 1px solid #ebeff2;\n}\n.faq-box .question {\n  font-weight: 600;\n  font-size: 16px;\n  margin-top: 0px;\n}\n.faq-box .answer {\n  color: #98a6ad;\n  margin-bottom: 0px;\n}\n/* Search result */\n.search-result-box .tab-content {\n  padding: 30px 30px 10px 30px;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n  -moz-box-shadow: none;\n}\n.search-result-box .search-item {\n  padding-bottom: 20px;\n  border-bottom: 1px solid #ebeff2;\n  margin-bottom: 30px;\n}\n/*  Contact */\n.contact-search .btn-white {\n  position: absolute;\n  top: 1px;\n  right: 16px;\n  background-color: transparent !important;\n  border: none !important;\n  font-size: 16px;\n  box-shadow: none !important;\n  outline: none !important;\n  color: #98a6ad;\n}\n.contact-card {\n  position: relative;\n}\n.contact-card:hover .contact-action {\n  display: block;\n}\n.contact-card img {\n  width: 80px;\n  height: 80px;\n}\n.contact-card .member-info {\n  padding-left: 100px;\n  padding-bottom: 20px;\n}\n.contact-card .member-info h4,\n.contact-card .member-info p {\n  display: block;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  width: 100%;\n  white-space: nowrap;\n}\n.contact-card .contact-action {\n  position: absolute;\n  right: 0px;\n  top: 0px;\n  display: none;\n}\n/*  Image crop */\n#showDataURL img {\n  width: 100%;\n}\n/* Switchery demo */\n.switchery-demo .switchery {\n  margin-bottom: 10px;\n}\n/* Chat app */\n.chat-app-list {\n  padding: 0px 20px;\n}\n.chat-app-list .list-group-item {\n  background: transparent;\n}\n.chat-ready .conversation-list {\n  max-height: 800px;\n}\n.chat-ready .spinner {\n  width: 70px;\n  text-align: center;\n}\n.chat-ready .spinner > div {\n  width: 10px;\n  height: 10px;\n  background-color: #E3E3E3;\n  border-radius: 100%;\n  display: inline-block;\n  -webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both;\n  animation: sk-bouncedelay 1.4s infinite ease-in-out both;\n}\n.chat-ready .spinner .bounce1 {\n  -webkit-animation-delay: -0.32s;\n  animation-delay: -0.32s;\n}\n.chat-ready .spinner .bounce2 {\n  -webkit-animation-delay: -0.16s;\n  animation-delay: -0.16s;\n}\n@-webkit-keyframes sk-bouncedelay {\n  0%,\n  80%,\n  100% {\n    -webkit-transform: scale(0);\n  }\n  40% {\n    -webkit-transform: scale(1);\n  }\n}\n@keyframes sk-bouncedelay {\n  0%,\n  80%,\n  100% {\n    -webkit-transform: scale(0);\n    transform: scale(0);\n  }\n  40% {\n    -webkit-transform: scale(1);\n    transform: scale(1);\n  }\n}\n/* Opportunities page */\n.opport-box .checkbx-detail {\n  width: 30px;\n}\n.opport-box .lable-detail {\n  text-align: center;\n  width: 20%;\n}\n.opport-box .member-info {\n  padding-right: 10px;\n}\n.opport-box .member-info h4 {\n  font-size: 16px;\n  display: block;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n.opport-box .member-info p {\n  font-size: 13px;\n  display: block;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n/* Product page */\n.product-list-box {\n  position: relative;\n}\n.product-list-box img {\n  max-width: 220px;\n  height: auto;\n  margin: 0 auto;\n  display: block;\n}\n.product-list-box .product-action {\n  position: absolute;\n  right: 10px;\n  top: 10px;\n  display: none;\n}\n.product-list-box .detail {\n  background: #f4f8fb;\n  padding: 20px;\n  margin: 0px -10px -10px;\n}\n.product-list-box .detail h4 a {\n  white-space: nowrap;\n  display: block;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  font-size: 16px;\n  font-weight: 600;\n}\n.product-list-box .detail .rating ul {\n  margin-left: 0px;\n}\n.product-list-box .detail .rating ul li {\n  padding: 0px;\n}\n.product-list-box .detail .rating ul li a {\n  color: #ffbd4a;\n  font-size: 15px;\n  margin-bottom: 0;\n  padding-right: 4px;\n}\n.product-list-box:hover .product-action {\n  display: block;\n}\n/* =============\n   Accounts pages\n============= */\n.account-pages {\n  background: url(\"../images/agsquare.png\");\n  position: absolute;\n  height: 100%;\n  width: 100%;\n}\n.wrapper-page {\n  margin: 5% auto;\n  position: relative;\n  width: 420px;\n}\n.wrapper-page .card-box {\n  border: 1px solid rgba(54, 64, 74, 0.1);\n}\n.panel-pages {\n  border-radius: 6px;\n}\n.panel-pages .panel-body {\n  padding: 30px;\n}\n.panel-pages .panel-heading {\n  -moz-border-radius: 6px 6px 0px 0px;\n  -webkit-border-radius: 6px 6px 0px 0px;\n  border-radius: 6px 6px 0px 0px;\n  padding: 40px 20px;\n  position: relative;\n}\n.panel-pages .panel-heading h3 {\n  position: relative;\n  z-index: 999;\n}\n.user-thumb {\n  position: relative;\n  z-index: 999;\n}\n.user-thumb img {\n  height: 88px;\n  margin: 0px auto;\n  width: 88px;\n}\n.ex-page-content .text-error {\n  color: #252932;\n  font-size: 98px;\n  font-weight: 700;\n  line-height: 150px;\n}\n.ex-page-content .text-error i {\n  font-size: 78px;\n  padding: 0px 10px;\n}\n/* signup-signin-page */\n.signup-signin-page {\n  width: auto;\n}\n"
  },
  {
    "path": "static/assets/css/responsive.css",
    "content": "/*\nTemplate Name: Ubold Dashboard\nAuthor: CoderThemes\nEmail: coderthemes@gmail.com\nFile: Responsive\n*/\n@media only screen and (max-width: 6000px) and (min-width: 700px) {\n  .wrapper.right-bar-enabled .right-bar {\n    right: 0;\n    z-index: 99;\n  }\n}\n@media (min-width: 768px) and (max-width: 1024px) {\n  .email-msg {\n    display: none;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  body {\n    overflow-x: hidden;\n  }\n}\n@media (max-width: 767px) {\n  body {\n    overflow-x: hidden;\n  }\n  .mobile-sidebar {\n    left: 0px;\n  }\n  .mobile-content {\n    left: 250px;\n    right: -250px;\n  }\n  .wrapper-page {\n    width: 90%;\n  }\n  .wizard > .steps > ul > li {\n    width: 100%;\n  }\n  .wizard > .content {\n    padding: 0px !important;\n  }\n  .wizard > .content > .body {\n    float: none;\n    position: relative;\n    width: 100%;\n    height: 100%;\n    padding: 0%;\n  }\n  .wizard.vertical > .steps {\n    display: inline;\n    float: none;\n    width: 100%;\n  }\n  .wizard.vertical > .content {\n    display: inline;\n    float: none;\n    margin: 0%;\n    width: 100%;\n  }\n  .navbar-nav .open .dropdown-menu {\n    background-color: #ffffff;\n    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);\n    left: auto;\n    position: absolute;\n    right: 0;\n  }\n  .todo-send {\n    margin-top: 10px;\n    padding-left: 15px;\n  }\n  .chat-inputbar {\n    padding-left: 15px;\n  }\n  .chat-send {\n    margin-top: 10px;\n    padding-left: 15px;\n    padding-right: 15px;\n  }\n  .dataTables_wrapper .col-xs-6 {\n    width: 100%;\n    text-align: left;\n  }\n}\n@media (max-width: 480px) {\n  .side-menu {\n    z-index: 10 !important;\n  }\n  .button-menu-mobile {\n    display: block;\n  }\n  .search-bar {\n    display: none !important;\n  }\n}\n@media (max-width: 420px) {\n  .hide-phone {\n    display: none !important;\n  }\n}\n/* Container-alt */\n@media (min-width: 768px) {\n  .container-alt {\n    width: 750px;\n  }\n}\n@media (min-width: 992px) {\n  .container-alt {\n    width: 970px;\n  }\n}\n@media (min-width: 1200px) {\n  .container-alt {\n    width: 1170px;\n  }\n}\n@media (max-width: 419px) {\n  .topbar-left {\n    width: 70px !important;\n  }\n  .logo .icon-c-logo {\n    display: inline-block !important;\n  }\n  .logo span {\n    display: none !important;\n  }\n}\n"
  },
  {
    "path": "static/assets/css/statusecho.css",
    "content": "\n.state_color_510 {\n    background-color: #90EE90;\n    border-radius: 4px;\n    color: #ffffff;\n    display: inline-block;\n    font-size: 12px;\n    font-weight: normal;\n    line-height: 18px;\n    text-align: center;\n    width: 50px;\n}\n.state_color_510:first-child {\n}\n.state_color_600 {\n    background-color: #f89406;\n    border-radius: 4px;\n    color: #ffffff;\n    display: inline-block;\n    font-size: 14px;\n    font-weight: normal;\n    line-height: 23px;\n    text-align: center;\n    width: 50px;\n}\n.state_color_600:first-child {\n}\n.state_color_610 {\n    background-color: #bd362f;\n    border-radius: 4px;\n    color: #ffffff;\n    display: inline-block;\n    font-size: 12px;\n    font-weight: normal;\n    line-height: 18px;\n    text-align: center;\n    width: 50px;\n}\n.state_color_710 {\n    color: #bd362f;\n    font-size: 15px;\n    font-weight: normal;\n    line-height: 11px;\n    text-align: center;\n}\n.state_710 {\n    text-align: center;\n}\n"
  },
  {
    "path": "static/assets/css/style.css",
    "content": "body {\n    font-family: helvetica, sans-serif, arial;\n    font-size: 1em;\n    color: #111;\n}\n\nh1 {\n    text-align: center;\n}\n\n#terminal-container {\n    width: 1024px;\n    height: 900px;\n    margin: 0 auto;\n    padding: 2px;\n}\n\n#terminal-container .terminal {\n    background-color: #111;\n    color: #fafafa;\n    padding: 2px;\n}\n\n#terminal-container .terminal:focus .terminal-cursor {\n    background-color: #fafafa;\n}\n"
  },
  {
    "path": "static/assets/css/variables.css",
    "content": ""
  },
  {
    "path": "static/assets/css/xterm.css",
    "content": "/**\n * xterm.js: xterm, in the browser\n * Copyright (c) 2014-2016, SourceLair Private Company (www.sourcelair.com (MIT License)\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * https://github.com/chjj/term.js\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n * Originally forked from (with the author's permission):\n *   Fabrice Bellard's javascript vt100 for jslinux:\n *   http://bellard.org/jslinux/\n *   Copyright (c) 2011 Fabrice Bellard\n *   The original design remains. The terminal itself\n *   has been extended to include xterm CSI codes, among\n *   other features.\n */\n\n/*\n *  Default style for xterm.js\n */\n\n.terminal {\n    background-color: #000;\n    color: #fff;\n    font-family: courier-new, courier, monospace;\n    font-feature-settings: \"liga\" 0;\n    position: relative;\n}\n\n.terminal.focus,\n.terminal:focus {\n    outline: none;\n}\n\n.terminal .xterm-helpers {\n    position: absolute;\n    top: 0;\n}\n\n.terminal .xterm-helper-textarea {\n    /*\n     * HACK: to fix IE's blinking cursor\n     * Move textarea out of the screen to the far left, so that the cursor is not visible.\n     */\n    position: absolute;\n    opacity: 0;\n    left: -9999em;\n    top: -9999em;\n    width: 0;\n    height: 0;\n    z-index: -10;\n    /** Prevent wrapping so the IME appears against the textarea at the correct position */\n    white-space: nowrap;\n    overflow: hidden;\n    resize: none;\n}\n\n.terminal .terminal-cursor {\n    background-color: #fff;\n    color: #000;\n}\n\n.terminal:not(.focus) .terminal-cursor {\n    outline: 1px solid #fff;\n    outline-offset: -1px;\n    background-color: transparent;\n}\n\n.terminal.focus .terminal-cursor.blinking {\n    animation: blink-cursor 1.2s infinite step-end;\n}\n\n@keyframes blink-cursor {\n    0% {\n        background-color: #fff;\n        color: #000;\n    }\n    50% {\n        background-color: transparent;\n        color: #FFF;\n    }\n}\n\n.terminal .composition-view {\n    background: #000;\n    color: #FFF;\n    display: none;\n    position: absolute;\n    white-space: nowrap;\n    z-index: 1;\n}\n\n.terminal .composition-view.active {\n    display: block;\n}\n\n.terminal .xterm-viewport {\n    /* On OS X this is required in order for the scroll bar to appear fully opaque */\n    background-color: #000;\n    overflow-y: scroll;\n}\n\n.terminal .xterm-rows {\n    position: absolute;\n    left: 0;\n    top: 0;\n}\n\n.terminal .xterm-rows > div {\n    /* Lines containing spans and text nodes ocassionally wrap despite being the same width (#327) */\n    white-space: nowrap;\n}\n\n.terminal .xterm-scroll-area {\n    visibility: hidden;\n}\n\n.terminal .xterm-char-measure-element {\n    display: inline-block;\n    visibility: hidden;\n    position: absolute;\n    left: -9999em;\n}\n\n/*\n *  Determine default colors for xterm.js\n */\n.terminal .xterm-bold {\n    font-weight: bold;\n}\n\n.terminal .xterm-underline {\n    text-decoration: underline;\n}\n\n.terminal .xterm-blink {\n    text-decoration: blink;\n}\n\n.terminal .xterm-hidden {\n    visibility: hidden;\n}\n\n.terminal .xterm-color-0 {\n    color: #2e3436;\n}\n\n.terminal .xterm-bg-color-0 {\n    background-color: #2e3436;\n}\n\n.terminal .xterm-color-1 {\n    color: #cc0000;\n}\n\n.terminal .xterm-bg-color-1 {\n    background-color: #cc0000;\n}\n\n.terminal .xterm-color-2 {\n    color: #4e9a06;\n}\n\n.terminal .xterm-bg-color-2 {\n    background-color: #4e9a06;\n}\n\n.terminal .xterm-color-3 {\n    color: #c4a000;\n}\n\n.terminal .xterm-bg-color-3 {\n    background-color: #c4a000;\n}\n\n.terminal .xterm-color-4 {\n    color: #3465a4;\n}\n\n.terminal .xterm-bg-color-4 {\n    background-color: #3465a4;\n}\n\n.terminal .xterm-color-5 {\n    color: #75507b;\n}\n\n.terminal .xterm-bg-color-5 {\n    background-color: #75507b;\n}\n\n.terminal .xterm-color-6 {\n    color: #06989a;\n}\n\n.terminal .xterm-bg-color-6 {\n    background-color: #06989a;\n}\n\n.terminal .xterm-color-7 {\n    color: #d3d7cf;\n}\n\n.terminal .xterm-bg-color-7 {\n    background-color: #d3d7cf;\n}\n\n.terminal .xterm-color-8 {\n    color: #555753;\n}\n\n.terminal .xterm-bg-color-8 {\n    background-color: #555753;\n}\n\n.terminal .xterm-color-9 {\n    color: #ef2929;\n}\n\n.terminal .xterm-bg-color-9 {\n    background-color: #ef2929;\n}\n\n.terminal .xterm-color-10 {\n    color: #8ae234;\n}\n\n.terminal .xterm-bg-color-10 {\n    background-color: #8ae234;\n}\n\n.terminal .xterm-color-11 {\n    color: #fce94f;\n}\n\n.terminal .xterm-bg-color-11 {\n    background-color: #fce94f;\n}\n\n.terminal .xterm-color-12 {\n    color: #729fcf;\n}\n\n.terminal .xterm-bg-color-12 {\n    background-color: #729fcf;\n}\n\n.terminal .xterm-color-13 {\n    color: #ad7fa8;\n}\n\n.terminal .xterm-bg-color-13 {\n    background-color: #ad7fa8;\n}\n\n.terminal .xterm-color-14 {\n    color: #34e2e2;\n}\n\n.terminal .xterm-bg-color-14 {\n    background-color: #34e2e2;\n}\n\n.terminal .xterm-color-15 {\n    color: #eeeeec;\n}\n\n.terminal .xterm-bg-color-15 {\n    background-color: #eeeeec;\n}\n\n.terminal .xterm-color-16 {\n    color: #000000;\n}\n\n.terminal .xterm-bg-color-16 {\n    background-color: #000000;\n}\n\n.terminal .xterm-color-17 {\n    color: #00005f;\n}\n\n.terminal .xterm-bg-color-17 {\n    background-color: #00005f;\n}\n\n.terminal .xterm-color-18 {\n    color: #000087;\n}\n\n.terminal .xterm-bg-color-18 {\n    background-color: #000087;\n}\n\n.terminal .xterm-color-19 {\n    color: #0000af;\n}\n\n.terminal .xterm-bg-color-19 {\n    background-color: #0000af;\n}\n\n.terminal .xterm-color-20 {\n    color: #0000d7;\n}\n\n.terminal .xterm-bg-color-20 {\n    background-color: #0000d7;\n}\n\n.terminal .xterm-color-21 {\n    color: #0000ff;\n}\n\n.terminal .xterm-bg-color-21 {\n    background-color: #0000ff;\n}\n\n.terminal .xterm-color-22 {\n    color: #005f00;\n}\n\n.terminal .xterm-bg-color-22 {\n    background-color: #005f00;\n}\n\n.terminal .xterm-color-23 {\n    color: #005f5f;\n}\n\n.terminal .xterm-bg-color-23 {\n    background-color: #005f5f;\n}\n\n.terminal .xterm-color-24 {\n    color: #005f87;\n}\n\n.terminal .xterm-bg-color-24 {\n    background-color: #005f87;\n}\n\n.terminal .xterm-color-25 {\n    color: #005faf;\n}\n\n.terminal .xterm-bg-color-25 {\n    background-color: #005faf;\n}\n\n.terminal .xterm-color-26 {\n    color: #005fd7;\n}\n\n.terminal .xterm-bg-color-26 {\n    background-color: #005fd7;\n}\n\n.terminal .xterm-color-27 {\n    color: #005fff;\n}\n\n.terminal .xterm-bg-color-27 {\n    background-color: #005fff;\n}\n\n.terminal .xterm-color-28 {\n    color: #008700;\n}\n\n.terminal .xterm-bg-color-28 {\n    background-color: #008700;\n}\n\n.terminal .xterm-color-29 {\n    color: #00875f;\n}\n\n.terminal .xterm-bg-color-29 {\n    background-color: #00875f;\n}\n\n.terminal .xterm-color-30 {\n    color: #008787;\n}\n\n.terminal .xterm-bg-color-30 {\n    background-color: #008787;\n}\n\n.terminal .xterm-color-31 {\n    color: #0087af;\n}\n\n.terminal .xterm-bg-color-31 {\n    background-color: #0087af;\n}\n\n.terminal .xterm-color-32 {\n    color: #0087d7;\n}\n\n.terminal .xterm-bg-color-32 {\n    background-color: #0087d7;\n}\n\n.terminal .xterm-color-33 {\n    color: #0087ff;\n}\n\n.terminal .xterm-bg-color-33 {\n    background-color: #0087ff;\n}\n\n.terminal .xterm-color-34 {\n    color: #00af00;\n}\n\n.terminal .xterm-bg-color-34 {\n    background-color: #00af00;\n}\n\n.terminal .xterm-color-35 {\n    color: #00af5f;\n}\n\n.terminal .xterm-bg-color-35 {\n    background-color: #00af5f;\n}\n\n.terminal .xterm-color-36 {\n    color: #00af87;\n}\n\n.terminal .xterm-bg-color-36 {\n    background-color: #00af87;\n}\n\n.terminal .xterm-color-37 {\n    color: #00afaf;\n}\n\n.terminal .xterm-bg-color-37 {\n    background-color: #00afaf;\n}\n\n.terminal .xterm-color-38 {\n    color: #00afd7;\n}\n\n.terminal .xterm-bg-color-38 {\n    background-color: #00afd7;\n}\n\n.terminal .xterm-color-39 {\n    color: #00afff;\n}\n\n.terminal .xterm-bg-color-39 {\n    background-color: #00afff;\n}\n\n.terminal .xterm-color-40 {\n    color: #00d700;\n}\n\n.terminal .xterm-bg-color-40 {\n    background-color: #00d700;\n}\n\n.terminal .xterm-color-41 {\n    color: #00d75f;\n}\n\n.terminal .xterm-bg-color-41 {\n    background-color: #00d75f;\n}\n\n.terminal .xterm-color-42 {\n    color: #00d787;\n}\n\n.terminal .xterm-bg-color-42 {\n    background-color: #00d787;\n}\n\n.terminal .xterm-color-43 {\n    color: #00d7af;\n}\n\n.terminal .xterm-bg-color-43 {\n    background-color: #00d7af;\n}\n\n.terminal .xterm-color-44 {\n    color: #00d7d7;\n}\n\n.terminal .xterm-bg-color-44 {\n    background-color: #00d7d7;\n}\n\n.terminal .xterm-color-45 {\n    color: #00d7ff;\n}\n\n.terminal .xterm-bg-color-45 {\n    background-color: #00d7ff;\n}\n\n.terminal .xterm-color-46 {\n    color: #00ff00;\n}\n\n.terminal .xterm-bg-color-46 {\n    background-color: #00ff00;\n}\n\n.terminal .xterm-color-47 {\n    color: #00ff5f;\n}\n\n.terminal .xterm-bg-color-47 {\n    background-color: #00ff5f;\n}\n\n.terminal .xterm-color-48 {\n    color: #00ff87;\n}\n\n.terminal .xterm-bg-color-48 {\n    background-color: #00ff87;\n}\n\n.terminal .xterm-color-49 {\n    color: #00ffaf;\n}\n\n.terminal .xterm-bg-color-49 {\n    background-color: #00ffaf;\n}\n\n.terminal .xterm-color-50 {\n    color: #00ffd7;\n}\n\n.terminal .xterm-bg-color-50 {\n    background-color: #00ffd7;\n}\n\n.terminal .xterm-color-51 {\n    color: #00ffff;\n}\n\n.terminal .xterm-bg-color-51 {\n    background-color: #00ffff;\n}\n\n.terminal .xterm-color-52 {\n    color: #5f0000;\n}\n\n.terminal .xterm-bg-color-52 {\n    background-color: #5f0000;\n}\n\n.terminal .xterm-color-53 {\n    color: #5f005f;\n}\n\n.terminal .xterm-bg-color-53 {\n    background-color: #5f005f;\n}\n\n.terminal .xterm-color-54 {\n    color: #5f0087;\n}\n\n.terminal .xterm-bg-color-54 {\n    background-color: #5f0087;\n}\n\n.terminal .xterm-color-55 {\n    color: #5f00af;\n}\n\n.terminal .xterm-bg-color-55 {\n    background-color: #5f00af;\n}\n\n.terminal .xterm-color-56 {\n    color: #5f00d7;\n}\n\n.terminal .xterm-bg-color-56 {\n    background-color: #5f00d7;\n}\n\n.terminal .xterm-color-57 {\n    color: #5f00ff;\n}\n\n.terminal .xterm-bg-color-57 {\n    background-color: #5f00ff;\n}\n\n.terminal .xterm-color-58 {\n    color: #5f5f00;\n}\n\n.terminal .xterm-bg-color-58 {\n    background-color: #5f5f00;\n}\n\n.terminal .xterm-color-59 {\n    color: #5f5f5f;\n}\n\n.terminal .xterm-bg-color-59 {\n    background-color: #5f5f5f;\n}\n\n.terminal .xterm-color-60 {\n    color: #5f5f87;\n}\n\n.terminal .xterm-bg-color-60 {\n    background-color: #5f5f87;\n}\n\n.terminal .xterm-color-61 {\n    color: #5f5faf;\n}\n\n.terminal .xterm-bg-color-61 {\n    background-color: #5f5faf;\n}\n\n.terminal .xterm-color-62 {\n    color: #5f5fd7;\n}\n\n.terminal .xterm-bg-color-62 {\n    background-color: #5f5fd7;\n}\n\n.terminal .xterm-color-63 {\n    color: #5f5fff;\n}\n\n.terminal .xterm-bg-color-63 {\n    background-color: #5f5fff;\n}\n\n.terminal .xterm-color-64 {\n    color: #5f8700;\n}\n\n.terminal .xterm-bg-color-64 {\n    background-color: #5f8700;\n}\n\n.terminal .xterm-color-65 {\n    color: #5f875f;\n}\n\n.terminal .xterm-bg-color-65 {\n    background-color: #5f875f;\n}\n\n.terminal .xterm-color-66 {\n    color: #5f8787;\n}\n\n.terminal .xterm-bg-color-66 {\n    background-color: #5f8787;\n}\n\n.terminal .xterm-color-67 {\n    color: #5f87af;\n}\n\n.terminal .xterm-bg-color-67 {\n    background-color: #5f87af;\n}\n\n.terminal .xterm-color-68 {\n    color: #5f87d7;\n}\n\n.terminal .xterm-bg-color-68 {\n    background-color: #5f87d7;\n}\n\n.terminal .xterm-color-69 {\n    color: #5f87ff;\n}\n\n.terminal .xterm-bg-color-69 {\n    background-color: #5f87ff;\n}\n\n.terminal .xterm-color-70 {\n    color: #5faf00;\n}\n\n.terminal .xterm-bg-color-70 {\n    background-color: #5faf00;\n}\n\n.terminal .xterm-color-71 {\n    color: #5faf5f;\n}\n\n.terminal .xterm-bg-color-71 {\n    background-color: #5faf5f;\n}\n\n.terminal .xterm-color-72 {\n    color: #5faf87;\n}\n\n.terminal .xterm-bg-color-72 {\n    background-color: #5faf87;\n}\n\n.terminal .xterm-color-73 {\n    color: #5fafaf;\n}\n\n.terminal .xterm-bg-color-73 {\n    background-color: #5fafaf;\n}\n\n.terminal .xterm-color-74 {\n    color: #5fafd7;\n}\n\n.terminal .xterm-bg-color-74 {\n    background-color: #5fafd7;\n}\n\n.terminal .xterm-color-75 {\n    color: #5fafff;\n}\n\n.terminal .xterm-bg-color-75 {\n    background-color: #5fafff;\n}\n\n.terminal .xterm-color-76 {\n    color: #5fd700;\n}\n\n.terminal .xterm-bg-color-76 {\n    background-color: #5fd700;\n}\n\n.terminal .xterm-color-77 {\n    color: #5fd75f;\n}\n\n.terminal .xterm-bg-color-77 {\n    background-color: #5fd75f;\n}\n\n.terminal .xterm-color-78 {\n    color: #5fd787;\n}\n\n.terminal .xterm-bg-color-78 {\n    background-color: #5fd787;\n}\n\n.terminal .xterm-color-79 {\n    color: #5fd7af;\n}\n\n.terminal .xterm-bg-color-79 {\n    background-color: #5fd7af;\n}\n\n.terminal .xterm-color-80 {\n    color: #5fd7d7;\n}\n\n.terminal .xterm-bg-color-80 {\n    background-color: #5fd7d7;\n}\n\n.terminal .xterm-color-81 {\n    color: #5fd7ff;\n}\n\n.terminal .xterm-bg-color-81 {\n    background-color: #5fd7ff;\n}\n\n.terminal .xterm-color-82 {\n    color: #5fff00;\n}\n\n.terminal .xterm-bg-color-82 {\n    background-color: #5fff00;\n}\n\n.terminal .xterm-color-83 {\n    color: #5fff5f;\n}\n\n.terminal .xterm-bg-color-83 {\n    background-color: #5fff5f;\n}\n\n.terminal .xterm-color-84 {\n    color: #5fff87;\n}\n\n.terminal .xterm-bg-color-84 {\n    background-color: #5fff87;\n}\n\n.terminal .xterm-color-85 {\n    color: #5fffaf;\n}\n\n.terminal .xterm-bg-color-85 {\n    background-color: #5fffaf;\n}\n\n.terminal .xterm-color-86 {\n    color: #5fffd7;\n}\n\n.terminal .xterm-bg-color-86 {\n    background-color: #5fffd7;\n}\n\n.terminal .xterm-color-87 {\n    color: #5fffff;\n}\n\n.terminal .xterm-bg-color-87 {\n    background-color: #5fffff;\n}\n\n.terminal .xterm-color-88 {\n    color: #870000;\n}\n\n.terminal .xterm-bg-color-88 {\n    background-color: #870000;\n}\n\n.terminal .xterm-color-89 {\n    color: #87005f;\n}\n\n.terminal .xterm-bg-color-89 {\n    background-color: #87005f;\n}\n\n.terminal .xterm-color-90 {\n    color: #870087;\n}\n\n.terminal .xterm-bg-color-90 {\n    background-color: #870087;\n}\n\n.terminal .xterm-color-91 {\n    color: #8700af;\n}\n\n.terminal .xterm-bg-color-91 {\n    background-color: #8700af;\n}\n\n.terminal .xterm-color-92 {\n    color: #8700d7;\n}\n\n.terminal .xterm-bg-color-92 {\n    background-color: #8700d7;\n}\n\n.terminal .xterm-color-93 {\n    color: #8700ff;\n}\n\n.terminal .xterm-bg-color-93 {\n    background-color: #8700ff;\n}\n\n.terminal .xterm-color-94 {\n    color: #875f00;\n}\n\n.terminal .xterm-bg-color-94 {\n    background-color: #875f00;\n}\n\n.terminal .xterm-color-95 {\n    color: #875f5f;\n}\n\n.terminal .xterm-bg-color-95 {\n    background-color: #875f5f;\n}\n\n.terminal .xterm-color-96 {\n    color: #875f87;\n}\n\n.terminal .xterm-bg-color-96 {\n    background-color: #875f87;\n}\n\n.terminal .xterm-color-97 {\n    color: #875faf;\n}\n\n.terminal .xterm-bg-color-97 {\n    background-color: #875faf;\n}\n\n.terminal .xterm-color-98 {\n    color: #875fd7;\n}\n\n.terminal .xterm-bg-color-98 {\n    background-color: #875fd7;\n}\n\n.terminal .xterm-color-99 {\n    color: #875fff;\n}\n\n.terminal .xterm-bg-color-99 {\n    background-color: #875fff;\n}\n\n.terminal .xterm-color-100 {\n    color: #878700;\n}\n\n.terminal .xterm-bg-color-100 {\n    background-color: #878700;\n}\n\n.terminal .xterm-color-101 {\n    color: #87875f;\n}\n\n.terminal .xterm-bg-color-101 {\n    background-color: #87875f;\n}\n\n.terminal .xterm-color-102 {\n    color: #878787;\n}\n\n.terminal .xterm-bg-color-102 {\n    background-color: #878787;\n}\n\n.terminal .xterm-color-103 {\n    color: #8787af;\n}\n\n.terminal .xterm-bg-color-103 {\n    background-color: #8787af;\n}\n\n.terminal .xterm-color-104 {\n    color: #8787d7;\n}\n\n.terminal .xterm-bg-color-104 {\n    background-color: #8787d7;\n}\n\n.terminal .xterm-color-105 {\n    color: #8787ff;\n}\n\n.terminal .xterm-bg-color-105 {\n    background-color: #8787ff;\n}\n\n.terminal .xterm-color-106 {\n    color: #87af00;\n}\n\n.terminal .xterm-bg-color-106 {\n    background-color: #87af00;\n}\n\n.terminal .xterm-color-107 {\n    color: #87af5f;\n}\n\n.terminal .xterm-bg-color-107 {\n    background-color: #87af5f;\n}\n\n.terminal .xterm-color-108 {\n    color: #87af87;\n}\n\n.terminal .xterm-bg-color-108 {\n    background-color: #87af87;\n}\n\n.terminal .xterm-color-109 {\n    color: #87afaf;\n}\n\n.terminal .xterm-bg-color-109 {\n    background-color: #87afaf;\n}\n\n.terminal .xterm-color-110 {\n    color: #87afd7;\n}\n\n.terminal .xterm-bg-color-110 {\n    background-color: #87afd7;\n}\n\n.terminal .xterm-color-111 {\n    color: #87afff;\n}\n\n.terminal .xterm-bg-color-111 {\n    background-color: #87afff;\n}\n\n.terminal .xterm-color-112 {\n    color: #87d700;\n}\n\n.terminal .xterm-bg-color-112 {\n    background-color: #87d700;\n}\n\n.terminal .xterm-color-113 {\n    color: #87d75f;\n}\n\n.terminal .xterm-bg-color-113 {\n    background-color: #87d75f;\n}\n\n.terminal .xterm-color-114 {\n    color: #87d787;\n}\n\n.terminal .xterm-bg-color-114 {\n    background-color: #87d787;\n}\n\n.terminal .xterm-color-115 {\n    color: #87d7af;\n}\n\n.terminal .xterm-bg-color-115 {\n    background-color: #87d7af;\n}\n\n.terminal .xterm-color-116 {\n    color: #87d7d7;\n}\n\n.terminal .xterm-bg-color-116 {\n    background-color: #87d7d7;\n}\n\n.terminal .xterm-color-117 {\n    color: #87d7ff;\n}\n\n.terminal .xterm-bg-color-117 {\n    background-color: #87d7ff;\n}\n\n.terminal .xterm-color-118 {\n    color: #87ff00;\n}\n\n.terminal .xterm-bg-color-118 {\n    background-color: #87ff00;\n}\n\n.terminal .xterm-color-119 {\n    color: #87ff5f;\n}\n\n.terminal .xterm-bg-color-119 {\n    background-color: #87ff5f;\n}\n\n.terminal .xterm-color-120 {\n    color: #87ff87;\n}\n\n.terminal .xterm-bg-color-120 {\n    background-color: #87ff87;\n}\n\n.terminal .xterm-color-121 {\n    color: #87ffaf;\n}\n\n.terminal .xterm-bg-color-121 {\n    background-color: #87ffaf;\n}\n\n.terminal .xterm-color-122 {\n    color: #87ffd7;\n}\n\n.terminal .xterm-bg-color-122 {\n    background-color: #87ffd7;\n}\n\n.terminal .xterm-color-123 {\n    color: #87ffff;\n}\n\n.terminal .xterm-bg-color-123 {\n    background-color: #87ffff;\n}\n\n.terminal .xterm-color-124 {\n    color: #af0000;\n}\n\n.terminal .xterm-bg-color-124 {\n    background-color: #af0000;\n}\n\n.terminal .xterm-color-125 {\n    color: #af005f;\n}\n\n.terminal .xterm-bg-color-125 {\n    background-color: #af005f;\n}\n\n.terminal .xterm-color-126 {\n    color: #af0087;\n}\n\n.terminal .xterm-bg-color-126 {\n    background-color: #af0087;\n}\n\n.terminal .xterm-color-127 {\n    color: #af00af;\n}\n\n.terminal .xterm-bg-color-127 {\n    background-color: #af00af;\n}\n\n.terminal .xterm-color-128 {\n    color: #af00d7;\n}\n\n.terminal .xterm-bg-color-128 {\n    background-color: #af00d7;\n}\n\n.terminal .xterm-color-129 {\n    color: #af00ff;\n}\n\n.terminal .xterm-bg-color-129 {\n    background-color: #af00ff;\n}\n\n.terminal .xterm-color-130 {\n    color: #af5f00;\n}\n\n.terminal .xterm-bg-color-130 {\n    background-color: #af5f00;\n}\n\n.terminal .xterm-color-131 {\n    color: #af5f5f;\n}\n\n.terminal .xterm-bg-color-131 {\n    background-color: #af5f5f;\n}\n\n.terminal .xterm-color-132 {\n    color: #af5f87;\n}\n\n.terminal .xterm-bg-color-132 {\n    background-color: #af5f87;\n}\n\n.terminal .xterm-color-133 {\n    color: #af5faf;\n}\n\n.terminal .xterm-bg-color-133 {\n    background-color: #af5faf;\n}\n\n.terminal .xterm-color-134 {\n    color: #af5fd7;\n}\n\n.terminal .xterm-bg-color-134 {\n    background-color: #af5fd7;\n}\n\n.terminal .xterm-color-135 {\n    color: #af5fff;\n}\n\n.terminal .xterm-bg-color-135 {\n    background-color: #af5fff;\n}\n\n.terminal .xterm-color-136 {\n    color: #af8700;\n}\n\n.terminal .xterm-bg-color-136 {\n    background-color: #af8700;\n}\n\n.terminal .xterm-color-137 {\n    color: #af875f;\n}\n\n.terminal .xterm-bg-color-137 {\n    background-color: #af875f;\n}\n\n.terminal .xterm-color-138 {\n    color: #af8787;\n}\n\n.terminal .xterm-bg-color-138 {\n    background-color: #af8787;\n}\n\n.terminal .xterm-color-139 {\n    color: #af87af;\n}\n\n.terminal .xterm-bg-color-139 {\n    background-color: #af87af;\n}\n\n.terminal .xterm-color-140 {\n    color: #af87d7;\n}\n\n.terminal .xterm-bg-color-140 {\n    background-color: #af87d7;\n}\n\n.terminal .xterm-color-141 {\n    color: #af87ff;\n}\n\n.terminal .xterm-bg-color-141 {\n    background-color: #af87ff;\n}\n\n.terminal .xterm-color-142 {\n    color: #afaf00;\n}\n\n.terminal .xterm-bg-color-142 {\n    background-color: #afaf00;\n}\n\n.terminal .xterm-color-143 {\n    color: #afaf5f;\n}\n\n.terminal .xterm-bg-color-143 {\n    background-color: #afaf5f;\n}\n\n.terminal .xterm-color-144 {\n    color: #afaf87;\n}\n\n.terminal .xterm-bg-color-144 {\n    background-color: #afaf87;\n}\n\n.terminal .xterm-color-145 {\n    color: #afafaf;\n}\n\n.terminal .xterm-bg-color-145 {\n    background-color: #afafaf;\n}\n\n.terminal .xterm-color-146 {\n    color: #afafd7;\n}\n\n.terminal .xterm-bg-color-146 {\n    background-color: #afafd7;\n}\n\n.terminal .xterm-color-147 {\n    color: #afafff;\n}\n\n.terminal .xterm-bg-color-147 {\n    background-color: #afafff;\n}\n\n.terminal .xterm-color-148 {\n    color: #afd700;\n}\n\n.terminal .xterm-bg-color-148 {\n    background-color: #afd700;\n}\n\n.terminal .xterm-color-149 {\n    color: #afd75f;\n}\n\n.terminal .xterm-bg-color-149 {\n    background-color: #afd75f;\n}\n\n.terminal .xterm-color-150 {\n    color: #afd787;\n}\n\n.terminal .xterm-bg-color-150 {\n    background-color: #afd787;\n}\n\n.terminal .xterm-color-151 {\n    color: #afd7af;\n}\n\n.terminal .xterm-bg-color-151 {\n    background-color: #afd7af;\n}\n\n.terminal .xterm-color-152 {\n    color: #afd7d7;\n}\n\n.terminal .xterm-bg-color-152 {\n    background-color: #afd7d7;\n}\n\n.terminal .xterm-color-153 {\n    color: #afd7ff;\n}\n\n.terminal .xterm-bg-color-153 {\n    background-color: #afd7ff;\n}\n\n.terminal .xterm-color-154 {\n    color: #afff00;\n}\n\n.terminal .xterm-bg-color-154 {\n    background-color: #afff00;\n}\n\n.terminal .xterm-color-155 {\n    color: #afff5f;\n}\n\n.terminal .xterm-bg-color-155 {\n    background-color: #afff5f;\n}\n\n.terminal .xterm-color-156 {\n    color: #afff87;\n}\n\n.terminal .xterm-bg-color-156 {\n    background-color: #afff87;\n}\n\n.terminal .xterm-color-157 {\n    color: #afffaf;\n}\n\n.terminal .xterm-bg-color-157 {\n    background-color: #afffaf;\n}\n\n.terminal .xterm-color-158 {\n    color: #afffd7;\n}\n\n.terminal .xterm-bg-color-158 {\n    background-color: #afffd7;\n}\n\n.terminal .xterm-color-159 {\n    color: #afffff;\n}\n\n.terminal .xterm-bg-color-159 {\n    background-color: #afffff;\n}\n\n.terminal .xterm-color-160 {\n    color: #d70000;\n}\n\n.terminal .xterm-bg-color-160 {\n    background-color: #d70000;\n}\n\n.terminal .xterm-color-161 {\n    color: #d7005f;\n}\n\n.terminal .xterm-bg-color-161 {\n    background-color: #d7005f;\n}\n\n.terminal .xterm-color-162 {\n    color: #d70087;\n}\n\n.terminal .xterm-bg-color-162 {\n    background-color: #d70087;\n}\n\n.terminal .xterm-color-163 {\n    color: #d700af;\n}\n\n.terminal .xterm-bg-color-163 {\n    background-color: #d700af;\n}\n\n.terminal .xterm-color-164 {\n    color: #d700d7;\n}\n\n.terminal .xterm-bg-color-164 {\n    background-color: #d700d7;\n}\n\n.terminal .xterm-color-165 {\n    color: #d700ff;\n}\n\n.terminal .xterm-bg-color-165 {\n    background-color: #d700ff;\n}\n\n.terminal .xterm-color-166 {\n    color: #d75f00;\n}\n\n.terminal .xterm-bg-color-166 {\n    background-color: #d75f00;\n}\n\n.terminal .xterm-color-167 {\n    color: #d75f5f;\n}\n\n.terminal .xterm-bg-color-167 {\n    background-color: #d75f5f;\n}\n\n.terminal .xterm-color-168 {\n    color: #d75f87;\n}\n\n.terminal .xterm-bg-color-168 {\n    background-color: #d75f87;\n}\n\n.terminal .xterm-color-169 {\n    color: #d75faf;\n}\n\n.terminal .xterm-bg-color-169 {\n    background-color: #d75faf;\n}\n\n.terminal .xterm-color-170 {\n    color: #d75fd7;\n}\n\n.terminal .xterm-bg-color-170 {\n    background-color: #d75fd7;\n}\n\n.terminal .xterm-color-171 {\n    color: #d75fff;\n}\n\n.terminal .xterm-bg-color-171 {\n    background-color: #d75fff;\n}\n\n.terminal .xterm-color-172 {\n    color: #d78700;\n}\n\n.terminal .xterm-bg-color-172 {\n    background-color: #d78700;\n}\n\n.terminal .xterm-color-173 {\n    color: #d7875f;\n}\n\n.terminal .xterm-bg-color-173 {\n    background-color: #d7875f;\n}\n\n.terminal .xterm-color-174 {\n    color: #d78787;\n}\n\n.terminal .xterm-bg-color-174 {\n    background-color: #d78787;\n}\n\n.terminal .xterm-color-175 {\n    color: #d787af;\n}\n\n.terminal .xterm-bg-color-175 {\n    background-color: #d787af;\n}\n\n.terminal .xterm-color-176 {\n    color: #d787d7;\n}\n\n.terminal .xterm-bg-color-176 {\n    background-color: #d787d7;\n}\n\n.terminal .xterm-color-177 {\n    color: #d787ff;\n}\n\n.terminal .xterm-bg-color-177 {\n    background-color: #d787ff;\n}\n\n.terminal .xterm-color-178 {\n    color: #d7af00;\n}\n\n.terminal .xterm-bg-color-178 {\n    background-color: #d7af00;\n}\n\n.terminal .xterm-color-179 {\n    color: #d7af5f;\n}\n\n.terminal .xterm-bg-color-179 {\n    background-color: #d7af5f;\n}\n\n.terminal .xterm-color-180 {\n    color: #d7af87;\n}\n\n.terminal .xterm-bg-color-180 {\n    background-color: #d7af87;\n}\n\n.terminal .xterm-color-181 {\n    color: #d7afaf;\n}\n\n.terminal .xterm-bg-color-181 {\n    background-color: #d7afaf;\n}\n\n.terminal .xterm-color-182 {\n    color: #d7afd7;\n}\n\n.terminal .xterm-bg-color-182 {\n    background-color: #d7afd7;\n}\n\n.terminal .xterm-color-183 {\n    color: #d7afff;\n}\n\n.terminal .xterm-bg-color-183 {\n    background-color: #d7afff;\n}\n\n.terminal .xterm-color-184 {\n    color: #d7d700;\n}\n\n.terminal .xterm-bg-color-184 {\n    background-color: #d7d700;\n}\n\n.terminal .xterm-color-185 {\n    color: #d7d75f;\n}\n\n.terminal .xterm-bg-color-185 {\n    background-color: #d7d75f;\n}\n\n.terminal .xterm-color-186 {\n    color: #d7d787;\n}\n\n.terminal .xterm-bg-color-186 {\n    background-color: #d7d787;\n}\n\n.terminal .xterm-color-187 {\n    color: #d7d7af;\n}\n\n.terminal .xterm-bg-color-187 {\n    background-color: #d7d7af;\n}\n\n.terminal .xterm-color-188 {\n    color: #d7d7d7;\n}\n\n.terminal .xterm-bg-color-188 {\n    background-color: #d7d7d7;\n}\n\n.terminal .xterm-color-189 {\n    color: #d7d7ff;\n}\n\n.terminal .xterm-bg-color-189 {\n    background-color: #d7d7ff;\n}\n\n.terminal .xterm-color-190 {\n    color: #d7ff00;\n}\n\n.terminal .xterm-bg-color-190 {\n    background-color: #d7ff00;\n}\n\n.terminal .xterm-color-191 {\n    color: #d7ff5f;\n}\n\n.terminal .xterm-bg-color-191 {\n    background-color: #d7ff5f;\n}\n\n.terminal .xterm-color-192 {\n    color: #d7ff87;\n}\n\n.terminal .xterm-bg-color-192 {\n    background-color: #d7ff87;\n}\n\n.terminal .xterm-color-193 {\n    color: #d7ffaf;\n}\n\n.terminal .xterm-bg-color-193 {\n    background-color: #d7ffaf;\n}\n\n.terminal .xterm-color-194 {\n    color: #d7ffd7;\n}\n\n.terminal .xterm-bg-color-194 {\n    background-color: #d7ffd7;\n}\n\n.terminal .xterm-color-195 {\n    color: #d7ffff;\n}\n\n.terminal .xterm-bg-color-195 {\n    background-color: #d7ffff;\n}\n\n.terminal .xterm-color-196 {\n    color: #ff0000;\n}\n\n.terminal .xterm-bg-color-196 {\n    background-color: #ff0000;\n}\n\n.terminal .xterm-color-197 {\n    color: #ff005f;\n}\n\n.terminal .xterm-bg-color-197 {\n    background-color: #ff005f;\n}\n\n.terminal .xterm-color-198 {\n    color: #ff0087;\n}\n\n.terminal .xterm-bg-color-198 {\n    background-color: #ff0087;\n}\n\n.terminal .xterm-color-199 {\n    color: #ff00af;\n}\n\n.terminal .xterm-bg-color-199 {\n    background-color: #ff00af;\n}\n\n.terminal .xterm-color-200 {\n    color: #ff00d7;\n}\n\n.terminal .xterm-bg-color-200 {\n    background-color: #ff00d7;\n}\n\n.terminal .xterm-color-201 {\n    color: #ff00ff;\n}\n\n.terminal .xterm-bg-color-201 {\n    background-color: #ff00ff;\n}\n\n.terminal .xterm-color-202 {\n    color: #ff5f00;\n}\n\n.terminal .xterm-bg-color-202 {\n    background-color: #ff5f00;\n}\n\n.terminal .xterm-color-203 {\n    color: #ff5f5f;\n}\n\n.terminal .xterm-bg-color-203 {\n    background-color: #ff5f5f;\n}\n\n.terminal .xterm-color-204 {\n    color: #ff5f87;\n}\n\n.terminal .xterm-bg-color-204 {\n    background-color: #ff5f87;\n}\n\n.terminal .xterm-color-205 {\n    color: #ff5faf;\n}\n\n.terminal .xterm-bg-color-205 {\n    background-color: #ff5faf;\n}\n\n.terminal .xterm-color-206 {\n    color: #ff5fd7;\n}\n\n.terminal .xterm-bg-color-206 {\n    background-color: #ff5fd7;\n}\n\n.terminal .xterm-color-207 {\n    color: #ff5fff;\n}\n\n.terminal .xterm-bg-color-207 {\n    background-color: #ff5fff;\n}\n\n.terminal .xterm-color-208 {\n    color: #ff8700;\n}\n\n.terminal .xterm-bg-color-208 {\n    background-color: #ff8700;\n}\n\n.terminal .xterm-color-209 {\n    color: #ff875f;\n}\n\n.terminal .xterm-bg-color-209 {\n    background-color: #ff875f;\n}\n\n.terminal .xterm-color-210 {\n    color: #ff8787;\n}\n\n.terminal .xterm-bg-color-210 {\n    background-color: #ff8787;\n}\n\n.terminal .xterm-color-211 {\n    color: #ff87af;\n}\n\n.terminal .xterm-bg-color-211 {\n    background-color: #ff87af;\n}\n\n.terminal .xterm-color-212 {\n    color: #ff87d7;\n}\n\n.terminal .xterm-bg-color-212 {\n    background-color: #ff87d7;\n}\n\n.terminal .xterm-color-213 {\n    color: #ff87ff;\n}\n\n.terminal .xterm-bg-color-213 {\n    background-color: #ff87ff;\n}\n\n.terminal .xterm-color-214 {\n    color: #ffaf00;\n}\n\n.terminal .xterm-bg-color-214 {\n    background-color: #ffaf00;\n}\n\n.terminal .xterm-color-215 {\n    color: #ffaf5f;\n}\n\n.terminal .xterm-bg-color-215 {\n    background-color: #ffaf5f;\n}\n\n.terminal .xterm-color-216 {\n    color: #ffaf87;\n}\n\n.terminal .xterm-bg-color-216 {\n    background-color: #ffaf87;\n}\n\n.terminal .xterm-color-217 {\n    color: #ffafaf;\n}\n\n.terminal .xterm-bg-color-217 {\n    background-color: #ffafaf;\n}\n\n.terminal .xterm-color-218 {\n    color: #ffafd7;\n}\n\n.terminal .xterm-bg-color-218 {\n    background-color: #ffafd7;\n}\n\n.terminal .xterm-color-219 {\n    color: #ffafff;\n}\n\n.terminal .xterm-bg-color-219 {\n    background-color: #ffafff;\n}\n\n.terminal .xterm-color-220 {\n    color: #ffd700;\n}\n\n.terminal .xterm-bg-color-220 {\n    background-color: #ffd700;\n}\n\n.terminal .xterm-color-221 {\n    color: #ffd75f;\n}\n\n.terminal .xterm-bg-color-221 {\n    background-color: #ffd75f;\n}\n\n.terminal .xterm-color-222 {\n    color: #ffd787;\n}\n\n.terminal .xterm-bg-color-222 {\n    background-color: #ffd787;\n}\n\n.terminal .xterm-color-223 {\n    color: #ffd7af;\n}\n\n.terminal .xterm-bg-color-223 {\n    background-color: #ffd7af;\n}\n\n.terminal .xterm-color-224 {\n    color: #ffd7d7;\n}\n\n.terminal .xterm-bg-color-224 {\n    background-color: #ffd7d7;\n}\n\n.terminal .xterm-color-225 {\n    color: #ffd7ff;\n}\n\n.terminal .xterm-bg-color-225 {\n    background-color: #ffd7ff;\n}\n\n.terminal .xterm-color-226 {\n    color: #ffff00;\n}\n\n.terminal .xterm-bg-color-226 {\n    background-color: #ffff00;\n}\n\n.terminal .xterm-color-227 {\n    color: #ffff5f;\n}\n\n.terminal .xterm-bg-color-227 {\n    background-color: #ffff5f;\n}\n\n.terminal .xterm-color-228 {\n    color: #ffff87;\n}\n\n.terminal .xterm-bg-color-228 {\n    background-color: #ffff87;\n}\n\n.terminal .xterm-color-229 {\n    color: #ffffaf;\n}\n\n.terminal .xterm-bg-color-229 {\n    background-color: #ffffaf;\n}\n\n.terminal .xterm-color-230 {\n    color: #ffffd7;\n}\n\n.terminal .xterm-bg-color-230 {\n    background-color: #ffffd7;\n}\n\n.terminal .xterm-color-231 {\n    color: #ffffff;\n}\n\n.terminal .xterm-bg-color-231 {\n    background-color: #ffffff;\n}\n\n.terminal .xterm-color-232 {\n    color: #080808;\n}\n\n.terminal .xterm-bg-color-232 {\n    background-color: #080808;\n}\n\n.terminal .xterm-color-233 {\n    color: #121212;\n}\n\n.terminal .xterm-bg-color-233 {\n    background-color: #121212;\n}\n\n.terminal .xterm-color-234 {\n    color: #1c1c1c;\n}\n\n.terminal .xterm-bg-color-234 {\n    background-color: #1c1c1c;\n}\n\n.terminal .xterm-color-235 {\n    color: #262626;\n}\n\n.terminal .xterm-bg-color-235 {\n    background-color: #262626;\n}\n\n.terminal .xterm-color-236 {\n    color: #303030;\n}\n\n.terminal .xterm-bg-color-236 {\n    background-color: #303030;\n}\n\n.terminal .xterm-color-237 {\n    color: #3a3a3a;\n}\n\n.terminal .xterm-bg-color-237 {\n    background-color: #3a3a3a;\n}\n\n.terminal .xterm-color-238 {\n    color: #444444;\n}\n\n.terminal .xterm-bg-color-238 {\n    background-color: #444444;\n}\n\n.terminal .xterm-color-239 {\n    color: #4e4e4e;\n}\n\n.terminal .xterm-bg-color-239 {\n    background-color: #4e4e4e;\n}\n\n.terminal .xterm-color-240 {\n    color: #585858;\n}\n\n.terminal .xterm-bg-color-240 {\n    background-color: #585858;\n}\n\n.terminal .xterm-color-241 {\n    color: #626262;\n}\n\n.terminal .xterm-bg-color-241 {\n    background-color: #626262;\n}\n\n.terminal .xterm-color-242 {\n    color: #6c6c6c;\n}\n\n.terminal .xterm-bg-color-242 {\n    background-color: #6c6c6c;\n}\n\n.terminal .xterm-color-243 {\n    color: #767676;\n}\n\n.terminal .xterm-bg-color-243 {\n    background-color: #767676;\n}\n\n.terminal .xterm-color-244 {\n    color: #808080;\n}\n\n.terminal .xterm-bg-color-244 {\n    background-color: #808080;\n}\n\n.terminal .xterm-color-245 {\n    color: #8a8a8a;\n}\n\n.terminal .xterm-bg-color-245 {\n    background-color: #8a8a8a;\n}\n\n.terminal .xterm-color-246 {\n    color: #949494;\n}\n\n.terminal .xterm-bg-color-246 {\n    background-color: #949494;\n}\n\n.terminal .xterm-color-247 {\n    color: #9e9e9e;\n}\n\n.terminal .xterm-bg-color-247 {\n    background-color: #9e9e9e;\n}\n\n.terminal .xterm-color-248 {\n    color: #a8a8a8;\n}\n\n.terminal .xterm-bg-color-248 {\n    background-color: #a8a8a8;\n}\n\n.terminal .xterm-color-249 {\n    color: #b2b2b2;\n}\n\n.terminal .xterm-bg-color-249 {\n    background-color: #b2b2b2;\n}\n\n.terminal .xterm-color-250 {\n    color: #bcbcbc;\n}\n\n.terminal .xterm-bg-color-250 {\n    background-color: #bcbcbc;\n}\n\n.terminal .xterm-color-251 {\n    color: #c6c6c6;\n}\n\n.terminal .xterm-bg-color-251 {\n    background-color: #c6c6c6;\n}\n\n.terminal .xterm-color-252 {\n    color: #d0d0d0;\n}\n\n.terminal .xterm-bg-color-252 {\n    background-color: #d0d0d0;\n}\n\n.terminal .xterm-color-253 {\n    color: #dadada;\n}\n\n.terminal .xterm-bg-color-253 {\n    background-color: #dadada;\n}\n\n.terminal .xterm-color-254 {\n    color: #e4e4e4;\n}\n\n.terminal .xterm-bg-color-254 {\n    background-color: #e4e4e4;\n}\n\n.terminal .xterm-color-255 {\n    color: #eeeeee;\n}\n\n.terminal .xterm-bg-color-255 {\n    background-color: #eeeeee;\n}\n"
  },
  {
    "path": "static/assets/js/bootstrap.js",
    "content": "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under the MIT license\n */\n\nif (typeof jQuery === 'undefined') {\n  throw new Error('Bootstrap\\'s JavaScript requires jQuery')\n}\n\n+function ($) {\n  'use strict';\n  var version = $.fn.jquery.split(' ')[0].split('.')\n  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {\n    throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher')\n  }\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: transition.js v3.3.5\n * http://getbootstrap.com/javascript/#transitions\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)\n  // ============================================================\n\n  function transitionEnd() {\n    var el = document.createElement('bootstrap')\n\n    var transEndEventNames = {\n      WebkitTransition : 'webkitTransitionEnd',\n      MozTransition    : 'transitionend',\n      OTransition      : 'oTransitionEnd otransitionend',\n      transition       : 'transitionend'\n    }\n\n    for (var name in transEndEventNames) {\n      if (el.style[name] !== undefined) {\n        return { end: transEndEventNames[name] }\n      }\n    }\n\n    return false // explicit for ie8 (  ._.)\n  }\n\n  // http://blog.alexmaccaw.com/css-transitions\n  $.fn.emulateTransitionEnd = function (duration) {\n    var called = false\n    var $el = this\n    $(this).one('bsTransitionEnd', function () { called = true })\n    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n    setTimeout(callback, duration)\n    return this\n  }\n\n  $(function () {\n    $.support.transition = transitionEnd()\n\n    if (!$.support.transition) return\n\n    $.event.special.bsTransitionEnd = {\n      bindType: $.support.transition.end,\n      delegateType: $.support.transition.end,\n      handle: function (e) {\n        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)\n      }\n    }\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: alert.js v3.3.5\n * http://getbootstrap.com/javascript/#alerts\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // ALERT CLASS DEFINITION\n  // ======================\n\n  var dismiss = '[data-dismiss=\"alert\"]'\n  var Alert   = function (el) {\n    $(el).on('click', dismiss, this.close)\n  }\n\n  Alert.VERSION = '3.3.5'\n\n  Alert.TRANSITION_DURATION = 150\n\n  Alert.prototype.close = function (e) {\n    var $this    = $(this)\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = $(selector)\n\n    if (e) e.preventDefault()\n\n    if (!$parent.length) {\n      $parent = $this.closest('.alert')\n    }\n\n    $parent.trigger(e = $.Event('close.bs.alert'))\n\n    if (e.isDefaultPrevented()) return\n\n    $parent.removeClass('in')\n\n    function removeElement() {\n      // detach from parent, fire event then clean up data\n      $parent.detach().trigger('closed.bs.alert').remove()\n    }\n\n    $.support.transition && $parent.hasClass('fade') ?\n      $parent\n        .one('bsTransitionEnd', removeElement)\n        .emulateTransitionEnd(Alert.TRANSITION_DURATION) :\n      removeElement()\n  }\n\n\n  // ALERT PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.alert')\n\n      if (!data) $this.data('bs.alert', (data = new Alert(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  var old = $.fn.alert\n\n  $.fn.alert             = Plugin\n  $.fn.alert.Constructor = Alert\n\n\n  // ALERT NO CONFLICT\n  // =================\n\n  $.fn.alert.noConflict = function () {\n    $.fn.alert = old\n    return this\n  }\n\n\n  // ALERT DATA-API\n  // ==============\n\n  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: button.js v3.3.5\n * http://getbootstrap.com/javascript/#buttons\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // BUTTON PUBLIC CLASS DEFINITION\n  // ==============================\n\n  var Button = function (element, options) {\n    this.$element  = $(element)\n    this.options   = $.extend({}, Button.DEFAULTS, options)\n    this.isLoading = false\n  }\n\n  Button.VERSION  = '3.3.5'\n\n  Button.DEFAULTS = {\n    loadingText: 'loading...'\n  }\n\n  Button.prototype.setState = function (state) {\n    var d    = 'disabled'\n    var $el  = this.$element\n    var val  = $el.is('input') ? 'val' : 'html'\n    var data = $el.data()\n\n    state += 'Text'\n\n    if (data.resetText == null) $el.data('resetText', $el[val]())\n\n    // push to event loop to allow forms to submit\n    setTimeout($.proxy(function () {\n      $el[val](data[state] == null ? this.options[state] : data[state])\n\n      if (state == 'loadingText') {\n        this.isLoading = true\n        $el.addClass(d).attr(d, d)\n      } else if (this.isLoading) {\n        this.isLoading = false\n        $el.removeClass(d).removeAttr(d)\n      }\n    }, this), 0)\n  }\n\n  Button.prototype.toggle = function () {\n    var changed = true\n    var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n\n    if ($parent.length) {\n      var $input = this.$element.find('input')\n      if ($input.prop('type') == 'radio') {\n        if ($input.prop('checked')) changed = false\n        $parent.find('.active').removeClass('active')\n        this.$element.addClass('active')\n      } else if ($input.prop('type') == 'checkbox') {\n        if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false\n        this.$element.toggleClass('active')\n      }\n      $input.prop('checked', this.$element.hasClass('active'))\n      if (changed) $input.trigger('change')\n    } else {\n      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))\n      this.$element.toggleClass('active')\n    }\n  }\n\n\n  // BUTTON PLUGIN DEFINITION\n  // ========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.button')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n      if (option == 'toggle') data.toggle()\n      else if (option) data.setState(option)\n    })\n  }\n\n  var old = $.fn.button\n\n  $.fn.button             = Plugin\n  $.fn.button.Constructor = Button\n\n\n  // BUTTON NO CONFLICT\n  // ==================\n\n  $.fn.button.noConflict = function () {\n    $.fn.button = old\n    return this\n  }\n\n\n  // BUTTON DATA-API\n  // ===============\n\n  $(document)\n    .on('click.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n      var $btn = $(e.target)\n      if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')\n      Plugin.call($btn, 'toggle')\n      if (!($(e.target).is('input[type=\"radio\"]') || $(e.target).is('input[type=\"checkbox\"]'))) e.preventDefault()\n    })\n    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))\n    })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: carousel.js v3.3.5\n * http://getbootstrap.com/javascript/#carousel\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // CAROUSEL CLASS DEFINITION\n  // =========================\n\n  var Carousel = function (element, options) {\n    this.$element    = $(element)\n    this.$indicators = this.$element.find('.carousel-indicators')\n    this.options     = options\n    this.paused      = null\n    this.sliding     = null\n    this.interval    = null\n    this.$active     = null\n    this.$items      = null\n\n    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))\n\n    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element\n      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))\n      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))\n  }\n\n  Carousel.VERSION  = '3.3.5'\n\n  Carousel.TRANSITION_DURATION = 600\n\n  Carousel.DEFAULTS = {\n    interval: 5000,\n    pause: 'hover',\n    wrap: true,\n    keyboard: true\n  }\n\n  Carousel.prototype.keydown = function (e) {\n    if (/input|textarea/i.test(e.target.tagName)) return\n    switch (e.which) {\n      case 37: this.prev(); break\n      case 39: this.next(); break\n      default: return\n    }\n\n    e.preventDefault()\n  }\n\n  Carousel.prototype.cycle = function (e) {\n    e || (this.paused = false)\n\n    this.interval && clearInterval(this.interval)\n\n    this.options.interval\n      && !this.paused\n      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n    return this\n  }\n\n  Carousel.prototype.getItemIndex = function (item) {\n    this.$items = item.parent().children('.item')\n    return this.$items.index(item || this.$active)\n  }\n\n  Carousel.prototype.getItemForDirection = function (direction, active) {\n    var activeIndex = this.getItemIndex(active)\n    var willWrap = (direction == 'prev' && activeIndex === 0)\n                || (direction == 'next' && activeIndex == (this.$items.length - 1))\n    if (willWrap && !this.options.wrap) return active\n    var delta = direction == 'prev' ? -1 : 1\n    var itemIndex = (activeIndex + delta) % this.$items.length\n    return this.$items.eq(itemIndex)\n  }\n\n  Carousel.prototype.to = function (pos) {\n    var that        = this\n    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))\n\n    if (pos > (this.$items.length - 1) || pos < 0) return\n\n    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, \"slid\"\n    if (activeIndex == pos) return this.pause().cycle()\n\n    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))\n  }\n\n  Carousel.prototype.pause = function (e) {\n    e || (this.paused = true)\n\n    if (this.$element.find('.next, .prev').length && $.support.transition) {\n      this.$element.trigger($.support.transition.end)\n      this.cycle(true)\n    }\n\n    this.interval = clearInterval(this.interval)\n\n    return this\n  }\n\n  Carousel.prototype.next = function () {\n    if (this.sliding) return\n    return this.slide('next')\n  }\n\n  Carousel.prototype.prev = function () {\n    if (this.sliding) return\n    return this.slide('prev')\n  }\n\n  Carousel.prototype.slide = function (type, next) {\n    var $active   = this.$element.find('.item.active')\n    var $next     = next || this.getItemForDirection(type, $active)\n    var isCycling = this.interval\n    var direction = type == 'next' ? 'left' : 'right'\n    var that      = this\n\n    if ($next.hasClass('active')) return (this.sliding = false)\n\n    var relatedTarget = $next[0]\n    var slideEvent = $.Event('slide.bs.carousel', {\n      relatedTarget: relatedTarget,\n      direction: direction\n    })\n    this.$element.trigger(slideEvent)\n    if (slideEvent.isDefaultPrevented()) return\n\n    this.sliding = true\n\n    isCycling && this.pause()\n\n    if (this.$indicators.length) {\n      this.$indicators.find('.active').removeClass('active')\n      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])\n      $nextIndicator && $nextIndicator.addClass('active')\n    }\n\n    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, \"slid\"\n    if ($.support.transition && this.$element.hasClass('slide')) {\n      $next.addClass(type)\n      $next[0].offsetWidth // force reflow\n      $active.addClass(direction)\n      $next.addClass(direction)\n      $active\n        .one('bsTransitionEnd', function () {\n          $next.removeClass([type, direction].join(' ')).addClass('active')\n          $active.removeClass(['active', direction].join(' '))\n          that.sliding = false\n          setTimeout(function () {\n            that.$element.trigger(slidEvent)\n          }, 0)\n        })\n        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)\n    } else {\n      $active.removeClass('active')\n      $next.addClass('active')\n      this.sliding = false\n      this.$element.trigger(slidEvent)\n    }\n\n    isCycling && this.cycle()\n\n    return this\n  }\n\n\n  // CAROUSEL PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.carousel')\n      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n      var action  = typeof option == 'string' ? option : options.slide\n\n      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n      if (typeof option == 'number') data.to(option)\n      else if (action) data[action]()\n      else if (options.interval) data.pause().cycle()\n    })\n  }\n\n  var old = $.fn.carousel\n\n  $.fn.carousel             = Plugin\n  $.fn.carousel.Constructor = Carousel\n\n\n  // CAROUSEL NO CONFLICT\n  // ====================\n\n  $.fn.carousel.noConflict = function () {\n    $.fn.carousel = old\n    return this\n  }\n\n\n  // CAROUSEL DATA-API\n  // =================\n\n  var clickHandler = function (e) {\n    var href\n    var $this   = $(this)\n    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) // strip for ie7\n    if (!$target.hasClass('carousel')) return\n    var options = $.extend({}, $target.data(), $this.data())\n    var slideIndex = $this.attr('data-slide-to')\n    if (slideIndex) options.interval = false\n\n    Plugin.call($target, options)\n\n    if (slideIndex) {\n      $target.data('bs.carousel').to(slideIndex)\n    }\n\n    e.preventDefault()\n  }\n\n  $(document)\n    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)\n    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)\n\n  $(window).on('load', function () {\n    $('[data-ride=\"carousel\"]').each(function () {\n      var $carousel = $(this)\n      Plugin.call($carousel, $carousel.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: collapse.js v3.3.5\n * http://getbootstrap.com/javascript/#collapse\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // COLLAPSE PUBLIC CLASS DEFINITION\n  // ================================\n\n  var Collapse = function (element, options) {\n    this.$element      = $(element)\n    this.options       = $.extend({}, Collapse.DEFAULTS, options)\n    this.$trigger      = $('[data-toggle=\"collapse\"][href=\"#' + element.id + '\"],' +\n                           '[data-toggle=\"collapse\"][data-target=\"#' + element.id + '\"]')\n    this.transitioning = null\n\n    if (this.options.parent) {\n      this.$parent = this.getParent()\n    } else {\n      this.addAriaAndCollapsedClass(this.$element, this.$trigger)\n    }\n\n    if (this.options.toggle) this.toggle()\n  }\n\n  Collapse.VERSION  = '3.3.5'\n\n  Collapse.TRANSITION_DURATION = 350\n\n  Collapse.DEFAULTS = {\n    toggle: true\n  }\n\n  Collapse.prototype.dimension = function () {\n    var hasWidth = this.$element.hasClass('width')\n    return hasWidth ? 'width' : 'height'\n  }\n\n  Collapse.prototype.show = function () {\n    if (this.transitioning || this.$element.hasClass('in')) return\n\n    var activesData\n    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')\n\n    if (actives && actives.length) {\n      activesData = actives.data('bs.collapse')\n      if (activesData && activesData.transitioning) return\n    }\n\n    var startEvent = $.Event('show.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    if (actives && actives.length) {\n      Plugin.call(actives, 'hide')\n      activesData || actives.data('bs.collapse', null)\n    }\n\n    var dimension = this.dimension()\n\n    this.$element\n      .removeClass('collapse')\n      .addClass('collapsing')[dimension](0)\n      .attr('aria-expanded', true)\n\n    this.$trigger\n      .removeClass('collapsed')\n      .attr('aria-expanded', true)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.$element\n        .removeClass('collapsing')\n        .addClass('collapse in')[dimension]('')\n      this.transitioning = 0\n      this.$element\n        .trigger('shown.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n    this.$element\n      .one('bsTransitionEnd', $.proxy(complete, this))\n      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])\n  }\n\n  Collapse.prototype.hide = function () {\n    if (this.transitioning || !this.$element.hasClass('in')) return\n\n    var startEvent = $.Event('hide.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    var dimension = this.dimension()\n\n    this.$element[dimension](this.$element[dimension]())[0].offsetHeight\n\n    this.$element\n      .addClass('collapsing')\n      .removeClass('collapse in')\n      .attr('aria-expanded', false)\n\n    this.$trigger\n      .addClass('collapsed')\n      .attr('aria-expanded', false)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.transitioning = 0\n      this.$element\n        .removeClass('collapsing')\n        .addClass('collapse')\n        .trigger('hidden.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    this.$element\n      [dimension](0)\n      .one('bsTransitionEnd', $.proxy(complete, this))\n      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)\n  }\n\n  Collapse.prototype.toggle = function () {\n    this[this.$element.hasClass('in') ? 'hide' : 'show']()\n  }\n\n  Collapse.prototype.getParent = function () {\n    return $(this.options.parent)\n      .find('[data-toggle=\"collapse\"][data-parent=\"' + this.options.parent + '\"]')\n      .each($.proxy(function (i, element) {\n        var $element = $(element)\n        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)\n      }, this))\n      .end()\n  }\n\n  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {\n    var isOpen = $element.hasClass('in')\n\n    $element.attr('aria-expanded', isOpen)\n    $trigger\n      .toggleClass('collapsed', !isOpen)\n      .attr('aria-expanded', isOpen)\n  }\n\n  function getTargetFromTrigger($trigger) {\n    var href\n    var target = $trigger.attr('data-target')\n      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') // strip for ie7\n\n    return $(target)\n  }\n\n\n  // COLLAPSE PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.collapse')\n      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false\n      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.collapse\n\n  $.fn.collapse             = Plugin\n  $.fn.collapse.Constructor = Collapse\n\n\n  // COLLAPSE NO CONFLICT\n  // ====================\n\n  $.fn.collapse.noConflict = function () {\n    $.fn.collapse = old\n    return this\n  }\n\n\n  // COLLAPSE DATA-API\n  // =================\n\n  $(document).on('click.bs.collapse.data-api', '[data-toggle=\"collapse\"]', function (e) {\n    var $this   = $(this)\n\n    if (!$this.attr('data-target')) e.preventDefault()\n\n    var $target = getTargetFromTrigger($this)\n    var data    = $target.data('bs.collapse')\n    var option  = data ? 'toggle' : $this.data()\n\n    Plugin.call($target, option)\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: dropdown.js v3.3.5\n * http://getbootstrap.com/javascript/#dropdowns\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // DROPDOWN CLASS DEFINITION\n  // =========================\n\n  var backdrop = '.dropdown-backdrop'\n  var toggle   = '[data-toggle=\"dropdown\"]'\n  var Dropdown = function (element) {\n    $(element).on('click.bs.dropdown', this.toggle)\n  }\n\n  Dropdown.VERSION = '3.3.5'\n\n  function getParent($this) {\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = selector && $(selector)\n\n    return $parent && $parent.length ? $parent : $this.parent()\n  }\n\n  function clearMenus(e) {\n    if (e && e.which === 3) return\n    $(backdrop).remove()\n    $(toggle).each(function () {\n      var $this         = $(this)\n      var $parent       = getParent($this)\n      var relatedTarget = { relatedTarget: this }\n\n      if (!$parent.hasClass('open')) return\n\n      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return\n\n      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))\n\n      if (e.isDefaultPrevented()) return\n\n      $this.attr('aria-expanded', 'false')\n      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)\n    })\n  }\n\n  Dropdown.prototype.toggle = function (e) {\n    var $this = $(this)\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    clearMenus()\n\n    if (!isActive) {\n      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n        // if mobile we use a backdrop because click events don't delegate\n        $(document.createElement('div'))\n          .addClass('dropdown-backdrop')\n          .insertAfter($(this))\n          .on('click', clearMenus)\n      }\n\n      var relatedTarget = { relatedTarget: this }\n      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))\n\n      if (e.isDefaultPrevented()) return\n\n      $this\n        .trigger('focus')\n        .attr('aria-expanded', 'true')\n\n      $parent\n        .toggleClass('open')\n        .trigger('shown.bs.dropdown', relatedTarget)\n    }\n\n    return false\n  }\n\n  Dropdown.prototype.keydown = function (e) {\n    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return\n\n    var $this = $(this)\n\n    e.preventDefault()\n    e.stopPropagation()\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    if (!isActive && e.which != 27 || isActive && e.which == 27) {\n      if (e.which == 27) $parent.find(toggle).trigger('focus')\n      return $this.trigger('click')\n    }\n\n    var desc = ' li:not(.disabled):visible a'\n    var $items = $parent.find('.dropdown-menu' + desc)\n\n    if (!$items.length) return\n\n    var index = $items.index(e.target)\n\n    if (e.which == 38 && index > 0)                 index--         // up\n    if (e.which == 40 && index < $items.length - 1) index++         // down\n    if (!~index)                                    index = 0\n\n    $items.eq(index).trigger('focus')\n  }\n\n\n  // DROPDOWN PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.dropdown')\n\n      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  var old = $.fn.dropdown\n\n  $.fn.dropdown             = Plugin\n  $.fn.dropdown.Constructor = Dropdown\n\n\n  // DROPDOWN NO CONFLICT\n  // ====================\n\n  $.fn.dropdown.noConflict = function () {\n    $.fn.dropdown = old\n    return this\n  }\n\n\n  // APPLY TO STANDARD DROPDOWN ELEMENTS\n  // ===================================\n\n  $(document)\n    .on('click.bs.dropdown.data-api', clearMenus)\n    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)\n    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)\n    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: modal.js v3.3.5\n * http://getbootstrap.com/javascript/#modals\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // MODAL CLASS DEFINITION\n  // ======================\n\n  var Modal = function (element, options) {\n    this.options             = options\n    this.$body               = $(document.body)\n    this.$element            = $(element)\n    this.$dialog             = this.$element.find('.modal-dialog')\n    this.$backdrop           = null\n    this.isShown             = null\n    this.originalBodyPad     = null\n    this.scrollbarWidth      = 0\n    this.ignoreBackdropClick = false\n\n    if (this.options.remote) {\n      this.$element\n        .find('.modal-content')\n        .load(this.options.remote, $.proxy(function () {\n          this.$element.trigger('loaded.bs.modal')\n        }, this))\n    }\n  }\n\n  Modal.VERSION  = '3.3.5'\n\n  Modal.TRANSITION_DURATION = 300\n  Modal.BACKDROP_TRANSITION_DURATION = 150\n\n  Modal.DEFAULTS = {\n    backdrop: true,\n    keyboard: true,\n    show: true\n  }\n\n  Modal.prototype.toggle = function (_relatedTarget) {\n    return this.isShown ? this.hide() : this.show(_relatedTarget)\n  }\n\n  Modal.prototype.show = function (_relatedTarget) {\n    var that = this\n    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n    this.$element.trigger(e)\n\n    if (this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = true\n\n    this.checkScrollbar()\n    this.setScrollbar()\n    this.$body.addClass('modal-open')\n\n    this.escape()\n    this.resize()\n\n    this.$element.on('click.dismiss.bs.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n    this.$dialog.on('mousedown.dismiss.bs.modal', function () {\n      that.$element.one('mouseup.dismiss.bs.modal', function (e) {\n        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true\n      })\n    })\n\n    this.backdrop(function () {\n      var transition = $.support.transition && that.$element.hasClass('fade')\n\n      if (!that.$element.parent().length) {\n        that.$element.appendTo(that.$body) // don't move modals dom position\n      }\n\n      that.$element\n        .show()\n        .scrollTop(0)\n\n      that.adjustDialog()\n\n      if (transition) {\n        that.$element[0].offsetWidth // force reflow\n      }\n\n      that.$element.addClass('in')\n\n      that.enforceFocus()\n\n      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n      transition ?\n        that.$dialog // wait for modal to slide in\n          .one('bsTransitionEnd', function () {\n            that.$element.trigger('focus').trigger(e)\n          })\n          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n        that.$element.trigger('focus').trigger(e)\n    })\n  }\n\n  Modal.prototype.hide = function (e) {\n    if (e) e.preventDefault()\n\n    e = $.Event('hide.bs.modal')\n\n    this.$element.trigger(e)\n\n    if (!this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = false\n\n    this.escape()\n    this.resize()\n\n    $(document).off('focusin.bs.modal')\n\n    this.$element\n      .removeClass('in')\n      .off('click.dismiss.bs.modal')\n      .off('mouseup.dismiss.bs.modal')\n\n    this.$dialog.off('mousedown.dismiss.bs.modal')\n\n    $.support.transition && this.$element.hasClass('fade') ?\n      this.$element\n        .one('bsTransitionEnd', $.proxy(this.hideModal, this))\n        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n      this.hideModal()\n  }\n\n  Modal.prototype.enforceFocus = function () {\n    $(document)\n      .off('focusin.bs.modal') // guard against infinite focus loop\n      .on('focusin.bs.modal', $.proxy(function (e) {\n        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {\n          this.$element.trigger('focus')\n        }\n      }, this))\n  }\n\n  Modal.prototype.escape = function () {\n    if (this.isShown && this.options.keyboard) {\n      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {\n        e.which == 27 && this.hide()\n      }, this))\n    } else if (!this.isShown) {\n      this.$element.off('keydown.dismiss.bs.modal')\n    }\n  }\n\n  Modal.prototype.resize = function () {\n    if (this.isShown) {\n      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))\n    } else {\n      $(window).off('resize.bs.modal')\n    }\n  }\n\n  Modal.prototype.hideModal = function () {\n    var that = this\n    this.$element.hide()\n    this.backdrop(function () {\n      that.$body.removeClass('modal-open')\n      that.resetAdjustments()\n      that.resetScrollbar()\n      that.$element.trigger('hidden.bs.modal')\n    })\n  }\n\n  Modal.prototype.removeBackdrop = function () {\n    this.$backdrop && this.$backdrop.remove()\n    this.$backdrop = null\n  }\n\n  Modal.prototype.backdrop = function (callback) {\n    var that = this\n    var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n    if (this.isShown && this.options.backdrop) {\n      var doAnimate = $.support.transition && animate\n\n      this.$backdrop = $(document.createElement('div'))\n        .addClass('modal-backdrop ' + animate)\n        .appendTo(this.$body)\n\n      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {\n        if (this.ignoreBackdropClick) {\n          this.ignoreBackdropClick = false\n          return\n        }\n        if (e.target !== e.currentTarget) return\n        this.options.backdrop == 'static'\n          ? this.$element[0].focus()\n          : this.hide()\n      }, this))\n\n      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n      this.$backdrop.addClass('in')\n\n      if (!callback) return\n\n      doAnimate ?\n        this.$backdrop\n          .one('bsTransitionEnd', callback)\n          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n        callback()\n\n    } else if (!this.isShown && this.$backdrop) {\n      this.$backdrop.removeClass('in')\n\n      var callbackRemove = function () {\n        that.removeBackdrop()\n        callback && callback()\n      }\n      $.support.transition && this.$element.hasClass('fade') ?\n        this.$backdrop\n          .one('bsTransitionEnd', callbackRemove)\n          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n        callbackRemove()\n\n    } else if (callback) {\n      callback()\n    }\n  }\n\n  // these following methods are used to handle overflowing modals\n\n  Modal.prototype.handleUpdate = function () {\n    this.adjustDialog()\n  }\n\n  Modal.prototype.adjustDialog = function () {\n    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight\n\n    this.$element.css({\n      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',\n      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''\n    })\n  }\n\n  Modal.prototype.resetAdjustments = function () {\n    this.$element.css({\n      paddingLeft: '',\n      paddingRight: ''\n    })\n  }\n\n  Modal.prototype.checkScrollbar = function () {\n    var fullWindowWidth = window.innerWidth\n    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8\n      var documentElementRect = document.documentElement.getBoundingClientRect()\n      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)\n    }\n    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth\n    this.scrollbarWidth = this.measureScrollbar()\n  }\n\n  Modal.prototype.setScrollbar = function () {\n    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)\n    this.originalBodyPad = document.body.style.paddingRight || ''\n    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)\n  }\n\n  Modal.prototype.resetScrollbar = function () {\n    this.$body.css('padding-right', this.originalBodyPad)\n  }\n\n  Modal.prototype.measureScrollbar = function () { // thx walsh\n    var scrollDiv = document.createElement('div')\n    scrollDiv.className = 'modal-scrollbar-measure'\n    this.$body.append(scrollDiv)\n    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth\n    this.$body[0].removeChild(scrollDiv)\n    return scrollbarWidth\n  }\n\n\n  // MODAL PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option, _relatedTarget) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.modal')\n      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n      if (typeof option == 'string') data[option](_relatedTarget)\n      else if (options.show) data.show(_relatedTarget)\n    })\n  }\n\n  var old = $.fn.modal\n\n  $.fn.modal             = Plugin\n  $.fn.modal.Constructor = Modal\n\n\n  // MODAL NO CONFLICT\n  // =================\n\n  $.fn.modal.noConflict = function () {\n    $.fn.modal = old\n    return this\n  }\n\n\n  // MODAL DATA-API\n  // ==============\n\n  $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n    var $this   = $(this)\n    var href    = $this.attr('href')\n    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) // strip for ie7\n    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n    if ($this.is('a')) e.preventDefault()\n\n    $target.one('show.bs.modal', function (showEvent) {\n      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown\n      $target.one('hidden.bs.modal', function () {\n        $this.is(':visible') && $this.trigger('focus')\n      })\n    })\n    Plugin.call($target, option, this)\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tooltip.js v3.3.5\n * http://getbootstrap.com/javascript/#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // TOOLTIP PUBLIC CLASS DEFINITION\n  // ===============================\n\n  var Tooltip = function (element, options) {\n    this.type       = null\n    this.options    = null\n    this.enabled    = null\n    this.timeout    = null\n    this.hoverState = null\n    this.$element   = null\n    this.inState    = null\n\n    this.init('tooltip', element, options)\n  }\n\n  Tooltip.VERSION  = '3.3.5'\n\n  Tooltip.TRANSITION_DURATION = 150\n\n  Tooltip.DEFAULTS = {\n    animation: true,\n    placement: 'top',\n    selector: false,\n    template: '<div class=\"tooltip\" role=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>',\n    trigger: 'hover focus',\n    title: '',\n    delay: 0,\n    html: false,\n    container: false,\n    viewport: {\n      selector: 'body',\n      padding: 0\n    }\n  }\n\n  Tooltip.prototype.init = function (type, element, options) {\n    this.enabled   = true\n    this.type      = type\n    this.$element  = $(element)\n    this.options   = this.getOptions(options)\n    this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))\n    this.inState   = { click: false, hover: false, focus: false }\n\n    if (this.$element[0] instanceof document.constructor && !this.options.selector) {\n      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')\n    }\n\n    var triggers = this.options.trigger.split(' ')\n\n    for (var i = triggers.length; i--;) {\n      var trigger = triggers[i]\n\n      if (trigger == 'click') {\n        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n      } else if (trigger != 'manual') {\n        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'\n        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'\n\n        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n      }\n    }\n\n    this.options.selector ?\n      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n      this.fixTitle()\n  }\n\n  Tooltip.prototype.getDefaults = function () {\n    return Tooltip.DEFAULTS\n  }\n\n  Tooltip.prototype.getOptions = function (options) {\n    options = $.extend({}, this.getDefaults(), this.$element.data(), options)\n\n    if (options.delay && typeof options.delay == 'number') {\n      options.delay = {\n        show: options.delay,\n        hide: options.delay\n      }\n    }\n\n    return options\n  }\n\n  Tooltip.prototype.getDelegateOptions = function () {\n    var options  = {}\n    var defaults = this.getDefaults()\n\n    this._options && $.each(this._options, function (key, value) {\n      if (defaults[key] != value) options[key] = value\n    })\n\n    return options\n  }\n\n  Tooltip.prototype.enter = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget).data('bs.' + this.type)\n\n    if (!self) {\n      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n      $(obj.currentTarget).data('bs.' + this.type, self)\n    }\n\n    if (obj instanceof $.Event) {\n      self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true\n    }\n\n    if (self.tip().hasClass('in') || self.hoverState == 'in') {\n      self.hoverState = 'in'\n      return\n    }\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'in'\n\n    if (!self.options.delay || !self.options.delay.show) return self.show()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'in') self.show()\n    }, self.options.delay.show)\n  }\n\n  Tooltip.prototype.isInStateTrue = function () {\n    for (var key in this.inState) {\n      if (this.inState[key]) return true\n    }\n\n    return false\n  }\n\n  Tooltip.prototype.leave = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget).data('bs.' + this.type)\n\n    if (!self) {\n      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n      $(obj.currentTarget).data('bs.' + this.type, self)\n    }\n\n    if (obj instanceof $.Event) {\n      self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false\n    }\n\n    if (self.isInStateTrue()) return\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'out'\n\n    if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'out') self.hide()\n    }, self.options.delay.hide)\n  }\n\n  Tooltip.prototype.show = function () {\n    var e = $.Event('show.bs.' + this.type)\n\n    if (this.hasContent() && this.enabled) {\n      this.$element.trigger(e)\n\n      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])\n      if (e.isDefaultPrevented() || !inDom) return\n      var that = this\n\n      var $tip = this.tip()\n\n      var tipId = this.getUID(this.type)\n\n      this.setContent()\n      $tip.attr('id', tipId)\n      this.$element.attr('aria-describedby', tipId)\n\n      if (this.options.animation) $tip.addClass('fade')\n\n      var placement = typeof this.options.placement == 'function' ?\n        this.options.placement.call(this, $tip[0], this.$element[0]) :\n        this.options.placement\n\n      var autoToken = /\\s?auto?\\s?/i\n      var autoPlace = autoToken.test(placement)\n      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n      $tip\n        .detach()\n        .css({ top: 0, left: 0, display: 'block' })\n        .addClass(placement)\n        .data('bs.' + this.type, this)\n\n      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n      this.$element.trigger('inserted.bs.' + this.type)\n\n      var pos          = this.getPosition()\n      var actualWidth  = $tip[0].offsetWidth\n      var actualHeight = $tip[0].offsetHeight\n\n      if (autoPlace) {\n        var orgPlacement = placement\n        var viewportDim = this.getPosition(this.$viewport)\n\n        placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :\n                    placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :\n                    placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :\n                    placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :\n                    placement\n\n        $tip\n          .removeClass(orgPlacement)\n          .addClass(placement)\n      }\n\n      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n      this.applyPlacement(calculatedOffset, placement)\n\n      var complete = function () {\n        var prevHoverState = that.hoverState\n        that.$element.trigger('shown.bs.' + that.type)\n        that.hoverState = null\n\n        if (prevHoverState == 'out') that.leave(that)\n      }\n\n      $.support.transition && this.$tip.hasClass('fade') ?\n        $tip\n          .one('bsTransitionEnd', complete)\n          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n        complete()\n    }\n  }\n\n  Tooltip.prototype.applyPlacement = function (offset, placement) {\n    var $tip   = this.tip()\n    var width  = $tip[0].offsetWidth\n    var height = $tip[0].offsetHeight\n\n    // manually read margins because getBoundingClientRect includes difference\n    var marginTop = parseInt($tip.css('margin-top'), 10)\n    var marginLeft = parseInt($tip.css('margin-left'), 10)\n\n    // we must check for NaN for ie 8/9\n    if (isNaN(marginTop))  marginTop  = 0\n    if (isNaN(marginLeft)) marginLeft = 0\n\n    offset.top  += marginTop\n    offset.left += marginLeft\n\n    // $.fn.offset doesn't round pixel values\n    // so we use setOffset directly with our own function B-0\n    $.offset.setOffset($tip[0], $.extend({\n      using: function (props) {\n        $tip.css({\n          top: Math.round(props.top),\n          left: Math.round(props.left)\n        })\n      }\n    }, offset), 0)\n\n    $tip.addClass('in')\n\n    // check to see if placing tip in new offset caused the tip to resize itself\n    var actualWidth  = $tip[0].offsetWidth\n    var actualHeight = $tip[0].offsetHeight\n\n    if (placement == 'top' && actualHeight != height) {\n      offset.top = offset.top + height - actualHeight\n    }\n\n    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)\n\n    if (delta.left) offset.left += delta.left\n    else offset.top += delta.top\n\n    var isVertical          = /top|bottom/.test(placement)\n    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight\n    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'\n\n    $tip.offset(offset)\n    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)\n  }\n\n  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {\n    this.arrow()\n      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n      .css(isVertical ? 'top' : 'left', '')\n  }\n\n  Tooltip.prototype.setContent = function () {\n    var $tip  = this.tip()\n    var title = this.getTitle()\n\n    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n    $tip.removeClass('fade in top bottom left right')\n  }\n\n  Tooltip.prototype.hide = function (callback) {\n    var that = this\n    var $tip = $(this.$tip)\n    var e    = $.Event('hide.bs.' + this.type)\n\n    function complete() {\n      if (that.hoverState != 'in') $tip.detach()\n      that.$element\n        .removeAttr('aria-describedby')\n        .trigger('hidden.bs.' + that.type)\n      callback && callback()\n    }\n\n    this.$element.trigger(e)\n\n    if (e.isDefaultPrevented()) return\n\n    $tip.removeClass('in')\n\n    $.support.transition && $tip.hasClass('fade') ?\n      $tip\n        .one('bsTransitionEnd', complete)\n        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n      complete()\n\n    this.hoverState = null\n\n    return this\n  }\n\n  Tooltip.prototype.fixTitle = function () {\n    var $e = this.$element\n    if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {\n      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n    }\n  }\n\n  Tooltip.prototype.hasContent = function () {\n    return this.getTitle()\n  }\n\n  Tooltip.prototype.getPosition = function ($element) {\n    $element   = $element || this.$element\n\n    var el     = $element[0]\n    var isBody = el.tagName == 'BODY'\n\n    var elRect    = el.getBoundingClientRect()\n    if (elRect.width == null) {\n      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })\n    }\n    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()\n    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }\n    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null\n\n    return $.extend({}, elRect, scroll, outerDims, elOffset)\n  }\n\n  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :\n           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }\n\n  }\n\n  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {\n    var delta = { top: 0, left: 0 }\n    if (!this.$viewport) return delta\n\n    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0\n    var viewportDimensions = this.getPosition(this.$viewport)\n\n    if (/right|left/.test(placement)) {\n      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll\n      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight\n      if (topEdgeOffset < viewportDimensions.top) { // top overflow\n        delta.top = viewportDimensions.top - topEdgeOffset\n      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset\n      }\n    } else {\n      var leftEdgeOffset  = pos.left - viewportPadding\n      var rightEdgeOffset = pos.left + viewportPadding + actualWidth\n      if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n        delta.left = viewportDimensions.left - leftEdgeOffset\n      } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset\n      }\n    }\n\n    return delta\n  }\n\n  Tooltip.prototype.getTitle = function () {\n    var title\n    var $e = this.$element\n    var o  = this.options\n\n    title = $e.attr('data-original-title')\n      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)\n\n    return title\n  }\n\n  Tooltip.prototype.getUID = function (prefix) {\n    do prefix += ~~(Math.random() * 1000000)\n    while (document.getElementById(prefix))\n    return prefix\n  }\n\n  Tooltip.prototype.tip = function () {\n    if (!this.$tip) {\n      this.$tip = $(this.options.template)\n      if (this.$tip.length != 1) {\n        throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')\n      }\n    }\n    return this.$tip\n  }\n\n  Tooltip.prototype.arrow = function () {\n    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))\n  }\n\n  Tooltip.prototype.enable = function () {\n    this.enabled = true\n  }\n\n  Tooltip.prototype.disable = function () {\n    this.enabled = false\n  }\n\n  Tooltip.prototype.toggleEnabled = function () {\n    this.enabled = !this.enabled\n  }\n\n  Tooltip.prototype.toggle = function (e) {\n    var self = this\n    if (e) {\n      self = $(e.currentTarget).data('bs.' + this.type)\n      if (!self) {\n        self = new this.constructor(e.currentTarget, this.getDelegateOptions())\n        $(e.currentTarget).data('bs.' + this.type, self)\n      }\n    }\n\n    if (e) {\n      self.inState.click = !self.inState.click\n      if (self.isInStateTrue()) self.enter(self)\n      else self.leave(self)\n    } else {\n      self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n    }\n  }\n\n  Tooltip.prototype.destroy = function () {\n    var that = this\n    clearTimeout(this.timeout)\n    this.hide(function () {\n      that.$element.off('.' + that.type).removeData('bs.' + that.type)\n      if (that.$tip) {\n        that.$tip.detach()\n      }\n      that.$tip = null\n      that.$arrow = null\n      that.$viewport = null\n    })\n  }\n\n\n  // TOOLTIP PLUGIN DEFINITION\n  // =========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.tooltip')\n      var options = typeof option == 'object' && option\n\n      if (!data && /destroy|hide/.test(option)) return\n      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.tooltip\n\n  $.fn.tooltip             = Plugin\n  $.fn.tooltip.Constructor = Tooltip\n\n\n  // TOOLTIP NO CONFLICT\n  // ===================\n\n  $.fn.tooltip.noConflict = function () {\n    $.fn.tooltip = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: popover.js v3.3.5\n * http://getbootstrap.com/javascript/#popovers\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // POPOVER PUBLIC CLASS DEFINITION\n  // ===============================\n\n  var Popover = function (element, options) {\n    this.init('popover', element, options)\n  }\n\n  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n  Popover.VERSION  = '3.3.5'\n\n  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {\n    placement: 'right',\n    trigger: 'click',\n    content: '',\n    template: '<div class=\"popover\" role=\"tooltip\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>'\n  })\n\n\n  // NOTE: POPOVER EXTENDS tooltip.js\n  // ================================\n\n  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n  Popover.prototype.constructor = Popover\n\n  Popover.prototype.getDefaults = function () {\n    return Popover.DEFAULTS\n  }\n\n  Popover.prototype.setContent = function () {\n    var $tip    = this.tip()\n    var title   = this.getTitle()\n    var content = this.getContent()\n\n    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events\n      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'\n    ](content)\n\n    $tip.removeClass('fade top bottom left right in')\n\n    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do\n    // this manually by checking the contents.\n    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n  }\n\n  Popover.prototype.hasContent = function () {\n    return this.getTitle() || this.getContent()\n  }\n\n  Popover.prototype.getContent = function () {\n    var $e = this.$element\n    var o  = this.options\n\n    return $e.attr('data-content')\n      || (typeof o.content == 'function' ?\n            o.content.call($e[0]) :\n            o.content)\n  }\n\n  Popover.prototype.arrow = function () {\n    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))\n  }\n\n\n  // POPOVER PLUGIN DEFINITION\n  // =========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.popover')\n      var options = typeof option == 'object' && option\n\n      if (!data && /destroy|hide/.test(option)) return\n      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.popover\n\n  $.fn.popover             = Plugin\n  $.fn.popover.Constructor = Popover\n\n\n  // POPOVER NO CONFLICT\n  // ===================\n\n  $.fn.popover.noConflict = function () {\n    $.fn.popover = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: scrollspy.js v3.3.5\n * http://getbootstrap.com/javascript/#scrollspy\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // SCROLLSPY CLASS DEFINITION\n  // ==========================\n\n  function ScrollSpy(element, options) {\n    this.$body          = $(document.body)\n    this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)\n    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)\n    this.selector       = (this.options.target || '') + ' .nav li > a'\n    this.offsets        = []\n    this.targets        = []\n    this.activeTarget   = null\n    this.scrollHeight   = 0\n\n    this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))\n    this.refresh()\n    this.process()\n  }\n\n  ScrollSpy.VERSION  = '3.3.5'\n\n  ScrollSpy.DEFAULTS = {\n    offset: 10\n  }\n\n  ScrollSpy.prototype.getScrollHeight = function () {\n    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)\n  }\n\n  ScrollSpy.prototype.refresh = function () {\n    var that          = this\n    var offsetMethod  = 'offset'\n    var offsetBase    = 0\n\n    this.offsets      = []\n    this.targets      = []\n    this.scrollHeight = this.getScrollHeight()\n\n    if (!$.isWindow(this.$scrollElement[0])) {\n      offsetMethod = 'position'\n      offsetBase   = this.$scrollElement.scrollTop()\n    }\n\n    this.$body\n      .find(this.selector)\n      .map(function () {\n        var $el   = $(this)\n        var href  = $el.data('target') || $el.attr('href')\n        var $href = /^#./.test(href) && $(href)\n\n        return ($href\n          && $href.length\n          && $href.is(':visible')\n          && [[$href[offsetMethod]().top + offsetBase, href]]) || null\n      })\n      .sort(function (a, b) { return a[0] - b[0] })\n      .each(function () {\n        that.offsets.push(this[0])\n        that.targets.push(this[1])\n      })\n  }\n\n  ScrollSpy.prototype.process = function () {\n    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset\n    var scrollHeight = this.getScrollHeight()\n    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()\n    var offsets      = this.offsets\n    var targets      = this.targets\n    var activeTarget = this.activeTarget\n    var i\n\n    if (this.scrollHeight != scrollHeight) {\n      this.refresh()\n    }\n\n    if (scrollTop >= maxScroll) {\n      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)\n    }\n\n    if (activeTarget && scrollTop < offsets[0]) {\n      this.activeTarget = null\n      return this.clear()\n    }\n\n    for (i = offsets.length; i--;) {\n      activeTarget != targets[i]\n        && scrollTop >= offsets[i]\n        && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])\n        && this.activate(targets[i])\n    }\n  }\n\n  ScrollSpy.prototype.activate = function (target) {\n    this.activeTarget = target\n\n    this.clear()\n\n    var selector = this.selector +\n      '[data-target=\"' + target + '\"],' +\n      this.selector + '[href=\"' + target + '\"]'\n\n    var active = $(selector)\n      .parents('li')\n      .addClass('active')\n\n    if (active.parent('.dropdown-menu').length) {\n      active = active\n        .closest('li.dropdown')\n        .addClass('active')\n    }\n\n    active.trigger('activate.bs.scrollspy')\n  }\n\n  ScrollSpy.prototype.clear = function () {\n    $(this.selector)\n      .parentsUntil(this.options.target, '.active')\n      .removeClass('active')\n  }\n\n\n  // SCROLLSPY PLUGIN DEFINITION\n  // ===========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.scrollspy')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.scrollspy\n\n  $.fn.scrollspy             = Plugin\n  $.fn.scrollspy.Constructor = ScrollSpy\n\n\n  // SCROLLSPY NO CONFLICT\n  // =====================\n\n  $.fn.scrollspy.noConflict = function () {\n    $.fn.scrollspy = old\n    return this\n  }\n\n\n  // SCROLLSPY DATA-API\n  // ==================\n\n  $(window).on('load.bs.scrollspy.data-api', function () {\n    $('[data-spy=\"scroll\"]').each(function () {\n      var $spy = $(this)\n      Plugin.call($spy, $spy.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tab.js v3.3.5\n * http://getbootstrap.com/javascript/#tabs\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // TAB CLASS DEFINITION\n  // ====================\n\n  var Tab = function (element) {\n    // jscs:disable requireDollarBeforejQueryAssignment\n    this.element = $(element)\n    // jscs:enable requireDollarBeforejQueryAssignment\n  }\n\n  Tab.VERSION = '3.3.5'\n\n  Tab.TRANSITION_DURATION = 150\n\n  Tab.prototype.show = function () {\n    var $this    = this.element\n    var $ul      = $this.closest('ul:not(.dropdown-menu)')\n    var selector = $this.data('target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    if ($this.parent('li').hasClass('active')) return\n\n    var $previous = $ul.find('.active:last a')\n    var hideEvent = $.Event('hide.bs.tab', {\n      relatedTarget: $this[0]\n    })\n    var showEvent = $.Event('show.bs.tab', {\n      relatedTarget: $previous[0]\n    })\n\n    $previous.trigger(hideEvent)\n    $this.trigger(showEvent)\n\n    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return\n\n    var $target = $(selector)\n\n    this.activate($this.closest('li'), $ul)\n    this.activate($target, $target.parent(), function () {\n      $previous.trigger({\n        type: 'hidden.bs.tab',\n        relatedTarget: $this[0]\n      })\n      $this.trigger({\n        type: 'shown.bs.tab',\n        relatedTarget: $previous[0]\n      })\n    })\n  }\n\n  Tab.prototype.activate = function (element, container, callback) {\n    var $active    = container.find('> .active')\n    var transition = callback\n      && $.support.transition\n      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)\n\n    function next() {\n      $active\n        .removeClass('active')\n        .find('> .dropdown-menu > .active')\n          .removeClass('active')\n        .end()\n        .find('[data-toggle=\"tab\"]')\n          .attr('aria-expanded', false)\n\n      element\n        .addClass('active')\n        .find('[data-toggle=\"tab\"]')\n          .attr('aria-expanded', true)\n\n      if (transition) {\n        element[0].offsetWidth // reflow for transition\n        element.addClass('in')\n      } else {\n        element.removeClass('fade')\n      }\n\n      if (element.parent('.dropdown-menu').length) {\n        element\n          .closest('li.dropdown')\n            .addClass('active')\n          .end()\n          .find('[data-toggle=\"tab\"]')\n            .attr('aria-expanded', true)\n      }\n\n      callback && callback()\n    }\n\n    $active.length && transition ?\n      $active\n        .one('bsTransitionEnd', next)\n        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :\n      next()\n\n    $active.removeClass('in')\n  }\n\n\n  // TAB PLUGIN DEFINITION\n  // =====================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.tab')\n\n      if (!data) $this.data('bs.tab', (data = new Tab(this)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.tab\n\n  $.fn.tab             = Plugin\n  $.fn.tab.Constructor = Tab\n\n\n  // TAB NO CONFLICT\n  // ===============\n\n  $.fn.tab.noConflict = function () {\n    $.fn.tab = old\n    return this\n  }\n\n\n  // TAB DATA-API\n  // ============\n\n  var clickHandler = function (e) {\n    e.preventDefault()\n    Plugin.call($(this), 'show')\n  }\n\n  $(document)\n    .on('click.bs.tab.data-api', '[data-toggle=\"tab\"]', clickHandler)\n    .on('click.bs.tab.data-api', '[data-toggle=\"pill\"]', clickHandler)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: affix.js v3.3.5\n * http://getbootstrap.com/javascript/#affix\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // AFFIX CLASS DEFINITION\n  // ======================\n\n  var Affix = function (element, options) {\n    this.options = $.extend({}, Affix.DEFAULTS, options)\n\n    this.$target = $(this.options.target)\n      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))\n      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))\n\n    this.$element     = $(element)\n    this.affixed      = null\n    this.unpin        = null\n    this.pinnedOffset = null\n\n    this.checkPosition()\n  }\n\n  Affix.VERSION  = '3.3.5'\n\n  Affix.RESET    = 'affix affix-top affix-bottom'\n\n  Affix.DEFAULTS = {\n    offset: 0,\n    target: window\n  }\n\n  Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {\n    var scrollTop    = this.$target.scrollTop()\n    var position     = this.$element.offset()\n    var targetHeight = this.$target.height()\n\n    if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false\n\n    if (this.affixed == 'bottom') {\n      if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'\n      return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'\n    }\n\n    var initializing   = this.affixed == null\n    var colliderTop    = initializing ? scrollTop : position.top\n    var colliderHeight = initializing ? targetHeight : height\n\n    if (offsetTop != null && scrollTop <= offsetTop) return 'top'\n    if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'\n\n    return false\n  }\n\n  Affix.prototype.getPinnedOffset = function () {\n    if (this.pinnedOffset) return this.pinnedOffset\n    this.$element.removeClass(Affix.RESET).addClass('affix')\n    var scrollTop = this.$target.scrollTop()\n    var position  = this.$element.offset()\n    return (this.pinnedOffset = position.top - scrollTop)\n  }\n\n  Affix.prototype.checkPositionWithEventLoop = function () {\n    setTimeout($.proxy(this.checkPosition, this), 1)\n  }\n\n  Affix.prototype.checkPosition = function () {\n    if (!this.$element.is(':visible')) return\n\n    var height       = this.$element.height()\n    var offset       = this.options.offset\n    var offsetTop    = offset.top\n    var offsetBottom = offset.bottom\n    var scrollHeight = Math.max($(document).height(), $(document.body).height())\n\n    if (typeof offset != 'object')         offsetBottom = offsetTop = offset\n    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)\n    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)\n\n    var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)\n\n    if (this.affixed != affix) {\n      if (this.unpin != null) this.$element.css('top', '')\n\n      var affixType = 'affix' + (affix ? '-' + affix : '')\n      var e         = $.Event(affixType + '.bs.affix')\n\n      this.$element.trigger(e)\n\n      if (e.isDefaultPrevented()) return\n\n      this.affixed = affix\n      this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null\n\n      this.$element\n        .removeClass(Affix.RESET)\n        .addClass(affixType)\n        .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')\n    }\n\n    if (affix == 'bottom') {\n      this.$element.offset({\n        top: scrollHeight - height - offsetBottom\n      })\n    }\n  }\n\n\n  // AFFIX PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.affix')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.affix\n\n  $.fn.affix             = Plugin\n  $.fn.affix.Constructor = Affix\n\n\n  // AFFIX NO CONFLICT\n  // =================\n\n  $.fn.affix.noConflict = function () {\n    $.fn.affix = old\n    return this\n  }\n\n\n  // AFFIX DATA-API\n  // ==============\n\n  $(window).on('load', function () {\n    $('[data-spy=\"affix\"]').each(function () {\n      var $spy = $(this)\n      var data = $spy.data()\n\n      data.offset = data.offset || {}\n\n      if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom\n      if (data.offsetTop    != null) data.offset.top    = data.offsetTop\n\n      Plugin.call($spy, data)\n    })\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "static/assets/js/detect.js",
    "content": "/**\n * jQuery.browser.mobile (http://detectmobilebrowser.com/)\n *\n * jQuery.browser.mobile will be true if the browser is a mobile device\n *\n **/\n(function(a){(jQuery.browser=jQuery.browser||{}).mobile=/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(a.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera);"
  },
  {
    "path": "static/assets/js/fastclick.js",
    "content": "/**\n * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs.\n *\n * @version 0.6.11\n * @codingstandard ftlabs-jsv2\n * @copyright The Financial Times Limited [All Rights Reserved]\n * @license MIT License (see LICENSE.txt)\n */\n\n/*jslint browser:true, node:true*/\n/*global define, Event, Node*/\n\n\n/**\n * Instantiate fast-clicking listeners on the specificed layer.\n *\n * @constructor\n * @param {Element} layer The layer to listen on\n */\nfunction FastClick(layer) {\n\t'use strict';\n\tvar oldOnClick, self = this;\n\n\n\t/**\n\t * Whether a click is currently being tracked.\n\t *\n\t * @type boolean\n\t */\n\tthis.trackingClick = false;\n\n\n\t/**\n\t * Timestamp for when when click tracking started.\n\t *\n\t * @type number\n\t */\n\tthis.trackingClickStart = 0;\n\n\n\t/**\n\t * The element being tracked for a click.\n\t *\n\t * @type EventTarget\n\t */\n\tthis.targetElement = null;\n\n\n\t/**\n\t * X-coordinate of touch start event.\n\t *\n\t * @type number\n\t */\n\tthis.touchStartX = 0;\n\n\n\t/**\n\t * Y-coordinate of touch start event.\n\t *\n\t * @type number\n\t */\n\tthis.touchStartY = 0;\n\n\n\t/**\n\t * ID of the last touch, retrieved from Touch.identifier.\n\t *\n\t * @type number\n\t */\n\tthis.lastTouchIdentifier = 0;\n\n\n\t/**\n\t * Touchmove boundary, beyond which a click will be cancelled.\n\t *\n\t * @type number\n\t */\n\tthis.touchBoundary = 10;\n\n\n\t/**\n\t * The FastClick layer.\n\t *\n\t * @type Element\n\t */\n\tthis.layer = layer;\n\n\tif (!layer || !layer.nodeType) {\n\t\tthrow new TypeError('Layer must be a document node');\n\t}\n\n\t/** @type function() */\n\tthis.onClick = function() { return FastClick.prototype.onClick.apply(self, arguments); };\n\n\t/** @type function() */\n\tthis.onMouse = function() { return FastClick.prototype.onMouse.apply(self, arguments); };\n\n\t/** @type function() */\n\tthis.onTouchStart = function() { return FastClick.prototype.onTouchStart.apply(self, arguments); };\n\n\t/** @type function() */\n\tthis.onTouchMove = function() { return FastClick.prototype.onTouchMove.apply(self, arguments); };\n\n\t/** @type function() */\n\tthis.onTouchEnd = function() { return FastClick.prototype.onTouchEnd.apply(self, arguments); };\n\n\t/** @type function() */\n\tthis.onTouchCancel = function() { return FastClick.prototype.onTouchCancel.apply(self, arguments); };\n\n\tif (FastClick.notNeeded(layer)) {\n\t\treturn;\n\t}\n\n\t// Set up event handlers as required\n\tif (this.deviceIsAndroid) {\n\t\tlayer.addEventListener('mouseover', this.onMouse, true);\n\t\tlayer.addEventListener('mousedown', this.onMouse, true);\n\t\tlayer.addEventListener('mouseup', this.onMouse, true);\n\t}\n\n\tlayer.addEventListener('click', this.onClick, true);\n\tlayer.addEventListener('touchstart', this.onTouchStart, false);\n\tlayer.addEventListener('touchmove', this.onTouchMove, false);\n\tlayer.addEventListener('touchend', this.onTouchEnd, false);\n\tlayer.addEventListener('touchcancel', this.onTouchCancel, false);\n\n\t// Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)\n\t// which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick\n\t// layer when they are cancelled.\n\tif (!Event.prototype.stopImmediatePropagation) {\n\t\tlayer.removeEventListener = function(type, callback, capture) {\n\t\t\tvar rmv = Node.prototype.removeEventListener;\n\t\t\tif (type === 'click') {\n\t\t\t\trmv.call(layer, type, callback.hijacked || callback, capture);\n\t\t\t} else {\n\t\t\t\trmv.call(layer, type, callback, capture);\n\t\t\t}\n\t\t};\n\n\t\tlayer.addEventListener = function(type, callback, capture) {\n\t\t\tvar adv = Node.prototype.addEventListener;\n\t\t\tif (type === 'click') {\n\t\t\t\tadv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {\n\t\t\t\t\tif (!event.propagationStopped) {\n\t\t\t\t\t\tcallback(event);\n\t\t\t\t\t}\n\t\t\t\t}), capture);\n\t\t\t} else {\n\t\t\t\tadv.call(layer, type, callback, capture);\n\t\t\t}\n\t\t};\n\t}\n\n\t// If a handler is already declared in the element's onclick attribute, it will be fired before\n\t// FastClick's onClick handler. Fix this by pulling out the user-defined handler function and\n\t// adding it as listener.\n\tif (typeof layer.onclick === 'function') {\n\n\t\t// Android browser on at least 3.2 requires a new reference to the function in layer.onclick\n\t\t// - the old one won't work if passed to addEventListener directly.\n\t\toldOnClick = layer.onclick;\n\t\tlayer.addEventListener('click', function(event) {\n\t\t\toldOnClick(event);\n\t\t}, false);\n\t\tlayer.onclick = null;\n\t}\n}\n\n\n/**\n * Android requires exceptions.\n *\n * @type boolean\n */\nFastClick.prototype.deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0;\n\n\n/**\n * iOS requires exceptions.\n *\n * @type boolean\n */\nFastClick.prototype.deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent);\n\n\n/**\n * iOS 4 requires an exception for select elements.\n *\n * @type boolean\n */\nFastClick.prototype.deviceIsIOS4 = FastClick.prototype.deviceIsIOS && (/OS 4_\\d(_\\d)?/).test(navigator.userAgent);\n\n\n/**\n * iOS 6.0(+?) requires the target element to be manually derived\n *\n * @type boolean\n */\nFastClick.prototype.deviceIsIOSWithBadTarget = FastClick.prototype.deviceIsIOS && (/OS ([6-9]|\\d{2})_\\d/).test(navigator.userAgent);\n\n\n/**\n * Determine whether a given element requires a native click.\n *\n * @param {EventTarget|Element} target Target DOM element\n * @returns {boolean} Returns true if the element needs a native click\n */\nFastClick.prototype.needsClick = function(target) {\n\t'use strict';\n\tswitch (target.nodeName.toLowerCase()) {\n\n\t// Don't send a synthetic click to disabled inputs (issue #62)\n\tcase 'button':\n\tcase 'select':\n\tcase 'textarea':\n\t\tif (target.disabled) {\n\t\t\treturn true;\n\t\t}\n\n\t\tbreak;\n\tcase 'input':\n\n\t\t// File inputs need real clicks on iOS 6 due to a browser bug (issue #68)\n\t\tif ((this.deviceIsIOS && target.type === 'file') || target.disabled) {\n\t\t\treturn true;\n\t\t}\n\n\t\tbreak;\n\tcase 'label':\n\tcase 'video':\n\t\treturn true;\n\t}\n\n\treturn (/\\bneedsclick\\b/).test(target.className);\n};\n\n\n/**\n * Determine whether a given element requires a call to focus to simulate click into element.\n *\n * @param {EventTarget|Element} target Target DOM element\n * @returns {boolean} Returns true if the element requires a call to focus to simulate native click.\n */\nFastClick.prototype.needsFocus = function(target) {\n\t'use strict';\n\tswitch (target.nodeName.toLowerCase()) {\n\tcase 'textarea':\n\t\treturn true;\n\tcase 'select':\n\t\treturn !this.deviceIsAndroid;\n\tcase 'input':\n\t\tswitch (target.type) {\n\t\tcase 'button':\n\t\tcase 'checkbox':\n\t\tcase 'file':\n\t\tcase 'image':\n\t\tcase 'radio':\n\t\tcase 'submit':\n\t\t\treturn false;\n\t\t}\n\n\t\t// No point in attempting to focus disabled inputs\n\t\treturn !target.disabled && !target.readOnly;\n\tdefault:\n\t\treturn (/\\bneedsfocus\\b/).test(target.className);\n\t}\n};\n\n\n/**\n * Send a click event to the specified element.\n *\n * @param {EventTarget|Element} targetElement\n * @param {Event} event\n */\nFastClick.prototype.sendClick = function(targetElement, event) {\n\t'use strict';\n\tvar clickEvent, touch;\n\n\t// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)\n\tif (document.activeElement && document.activeElement !== targetElement) {\n\t\tdocument.activeElement.blur();\n\t}\n\n\ttouch = event.changedTouches[0];\n\n\t// Synthesise a click event, with an extra attribute so it can be tracked\n\tclickEvent = document.createEvent('MouseEvents');\n\tclickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);\n\tclickEvent.forwardedTouchEvent = true;\n\ttargetElement.dispatchEvent(clickEvent);\n};\n\nFastClick.prototype.determineEventType = function(targetElement) {\n\t'use strict';\n\n\t//Issue #159: Android Chrome Select Box does not open with a synthetic click event\n\tif (this.deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') {\n\t\treturn 'mousedown';\n\t}\n\n\treturn 'click';\n};\n\n\n/**\n * @param {EventTarget|Element} targetElement\n */\nFastClick.prototype.focus = function(targetElement) {\n\t'use strict';\n\tvar length;\n\n\t// Issue #160: on iOS 7, some input elements (e.g. date datetime) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.\n\tif (this.deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time') {\n\t\tlength = targetElement.value.length;\n\t\ttargetElement.setSelectionRange(length, length);\n\t} else {\n\t\ttargetElement.focus();\n\t}\n};\n\n\n/**\n * Check whether the given target element is a child of a scrollable layer and if so, set a flag on it.\n *\n * @param {EventTarget|Element} targetElement\n */\nFastClick.prototype.updateScrollParent = function(targetElement) {\n\t'use strict';\n\tvar scrollParent, parentElement;\n\n\tscrollParent = targetElement.fastClickScrollParent;\n\n\t// Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the\n\t// target element was moved to another parent.\n\tif (!scrollParent || !scrollParent.contains(targetElement)) {\n\t\tparentElement = targetElement;\n\t\tdo {\n\t\t\tif (parentElement.scrollHeight > parentElement.offsetHeight) {\n\t\t\t\tscrollParent = parentElement;\n\t\t\t\ttargetElement.fastClickScrollParent = parentElement;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tparentElement = parentElement.parentElement;\n\t\t} while (parentElement);\n\t}\n\n\t// Always update the scroll top tracker if possible.\n\tif (scrollParent) {\n\t\tscrollParent.fastClickLastScrollTop = scrollParent.scrollTop;\n\t}\n};\n\n\n/**\n * @param {EventTarget} targetElement\n * @returns {Element|EventTarget}\n */\nFastClick.prototype.getTargetElementFromEventTarget = function(eventTarget) {\n\t'use strict';\n\n\t// On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node.\n\tif (eventTarget.nodeType === Node.TEXT_NODE) {\n\t\treturn eventTarget.parentNode;\n\t}\n\n\treturn eventTarget;\n};\n\n\n/**\n * On touch start, record the position and scroll offset.\n *\n * @param {Event} event\n * @returns {boolean}\n */\nFastClick.prototype.onTouchStart = function(event) {\n\t'use strict';\n\tvar targetElement, touch, selection;\n\n\t// Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111).\n\tif (event.targetTouches.length > 1) {\n\t\treturn true;\n\t}\n\n\ttargetElement = this.getTargetElementFromEventTarget(event.target);\n\ttouch = event.targetTouches[0];\n\n\tif (this.deviceIsIOS) {\n\n\t\t// Only trusted events will deselect text on iOS (issue #49)\n\t\tselection = window.getSelection();\n\t\tif (selection.rangeCount && !selection.isCollapsed) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (!this.deviceIsIOS4) {\n\n\t\t\t// Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23):\n\t\t\t// when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched\n\t\t\t// with the same identifier as the touch event that previously triggered the click that triggered the alert.\n\t\t\t// Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an\n\t\t\t// immediately preceeding touch event (issue #52), so this fix is unavailable on that platform.\n\t\t\tif (touch.identifier === this.lastTouchIdentifier) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis.lastTouchIdentifier = touch.identifier;\n\n\t\t\t// If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and:\n\t\t\t// 1) the user does a fling scroll on the scrollable layer\n\t\t\t// 2) the user stops the fling scroll with another tap\n\t\t\t// then the event.target of the last 'touchend' event will be the element that was under the user's finger\n\t\t\t// when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check\n\t\t\t// is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42).\n\t\t\tthis.updateScrollParent(targetElement);\n\t\t}\n\t}\n\n\tthis.trackingClick = true;\n\tthis.trackingClickStart = event.timeStamp;\n\tthis.targetElement = targetElement;\n\n\tthis.touchStartX = touch.pageX;\n\tthis.touchStartY = touch.pageY;\n\n\t// Prevent phantom clicks on fast double-tap (issue #36)\n\tif ((event.timeStamp - this.lastClickTime) < 200) {\n\t\tevent.preventDefault();\n\t}\n\n\treturn true;\n};\n\n\n/**\n * Based on a touchmove event object, check whether the touch has moved past a boundary since it started.\n *\n * @param {Event} event\n * @returns {boolean}\n */\nFastClick.prototype.touchHasMoved = function(event) {\n\t'use strict';\n\tvar touch = event.changedTouches[0], boundary = this.touchBoundary;\n\n\tif (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n\n/**\n * Update the last position.\n *\n * @param {Event} event\n * @returns {boolean}\n */\nFastClick.prototype.onTouchMove = function(event) {\n\t'use strict';\n\tif (!this.trackingClick) {\n\t\treturn true;\n\t}\n\n\t// If the touch has moved, cancel the click tracking\n\tif (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {\n\t\tthis.trackingClick = false;\n\t\tthis.targetElement = null;\n\t}\n\n\treturn true;\n};\n\n\n/**\n * Attempt to find the labelled control for the given label element.\n *\n * @param {EventTarget|HTMLLabelElement} labelElement\n * @returns {Element|null}\n */\nFastClick.prototype.findControl = function(labelElement) {\n\t'use strict';\n\n\t// Fast path for newer browsers supporting the HTML5 control attribute\n\tif (labelElement.control !== undefined) {\n\t\treturn labelElement.control;\n\t}\n\n\t// All browsers under test that support touch events also support the HTML5 htmlFor attribute\n\tif (labelElement.htmlFor) {\n\t\treturn document.getElementById(labelElement.htmlFor);\n\t}\n\n\t// If no for attribute exists, attempt to retrieve the first labellable descendant element\n\t// the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label\n\treturn labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea');\n};\n\n\n/**\n * On touch end, determine whether to send a click event at once.\n *\n * @param {Event} event\n * @returns {boolean}\n */\nFastClick.prototype.onTouchEnd = function(event) {\n\t'use strict';\n\tvar forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;\n\n\tif (!this.trackingClick) {\n\t\treturn true;\n\t}\n\n\t// Prevent phantom clicks on fast double-tap (issue #36)\n\tif ((event.timeStamp - this.lastClickTime) < 200) {\n\t\tthis.cancelNextClick = true;\n\t\treturn true;\n\t}\n\n\t// Reset to prevent wrong click cancel on input (issue #156).\n\tthis.cancelNextClick = false;\n\n\tthis.lastClickTime = event.timeStamp;\n\n\ttrackingClickStart = this.trackingClickStart;\n\tthis.trackingClick = false;\n\tthis.trackingClickStart = 0;\n\n\t// On some iOS devices, the targetElement supplied with the event is invalid if the layer\n\t// is performing a transition or scroll, and has to be re-detected manually. Note that\n\t// for this to function correctly, it must be called *after* the event target is checked!\n\t// See issue #57; also filed as rdar://13048589 .\n\tif (this.deviceIsIOSWithBadTarget) {\n\t\ttouch = event.changedTouches[0];\n\n\t\t// In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null\n\t\ttargetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;\n\t\ttargetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;\n\t}\n\n\ttargetTagName = targetElement.tagName.toLowerCase();\n\tif (targetTagName === 'label') {\n\t\tforElement = this.findControl(targetElement);\n\t\tif (forElement) {\n\t\t\tthis.focus(targetElement);\n\t\t\tif (this.deviceIsAndroid) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\ttargetElement = forElement;\n\t\t}\n\t} else if (this.needsFocus(targetElement)) {\n\n\t\t// Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through.\n\t\t// Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37).\n\t\tif ((event.timeStamp - trackingClickStart) > 100 || (this.deviceIsIOS && window.top !== window && targetTagName === 'input')) {\n\t\t\tthis.targetElement = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.focus(targetElement);\n\n\t\t// Select elements need the event to go through on iOS 4, otherwise the selector menu won't open.\n\t\tif (!this.deviceIsIOS4 || targetTagName !== 'select') {\n\t\t\tthis.targetElement = null;\n\t\t\tevent.preventDefault();\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tif (this.deviceIsIOS && !this.deviceIsIOS4) {\n\n\t\t// Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled\n\t\t// and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42).\n\t\tscrollParent = targetElement.fastClickScrollParent;\n\t\tif (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Prevent the actual click from going though - unless the target node is marked as requiring\n\t// real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted.\n\tif (!this.needsClick(targetElement)) {\n\t\tevent.preventDefault();\n\t\tthis.sendClick(targetElement, event);\n\t}\n\n\treturn false;\n};\n\n\n/**\n * On touch cancel, stop tracking the click.\n *\n * @returns {void}\n */\nFastClick.prototype.onTouchCancel = function() {\n\t'use strict';\n\tthis.trackingClick = false;\n\tthis.targetElement = null;\n};\n\n\n/**\n * Determine mouse events which should be permitted.\n *\n * @param {Event} event\n * @returns {boolean}\n */\nFastClick.prototype.onMouse = function(event) {\n\t'use strict';\n\n\t// If a target element was never set (because a touch event was never fired) allow the event\n\tif (!this.targetElement) {\n\t\treturn true;\n\t}\n\n\tif (event.forwardedTouchEvent) {\n\t\treturn true;\n\t}\n\n\t// Programmatically generated events targeting a specific element should be permitted\n\tif (!event.cancelable) {\n\t\treturn true;\n\t}\n\n\t// Derive and check the target element to see whether the mouse event needs to be permitted;\n\t// unless explicitly enabled, prevent non-touch click events from triggering actions,\n\t// to prevent ghost/doubleclicks.\n\tif (!this.needsClick(this.targetElement) || this.cancelNextClick) {\n\n\t\t// Prevent any user-added listeners declared on FastClick element from being fired.\n\t\tif (event.stopImmediatePropagation) {\n\t\t\tevent.stopImmediatePropagation();\n\t\t} else {\n\n\t\t\t// Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)\n\t\t\tevent.propagationStopped = true;\n\t\t}\n\n\t\t// Cancel the event\n\t\tevent.stopPropagation();\n\t\tevent.preventDefault();\n\n\t\treturn false;\n\t}\n\n\t// If the mouse event is permitted, return true for the action to go through.\n\treturn true;\n};\n\n\n/**\n * On actual clicks, determine whether this is a touch-generated click, a click action occurring\n * naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or\n * an actual click which should be permitted.\n *\n * @param {Event} event\n * @returns {boolean}\n */\nFastClick.prototype.onClick = function(event) {\n\t'use strict';\n\tvar permitted;\n\n\t// It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early.\n\tif (this.trackingClick) {\n\t\tthis.targetElement = null;\n\t\tthis.trackingClick = false;\n\t\treturn true;\n\t}\n\n\t// Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target.\n\tif (event.target.type === 'submit' && event.detail === 0) {\n\t\treturn true;\n\t}\n\n\tpermitted = this.onMouse(event);\n\n\t// Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through.\n\tif (!permitted) {\n\t\tthis.targetElement = null;\n\t}\n\n\t// If clicks are permitted, return true for the action to go through.\n\treturn permitted;\n};\n\n\n/**\n * Remove all FastClick's event listeners.\n *\n * @returns {void}\n */\nFastClick.prototype.destroy = function() {\n\t'use strict';\n\tvar layer = this.layer;\n\n\tif (this.deviceIsAndroid) {\n\t\tlayer.removeEventListener('mouseover', this.onMouse, true);\n\t\tlayer.removeEventListener('mousedown', this.onMouse, true);\n\t\tlayer.removeEventListener('mouseup', this.onMouse, true);\n\t}\n\n\tlayer.removeEventListener('click', this.onClick, true);\n\tlayer.removeEventListener('touchstart', this.onTouchStart, false);\n\tlayer.removeEventListener('touchmove', this.onTouchMove, false);\n\tlayer.removeEventListener('touchend', this.onTouchEnd, false);\n\tlayer.removeEventListener('touchcancel', this.onTouchCancel, false);\n};\n\n\n/**\n * Check whether FastClick is needed.\n *\n * @param {Element} layer The layer to listen on\n */\nFastClick.notNeeded = function(layer) {\n\t'use strict';\n\tvar metaViewport;\n\tvar chromeVersion;\n\n\t// Devices that don't support touch don't need FastClick\n\tif (typeof window.ontouchstart === 'undefined') {\n\t\treturn true;\n\t}\n\n\t// Chrome version - zero for other browsers\n\tchromeVersion = +(/Chrome\\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];\n\n\tif (chromeVersion) {\n\n\t\tif (FastClick.prototype.deviceIsAndroid) {\n\t\t\tmetaViewport = document.querySelector('meta[name=viewport]');\n\t\t\t\n\t\t\tif (metaViewport) {\n\t\t\t\t// Chrome on Android with user-scalable=\"no\" doesn't need FastClick (issue #89)\n\t\t\t\tif (metaViewport.content.indexOf('user-scalable=no') !== -1) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// Chrome 32 and above with width=device-width or less don't need FastClick\n\t\t\t\tif (chromeVersion > 31 && window.innerWidth <= window.screen.width) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Chrome desktop doesn't need FastClick (issue #15)\n\t\t} else {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// IE10 with -ms-touch-action: none, which disables double-tap-to-zoom (issue #97)\n\tif (layer.style.msTouchAction === 'none') {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n\n/**\n * Factory method for creating a FastClick object\n *\n * @param {Element} layer The layer to listen on\n */\nFastClick.attach = function(layer) {\n\t'use strict';\n\treturn new FastClick(layer);\n};\n\n\nif (typeof define !== 'undefined' && define.amd) {\n\n\t// AMD. Register as an anonymous module.\n\tdefine(function() {\n\t\t'use strict';\n\t\treturn FastClick;\n\t});\n} else if (typeof module !== 'undefined' && module.exports) {\n\tmodule.exports = FastClick.attach;\n\tmodule.exports.FastClick = FastClick;\n} else {\n\twindow.FastClick = FastClick;\n}\n"
  },
  {
    "path": "static/assets/js/jquery.app.js",
    "content": "/**\n* Theme: Ubold Admin Template\n* Author: Coderthemes\n* Module/App: Main Js\n*/\n\n\n!function($) {\n    \"use strict\";\n\n    var Sidemenu = function() {\n        this.$body = $(\"body\"),\n        this.$openLeftBtn = $(\".open-left\"),\n        this.$menuItem = $(\"#sidebar-menu a\")\n    };\n    Sidemenu.prototype.openLeftBar = function() {\n      $(\"#wrapper\").toggleClass(\"enlarged\");\n      $(\"#wrapper\").addClass(\"forced\");\n\n      if($(\"#wrapper\").hasClass(\"enlarged\") && $(\"body\").hasClass(\"fixed-left\")) {\n        $(\"body\").removeClass(\"fixed-left\").addClass(\"fixed-left-void\");\n      } else if(!$(\"#wrapper\").hasClass(\"enlarged\") && $(\"body\").hasClass(\"fixed-left-void\")) {\n        $(\"body\").removeClass(\"fixed-left-void\").addClass(\"fixed-left\");\n      }\n      \n      if($(\"#wrapper\").hasClass(\"enlarged\")) {\n        $(\".left ul\").removeAttr(\"style\");\n      } else {\n        $(\".subdrop\").siblings(\"ul:first\").show();\n      }\n      \n      toggle_slimscroll(\".slimscrollleft\");\n      $(\"body\").trigger(\"resize\");\n    },\n    //menu item click\n    Sidemenu.prototype.menuItemClick = function(e) {\n       if(!$(\"#wrapper\").hasClass(\"enlarged\")){\n        if($(this).parent().hasClass(\"has_sub\")) {\n          e.preventDefault();\n        }   \n        if(!$(this).hasClass(\"subdrop\")) {\n          // hide any open menus and remove all other classes\n          $(\"ul\",$(this).parents(\"ul:first\")).slideUp(350);\n          $(\"a\",$(this).parents(\"ul:first\")).removeClass(\"subdrop\");\n          $(\"#sidebar-menu .pull-right i\").removeClass(\"md-remove\").addClass(\"md-add\");\n          \n          // open our new menu and add the open class\n          $(this).next(\"ul\").slideDown(350);\n          $(this).addClass(\"subdrop\");\n          $(\".pull-right i\",$(this).parents(\".has_sub:last\")).removeClass(\"md-add\").addClass(\"md-remove\");\n          $(\".pull-right i\",$(this).siblings(\"ul\")).removeClass(\"md-remove\").addClass(\"md-add\");\n        }else if($(this).hasClass(\"subdrop\")) {\n          $(this).removeClass(\"subdrop\");\n          $(this).next(\"ul\").slideUp(350);\n          $(\".pull-right i\",$(this).parent()).removeClass(\"md-remove\").addClass(\"md-add\");\n        }\n      } \n    },\n\n    //init sidemenu\n    Sidemenu.prototype.init = function() {\n      var $this  = this;\n      //bind on click\n      $(\".open-left\").click(function(e) {\n        e.stopPropagation();\n        $this.openLeftBar();\n      });\n\n      // LEFT SIDE MAIN NAVIGATION\n      $this.$menuItem.on('click', $this.menuItemClick);\n\n      // NAVIGATION HIGHLIGHT & OPEN PARENT\n      $(\"#sidebar-menu ul li.has_sub a.active\").parents(\"li:last\").children(\"a:first\").addClass(\"active\").trigger(\"click\");\n    },\n\n    //init Sidemenu\n    $.Sidemenu = new Sidemenu, $.Sidemenu.Constructor = Sidemenu\n    \n}(window.jQuery),\n\n\nfunction($) {\n    \"use strict\";\n\n    var FullScreen = function() {\n        this.$body = $(\"body\"),\n        this.$fullscreenBtn = $(\"#btn-fullscreen\")\n    };\n\n    //turn on full screen\n    // Thanks to http://davidwalsh.name/fullscreen\n    FullScreen.prototype.launchFullscreen  = function(element) {\n      if(element.requestFullscreen) {\n        element.requestFullscreen();\n      } else if(element.mozRequestFullScreen) {\n        element.mozRequestFullScreen();\n      } else if(element.webkitRequestFullscreen) {\n        element.webkitRequestFullscreen();\n      } else if(element.msRequestFullscreen) {\n        element.msRequestFullscreen();\n      }\n    },\n    FullScreen.prototype.exitFullscreen = function() {\n      if(document.exitFullscreen) {\n        document.exitFullscreen();\n      } else if(document.mozCancelFullScreen) {\n        document.mozCancelFullScreen();\n      } else if(document.webkitExitFullscreen) {\n        document.webkitExitFullscreen();\n      }\n    },\n    //toggle screen\n    FullScreen.prototype.toggle_fullscreen  = function() {\n      var $this = this;\n      var fullscreenEnabled = document.fullscreenEnabled || document.mozFullScreenEnabled || document.webkitFullscreenEnabled;\n      if(fullscreenEnabled) {\n        if(!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {\n          $this.launchFullscreen(document.documentElement);\n        } else{\n          $this.exitFullscreen();\n        }\n      }\n    },\n    //init sidemenu\n    FullScreen.prototype.init = function() {\n      var $this  = this;\n      //bind\n      $this.$fullscreenBtn.on('click', function() {\n        $this.toggle_fullscreen();\n      });\n    },\n     //init FullScreen\n    $.FullScreen = new FullScreen, $.FullScreen.Constructor = FullScreen\n    \n}(window.jQuery),\n\n\n\n//main app module\n function($) {\n    \"use strict\";\n    \n    var App = function() {\n        this.VERSION = \"1.1.0\", \n        this.AUTHOR = \"Coderthemes\", \n        this.SUPPORT = \"coderthemes@gmail.com\", \n        this.pageScrollElement = \"html, body\", \n        this.$body = $(\"body\")\n    };\n    \n     //on doc load\n    App.prototype.onDocReady = function(e) {\n      FastClick.attach(document.body);\n      resizefunc.push(\"initscrolls\");\n      resizefunc.push(\"changeptype\");\n\n      $('.animate-number').each(function(){\n        $(this).animateNumbers($(this).attr(\"data-value\"), true, parseInt($(this).attr(\"data-duration\"))); \n      });\n    \n      //RUN RESIZE ITEMS\n      $(window).resize(debounce(resizeitems,100));\n      $(\"body\").trigger(\"resize\");\n\n      // right side-bar toggle\n      $('.right-bar-toggle').on('click', function(e){\n          e.preventDefault();\n          $('#wrapper').toggleClass('right-bar-enabled');\n      }); \n\n      \n    },\n    //initilizing \n    App.prototype.init = function() {\n        var $this = this;\n        //document load initialization\n        $(document).ready($this.onDocReady);\n        //init side bar - left\n        $.Sidemenu.init();\n        //init fullscreen\n        $.FullScreen.init();\n    },\n\n    $.App = new App, $.App.Constructor = App\n\n}(window.jQuery),\n\n//initializing main application module\nfunction($) {\n    \"use strict\";\n    $.App.init();\n}(window.jQuery);\n\n\n\n/* ------------ some utility functions ----------------------- */\n//this full screen\nvar toggle_fullscreen = function () {\n\n}\n\nfunction executeFunctionByName(functionName, context /*, args */) {\n  var args = [].slice.call(arguments).splice(2);\n  var namespaces = functionName.split(\".\");\n  var func = namespaces.pop();\n  for(var i = 0; i < namespaces.length; i++) {\n    context = context[namespaces[i]];\n  }\n  return context[func].apply(this, args);\n}\nvar w,h,dw,dh;\nvar changeptype = function(){\n    w = $(window).width();\n    h = $(window).height();\n    dw = $(document).width();\n    dh = $(document).height();\n\n    if(jQuery.browser.mobile === true){\n        $(\"body\").addClass(\"mobile\").removeClass(\"fixed-left\");\n    }\n\n    if(!$(\"#wrapper\").hasClass(\"forced\")){\n      if(w > 990){\n        $(\"body\").removeClass(\"smallscreen\").addClass(\"widescreen\");\n          $(\"#wrapper\").removeClass(\"enlarged\");\n      }else{\n        $(\"body\").removeClass(\"widescreen\").addClass(\"smallscreen\");\n        $(\"#wrapper\").addClass(\"enlarged\");\n        $(\".left ul\").removeAttr(\"style\");\n      }\n      if($(\"#wrapper\").hasClass(\"enlarged\") && $(\"body\").hasClass(\"fixed-left\")){\n        $(\"body\").removeClass(\"fixed-left\").addClass(\"fixed-left-void\");\n      }else if(!$(\"#wrapper\").hasClass(\"enlarged\") && $(\"body\").hasClass(\"fixed-left-void\")){\n        $(\"body\").removeClass(\"fixed-left-void\").addClass(\"fixed-left\");\n      }\n\n  }\n  toggle_slimscroll(\".slimscrollleft\");\n}\n\n\nvar debounce = function(func, wait, immediate) {\n  var timeout, result;\n  return function() {\n    var context = this, args = arguments;\n    var later = function() {\n      timeout = null;\n      if (!immediate) result = func.apply(context, args);\n    };\n    var callNow = immediate && !timeout;\n    clearTimeout(timeout);\n    timeout = setTimeout(later, wait);\n    if (callNow) result = func.apply(context, args);\n    return result;\n  };\n}\n\nfunction resizeitems(){\n  if($.isArray(resizefunc)){  \n    for (i = 0; i < resizefunc.length; i++) {\n        window[resizefunc[i]]();\n    }\n  }\n}\n\nfunction initscrolls(){\n    if(jQuery.browser.mobile !== true){\n      //SLIM SCROLL\n      $('.slimscroller').slimscroll({\n        height: 'auto',\n        size: \"5px\"\n      });\n\n      $('.slimscrollleft').slimScroll({\n          height: 'auto',\n          position: 'right',\n          size: \"5px\",\n          color: '#dcdcdc',\n          wheelStep: 5\n      });\n  }\n}\nfunction toggle_slimscroll(item){\n    if($(\"#wrapper\").hasClass(\"enlarged\")){\n      $(item).css(\"overflow\",\"inherit\").parent().css(\"overflow\",\"inherit\");\n      $(item). siblings(\".slimScrollBar\").css(\"visibility\",\"hidden\");\n    }else{\n      $(item).css(\"overflow\",\"hidden\").parent().css(\"overflow\",\"hidden\");\n      $(item). siblings(\".slimScrollBar\").css(\"visibility\",\"visible\");\n    }\n}\n\nvar wow = new WOW(\n  {\n    boxClass: 'wow', // animated element css class (default is wow)\n    animateClass: 'animated', // animation css class (default is animated)\n    offset: 50, // distance to the element when triggering the animation (default is 0)\n    mobile: false        // trigger animations on mobile devices (true is default)\n  }\n);\nwow.init();\n"
  },
  {
    "path": "static/assets/js/jquery.blockUI.js",
    "content": "/*!\n * jQuery blockUI plugin\n * Version 2.70.0-2014.11.23\n * Requires jQuery v1.7 or later\n *\n * Examples at: http://malsup.com/jquery/block/\n * Copyright (c) 2007-2013 M. Alsup\n * Dual licensed under the MIT and GPL licenses:\n * http://www.opensource.org/licenses/mit-license.php\n * http://www.gnu.org/licenses/gpl.html\n *\n * Thanks to Amir-Hossein Sobhi for some excellent contributions!\n */\n\n;(function() {\n/*jshint eqeqeq:false curly:false latedef:false */\n\"use strict\";\n\n\tfunction setup($) {\n\t\t$.fn._fadeIn = $.fn.fadeIn;\n\n\t\tvar noOp = $.noop || function() {};\n\n\t\t// this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle\n\t\t// confusing userAgent strings on Vista)\n\t\tvar msie = /MSIE/.test(navigator.userAgent);\n\t\tvar ie6  = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);\n\t\tvar mode = document.documentMode || 0;\n\t\tvar setExpr = $.isFunction( document.createElement('div').style.setExpression );\n\n\t\t// global $ methods for blocking/unblocking the entire page\n\t\t$.blockUI   = function(opts) { install(window, opts); };\n\t\t$.unblockUI = function(opts) { remove(window, opts); };\n\n\t\t// convenience method for quick growl-like notifications  (http://www.google.com/search?q=growl)\n\t\t$.growlUI = function(title, message, timeout, onClose) {\n\t\t\tvar $m = $('<div class=\"growlUI\"></div>');\n\t\t\tif (title) $m.append('<h1>'+title+'</h1>');\n\t\t\tif (message) $m.append('<h2>'+message+'</h2>');\n\t\t\tif (timeout === undefined) timeout = 3000;\n\n\t\t\t// Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications\n\t\t\tvar callBlock = function(opts) {\n\t\t\t\topts = opts || {};\n\n\t\t\t\t$.blockUI({\n\t\t\t\t\tmessage: $m,\n\t\t\t\t\tfadeIn : typeof opts.fadeIn  !== 'undefined' ? opts.fadeIn  : 700,\n\t\t\t\t\tfadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,\n\t\t\t\t\ttimeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,\n\t\t\t\t\tcenterY: false,\n\t\t\t\t\tshowOverlay: false,\n\t\t\t\t\tonUnblock: onClose,\n\t\t\t\t\tcss: $.blockUI.defaults.growlCSS\n\t\t\t\t});\n\t\t\t};\n\n\t\t\tcallBlock();\n\t\t\tvar nonmousedOpacity = $m.css('opacity');\n\t\t\t$m.mouseover(function() {\n\t\t\t\tcallBlock({\n\t\t\t\t\tfadeIn: 0,\n\t\t\t\t\ttimeout: 30000\n\t\t\t\t});\n\n\t\t\t\tvar displayBlock = $('.blockMsg');\n\t\t\t\tdisplayBlock.stop(); // cancel fadeout if it has started\n\t\t\t\tdisplayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency\n\t\t\t}).mouseout(function() {\n\t\t\t\t$('.blockMsg').fadeOut(1000);\n\t\t\t});\n\t\t\t// End konapun additions\n\t\t};\n\n\t\t// plugin method for blocking element content\n\t\t$.fn.block = function(opts) {\n\t\t\tif ( this[0] === window ) {\n\t\t\t\t$.blockUI( opts );\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\tvar fullOpts = $.extend({}, $.blockUI.defaults, opts || {});\n\t\t\tthis.each(function() {\n\t\t\t\tvar $el = $(this);\n\t\t\t\tif (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))\n\t\t\t\t\treturn;\n\t\t\t\t$el.unblock({ fadeOut: 0 });\n\t\t\t});\n\n\t\t\treturn this.each(function() {\n\t\t\t\tif ($.css(this,'position') == 'static') {\n\t\t\t\t\tthis.style.position = 'relative';\n\t\t\t\t\t$(this).data('blockUI.static', true);\n\t\t\t\t}\n\t\t\t\tthis.style.zoom = 1; // force 'hasLayout' in ie\n\t\t\t\tinstall(this, opts);\n\t\t\t});\n\t\t};\n\n\t\t// plugin method for unblocking element content\n\t\t$.fn.unblock = function(opts) {\n\t\t\tif ( this[0] === window ) {\n\t\t\t\t$.unblockUI( opts );\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\treturn this.each(function() {\n\t\t\t\tremove(this, opts);\n\t\t\t});\n\t\t};\n\n\t\t$.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!\n\n\t\t// override these in your code to change the default behavior and style\n\t\t$.blockUI.defaults = {\n\t\t\t// message displayed when blocking (use null for no message)\n\t\t\tmessage:  '<h1>Please wait...</h1>',\n\n\t\t\ttitle: null,\t\t// title string; only used when theme == true\n\t\t\tdraggable: true,\t// only used when theme == true (requires jquery-ui.js to be loaded)\n\n\t\t\ttheme: false, // set to true to use with jQuery UI themes\n\n\t\t\t// styles for the message when blocking; if you wish to disable\n\t\t\t// these and use an external stylesheet then do this in your code:\n\t\t\t// $.blockUI.defaults.css = {};\n\t\t\tcss: {\n\t\t\t\tpadding:\t0,\n\t\t\t\tmargin:\t\t0,\n\t\t\t\twidth:\t\t'30%',\n\t\t\t\ttop:\t\t'40%',\n\t\t\t\tleft:\t\t'35%',\n\t\t\t\ttextAlign:\t'center',\n\t\t\t\tcolor:\t\t'#000',\n\t\t\t\tborder:\t\t'3px solid #aaa',\n\t\t\t\tbackgroundColor:'#fff',\n\t\t\t\tcursor:\t\t'wait'\n\t\t\t},\n\n\t\t\t// minimal style set used when themes are used\n\t\t\tthemedCSS: {\n\t\t\t\twidth:\t'30%',\n\t\t\t\ttop:\t'40%',\n\t\t\t\tleft:\t'35%'\n\t\t\t},\n\n\t\t\t// styles for the overlay\n\t\t\toverlayCSS:  {\n\t\t\t\tbackgroundColor:\t'#000',\n\t\t\t\topacity:\t\t\t0.6,\n\t\t\t\tcursor:\t\t\t\t'wait'\n\t\t\t},\n\n\t\t\t// style to replace wait cursor before unblocking to correct issue\n\t\t\t// of lingering wait cursor\n\t\t\tcursorReset: 'default',\n\n\t\t\t// styles applied when using $.growlUI\n\t\t\tgrowlCSS: {\n\t\t\t\twidth:\t\t'350px',\n\t\t\t\ttop:\t\t'10px',\n\t\t\t\tleft:\t\t'',\n\t\t\t\tright:\t\t'10px',\n\t\t\t\tborder:\t\t'none',\n\t\t\t\tpadding:\t'5px',\n\t\t\t\topacity:\t0.6,\n\t\t\t\tcursor:\t\t'default',\n\t\t\t\tcolor:\t\t'#fff',\n\t\t\t\tbackgroundColor: '#000',\n\t\t\t\t'-webkit-border-radius':'10px',\n\t\t\t\t'-moz-border-radius':\t'10px',\n\t\t\t\t'border-radius':\t\t'10px'\n\t\t\t},\n\n\t\t\t// IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w\n\t\t\t// (hat tip to Jorge H. N. de Vasconcelos)\n\t\t\t/*jshint scripturl:true */\n\t\t\tiframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',\n\n\t\t\t// force usage of iframe in non-IE browsers (handy for blocking applets)\n\t\t\tforceIframe: false,\n\n\t\t\t// z-index for the blocking overlay\n\t\t\tbaseZ: 1000,\n\n\t\t\t// set these to true to have the message automatically centered\n\t\t\tcenterX: true, // <-- only effects element blocking (page block controlled via css above)\n\t\t\tcenterY: true,\n\n\t\t\t// allow body element to be stetched in ie6; this makes blocking look better\n\t\t\t// on \"short\" pages.  disable if you wish to prevent changes to the body height\n\t\t\tallowBodyStretch: true,\n\n\t\t\t// enable if you want key and mouse events to be disabled for content that is blocked\n\t\t\tbindEvents: true,\n\n\t\t\t// be default blockUI will supress tab navigation from leaving blocking content\n\t\t\t// (if bindEvents is true)\n\t\t\tconstrainTabKey: true,\n\n\t\t\t// fadeIn time in millis; set to 0 to disable fadeIn on block\n\t\t\tfadeIn:  200,\n\n\t\t\t// fadeOut time in millis; set to 0 to disable fadeOut on unblock\n\t\t\tfadeOut:  400,\n\n\t\t\t// time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock\n\t\t\ttimeout: 0,\n\n\t\t\t// disable if you don't want to show the overlay\n\t\t\tshowOverlay: true,\n\n\t\t\t// if true, focus will be placed in the first available input field when\n\t\t\t// page blocking\n\t\t\tfocusInput: true,\n\n            // elements that can receive focus\n            focusableElements: ':input:enabled:visible',\n\n\t\t\t// suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)\n\t\t\t// no longer needed in 2012\n\t\t\t// applyPlatformOpacityRules: true,\n\n\t\t\t// callback method invoked when fadeIn has completed and blocking message is visible\n\t\t\tonBlock: null,\n\n\t\t\t// callback method invoked when unblocking has completed; the callback is\n\t\t\t// passed the element that has been unblocked (which is the window object for page\n\t\t\t// blocks) and the options that were passed to the unblock call:\n\t\t\t//\tonUnblock(element, options)\n\t\t\tonUnblock: null,\n\n\t\t\t// callback method invoked when the overlay area is clicked.\n\t\t\t// setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.\n\t\t\tonOverlayClick: null,\n\n\t\t\t// don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493\n\t\t\tquirksmodeOffsetHack: 4,\n\n\t\t\t// class name of the message block\n\t\t\tblockMsgClass: 'blockMsg',\n\n\t\t\t// if it is already blocked, then ignore it (don't unblock and reblock)\n\t\t\tignoreIfBlocked: false\n\t\t};\n\n\t\t// private data and functions follow...\n\n\t\tvar pageBlock = null;\n\t\tvar pageBlockEls = [];\n\n\t\tfunction install(el, opts) {\n\t\t\tvar css, themedCSS;\n\t\t\tvar full = (el == window);\n\t\t\tvar msg = (opts && opts.message !== undefined ? opts.message : undefined);\n\t\t\topts = $.extend({}, $.blockUI.defaults, opts || {});\n\n\t\t\tif (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))\n\t\t\t\treturn;\n\n\t\t\topts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});\n\t\t\tcss = $.extend({}, $.blockUI.defaults.css, opts.css || {});\n\t\t\tif (opts.onOverlayClick)\n\t\t\t\topts.overlayCSS.cursor = 'pointer';\n\n\t\t\tthemedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});\n\t\t\tmsg = msg === undefined ? opts.message : msg;\n\n\t\t\t// remove the current block (if there is one)\n\t\t\tif (full && pageBlock)\n\t\t\t\tremove(window, {fadeOut:0});\n\n\t\t\t// if an existing element is being used as the blocking content then we capture\n\t\t\t// its current place in the DOM (and current display style) so we can restore\n\t\t\t// it when we unblock\n\t\t\tif (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {\n\t\t\t\tvar node = msg.jquery ? msg[0] : msg;\n\t\t\t\tvar data = {};\n\t\t\t\t$(el).data('blockUI.history', data);\n\t\t\t\tdata.el = node;\n\t\t\t\tdata.parent = node.parentNode;\n\t\t\t\tdata.display = node.style.display;\n\t\t\t\tdata.position = node.style.position;\n\t\t\t\tif (data.parent)\n\t\t\t\t\tdata.parent.removeChild(node);\n\t\t\t}\n\n\t\t\t$(el).data('blockUI.onUnblock', opts.onUnblock);\n\t\t\tvar z = opts.baseZ;\n\n\t\t\t// blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;\n\t\t\t// layer1 is the iframe layer which is used to supress bleed through of underlying content\n\t\t\t// layer2 is the overlay layer which has opacity and a wait cursor (by default)\n\t\t\t// layer3 is the message content that is displayed while blocking\n\t\t\tvar lyr1, lyr2, lyr3, s;\n\t\t\tif (msie || opts.forceIframe)\n\t\t\t\tlyr1 = $('<iframe class=\"blockUI\" style=\"z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0\" src=\"'+opts.iframeSrc+'\"></iframe>');\n\t\t\telse\n\t\t\t\tlyr1 = $('<div class=\"blockUI\" style=\"display:none\"></div>');\n\n\t\t\tif (opts.theme)\n\t\t\t\tlyr2 = $('<div class=\"blockUI blockOverlay ui-widget-overlay\" style=\"z-index:'+ (z++) +';display:none\"></div>');\n\t\t\telse\n\t\t\t\tlyr2 = $('<div class=\"blockUI blockOverlay\" style=\"z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0\"></div>');\n\n\t\t\tif (opts.theme && full) {\n\t\t\t\ts = '<div class=\"blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all\" style=\"z-index:'+(z+10)+';display:none;position:fixed\">';\n\t\t\t\tif ( opts.title ) {\n\t\t\t\t\ts += '<div class=\"ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle\">'+(opts.title || '&nbsp;')+'</div>';\n\t\t\t\t}\n\t\t\t\ts += '<div class=\"ui-widget-content ui-dialog-content\"></div>';\n\t\t\t\ts += '</div>';\n\t\t\t}\n\t\t\telse if (opts.theme) {\n\t\t\t\ts = '<div class=\"blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all\" style=\"z-index:'+(z+10)+';display:none;position:absolute\">';\n\t\t\t\tif ( opts.title ) {\n\t\t\t\t\ts += '<div class=\"ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle\">'+(opts.title || '&nbsp;')+'</div>';\n\t\t\t\t}\n\t\t\t\ts += '<div class=\"ui-widget-content ui-dialog-content\"></div>';\n\t\t\t\ts += '</div>';\n\t\t\t}\n\t\t\telse if (full) {\n\t\t\t\ts = '<div class=\"blockUI ' + opts.blockMsgClass + ' blockPage\" style=\"z-index:'+(z+10)+';display:none;position:fixed\"></div>';\n\t\t\t}\n\t\t\telse {\n\t\t\t\ts = '<div class=\"blockUI ' + opts.blockMsgClass + ' blockElement\" style=\"z-index:'+(z+10)+';display:none;position:absolute\"></div>';\n\t\t\t}\n\t\t\tlyr3 = $(s);\n\n\t\t\t// if we have a message, style it\n\t\t\tif (msg) {\n\t\t\t\tif (opts.theme) {\n\t\t\t\t\tlyr3.css(themedCSS);\n\t\t\t\t\tlyr3.addClass('ui-widget-content');\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tlyr3.css(css);\n\t\t\t}\n\n\t\t\t// style the overlay\n\t\t\tif (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)\n\t\t\t\tlyr2.css(opts.overlayCSS);\n\t\t\tlyr2.css('position', full ? 'fixed' : 'absolute');\n\n\t\t\t// make iframe layer transparent in IE\n\t\t\tif (msie || opts.forceIframe)\n\t\t\t\tlyr1.css('opacity',0.0);\n\n\t\t\t//$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);\n\t\t\tvar layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);\n\t\t\t$.each(layers, function() {\n\t\t\t\tthis.appendTo($par);\n\t\t\t});\n\n\t\t\tif (opts.theme && opts.draggable && $.fn.draggable) {\n\t\t\t\tlyr3.draggable({\n\t\t\t\t\thandle: '.ui-dialog-titlebar',\n\t\t\t\t\tcancel: 'li'\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)\n\t\t\tvar expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);\n\t\t\tif (ie6 || expr) {\n\t\t\t\t// give body 100% height\n\t\t\t\tif (full && opts.allowBodyStretch && $.support.boxModel)\n\t\t\t\t\t$('html,body').css('height','100%');\n\n\t\t\t\t// fix ie6 issue when blocked element has a border width\n\t\t\t\tif ((ie6 || !$.support.boxModel) && !full) {\n\t\t\t\t\tvar t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');\n\t\t\t\t\tvar fixT = t ? '(0 - '+t+')' : 0;\n\t\t\t\t\tvar fixL = l ? '(0 - '+l+')' : 0;\n\t\t\t\t}\n\n\t\t\t\t// simulate fixed position\n\t\t\t\t$.each(layers, function(i,o) {\n\t\t\t\t\tvar s = o[0].style;\n\t\t\t\t\ts.position = 'absolute';\n\t\t\t\t\tif (i < 2) {\n\t\t\t\t\t\tif (full)\n\t\t\t\t\t\t\ts.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + \"px\"');\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\ts.setExpression('height','this.parentNode.offsetHeight + \"px\"');\n\t\t\t\t\t\tif (full)\n\t\t\t\t\t\t\ts.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + \"px\"');\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\ts.setExpression('width','this.parentNode.offsetWidth + \"px\"');\n\t\t\t\t\t\tif (fixL) s.setExpression('left', fixL);\n\t\t\t\t\t\tif (fixT) s.setExpression('top', fixT);\n\t\t\t\t\t}\n\t\t\t\t\telse if (opts.centerY) {\n\t\t\t\t\t\tif (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + \"px\"');\n\t\t\t\t\t\ts.marginTop = 0;\n\t\t\t\t\t}\n\t\t\t\t\telse if (!opts.centerY && full) {\n\t\t\t\t\t\tvar top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;\n\t\t\t\t\t\tvar expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + \"px\"';\n\t\t\t\t\t\ts.setExpression('top',expression);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// show the message\n\t\t\tif (msg) {\n\t\t\t\tif (opts.theme)\n\t\t\t\t\tlyr3.find('.ui-widget-content').append(msg);\n\t\t\t\telse\n\t\t\t\t\tlyr3.append(msg);\n\t\t\t\tif (msg.jquery || msg.nodeType)\n\t\t\t\t\t$(msg).show();\n\t\t\t}\n\n\t\t\tif ((msie || opts.forceIframe) && opts.showOverlay)\n\t\t\t\tlyr1.show(); // opacity is zero\n\t\t\tif (opts.fadeIn) {\n\t\t\t\tvar cb = opts.onBlock ? opts.onBlock : noOp;\n\t\t\t\tvar cb1 = (opts.showOverlay && !msg) ? cb : noOp;\n\t\t\t\tvar cb2 = msg ? cb : noOp;\n\t\t\t\tif (opts.showOverlay)\n\t\t\t\t\tlyr2._fadeIn(opts.fadeIn, cb1);\n\t\t\t\tif (msg)\n\t\t\t\t\tlyr3._fadeIn(opts.fadeIn, cb2);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (opts.showOverlay)\n\t\t\t\t\tlyr2.show();\n\t\t\t\tif (msg)\n\t\t\t\t\tlyr3.show();\n\t\t\t\tif (opts.onBlock)\n\t\t\t\t\topts.onBlock.bind(lyr3)();\n\t\t\t}\n\n\t\t\t// bind key and mouse events\n\t\t\tbind(1, el, opts);\n\n\t\t\tif (full) {\n\t\t\t\tpageBlock = lyr3[0];\n\t\t\t\tpageBlockEls = $(opts.focusableElements,pageBlock);\n\t\t\t\tif (opts.focusInput)\n\t\t\t\t\tsetTimeout(focus, 20);\n\t\t\t}\n\t\t\telse\n\t\t\t\tcenter(lyr3[0], opts.centerX, opts.centerY);\n\n\t\t\tif (opts.timeout) {\n\t\t\t\t// auto-unblock\n\t\t\t\tvar to = setTimeout(function() {\n\t\t\t\t\tif (full)\n\t\t\t\t\t\t$.unblockUI(opts);\n\t\t\t\t\telse\n\t\t\t\t\t\t$(el).unblock(opts);\n\t\t\t\t}, opts.timeout);\n\t\t\t\t$(el).data('blockUI.timeout', to);\n\t\t\t}\n\t\t}\n\n\t\t// remove the block\n\t\tfunction remove(el, opts) {\n\t\t\tvar count;\n\t\t\tvar full = (el == window);\n\t\t\tvar $el = $(el);\n\t\t\tvar data = $el.data('blockUI.history');\n\t\t\tvar to = $el.data('blockUI.timeout');\n\t\t\tif (to) {\n\t\t\t\tclearTimeout(to);\n\t\t\t\t$el.removeData('blockUI.timeout');\n\t\t\t}\n\t\t\topts = $.extend({}, $.blockUI.defaults, opts || {});\n\t\t\tbind(0, el, opts); // unbind events\n\n\t\t\tif (opts.onUnblock === null) {\n\t\t\t\topts.onUnblock = $el.data('blockUI.onUnblock');\n\t\t\t\t$el.removeData('blockUI.onUnblock');\n\t\t\t}\n\n\t\t\tvar els;\n\t\t\tif (full) // crazy selector to handle odd field errors in ie6/7\n\t\t\t\tels = $('body').children().filter('.blockUI').add('body > .blockUI');\n\t\t\telse\n\t\t\t\tels = $el.find('>.blockUI');\n\n\t\t\t// fix cursor issue\n\t\t\tif ( opts.cursorReset ) {\n\t\t\t\tif ( els.length > 1 )\n\t\t\t\t\tels[1].style.cursor = opts.cursorReset;\n\t\t\t\tif ( els.length > 2 )\n\t\t\t\t\tels[2].style.cursor = opts.cursorReset;\n\t\t\t}\n\n\t\t\tif (full)\n\t\t\t\tpageBlock = pageBlockEls = null;\n\n\t\t\tif (opts.fadeOut) {\n\t\t\t\tcount = els.length;\n\t\t\t\tels.stop().fadeOut(opts.fadeOut, function() {\n\t\t\t\t\tif ( --count === 0)\n\t\t\t\t\t\treset(els,data,opts,el);\n\t\t\t\t});\n\t\t\t}\n\t\t\telse\n\t\t\t\treset(els, data, opts, el);\n\t\t}\n\n\t\t// move blocking element back into the DOM where it started\n\t\tfunction reset(els,data,opts,el) {\n\t\t\tvar $el = $(el);\n\t\t\tif ( $el.data('blockUI.isBlocked') )\n\t\t\t\treturn;\n\n\t\t\tels.each(function(i,o) {\n\t\t\t\t// remove via DOM calls so we don't lose event handlers\n\t\t\t\tif (this.parentNode)\n\t\t\t\t\tthis.parentNode.removeChild(this);\n\t\t\t});\n\n\t\t\tif (data && data.el) {\n\t\t\t\tdata.el.style.display = data.display;\n\t\t\t\tdata.el.style.position = data.position;\n\t\t\t\tdata.el.style.cursor = 'default'; // #59\n\t\t\t\tif (data.parent)\n\t\t\t\t\tdata.parent.appendChild(data.el);\n\t\t\t\t$el.removeData('blockUI.history');\n\t\t\t}\n\n\t\t\tif ($el.data('blockUI.static')) {\n\t\t\t\t$el.css('position', 'static'); // #22\n\t\t\t}\n\n\t\t\tif (typeof opts.onUnblock == 'function')\n\t\t\t\topts.onUnblock(el,opts);\n\n\t\t\t// fix issue in Safari 6 where block artifacts remain until reflow\n\t\t\tvar body = $(document.body), w = body.width(), cssW = body[0].style.width;\n\t\t\tbody.width(w-1).width(w);\n\t\t\tbody[0].style.width = cssW;\n\t\t}\n\n\t\t// bind/unbind the handler\n\t\tfunction bind(b, el, opts) {\n\t\t\tvar full = el == window, $el = $(el);\n\n\t\t\t// don't bother unbinding if there is nothing to unbind\n\t\t\tif (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))\n\t\t\t\treturn;\n\n\t\t\t$el.data('blockUI.isBlocked', b);\n\n\t\t\t// don't bind events when overlay is not in use or if bindEvents is false\n\t\t\tif (!full || !opts.bindEvents || (b && !opts.showOverlay))\n\t\t\t\treturn;\n\n\t\t\t// bind anchors and inputs for mouse and key events\n\t\t\tvar events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';\n\t\t\tif (b)\n\t\t\t\t$(document).bind(events, opts, handler);\n\t\t\telse\n\t\t\t\t$(document).unbind(events, handler);\n\n\t\t// former impl...\n\t\t//\t\tvar $e = $('a,:input');\n\t\t//\t\tb ? $e.bind(events, opts, handler) : $e.unbind(events, handler);\n\t\t}\n\n\t\t// event handler to suppress keyboard/mouse events when blocking\n\t\tfunction handler(e) {\n\t\t\t// allow tab navigation (conditionally)\n\t\t\tif (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {\n\t\t\t\tif (pageBlock && e.data.constrainTabKey) {\n\t\t\t\t\tvar els = pageBlockEls;\n\t\t\t\t\tvar fwd = !e.shiftKey && e.target === els[els.length-1];\n\t\t\t\t\tvar back = e.shiftKey && e.target === els[0];\n\t\t\t\t\tif (fwd || back) {\n\t\t\t\t\t\tsetTimeout(function(){focus(back);},10);\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar opts = e.data;\n\t\t\tvar target = $(e.target);\n\t\t\tif (target.hasClass('blockOverlay') && opts.onOverlayClick)\n\t\t\t\topts.onOverlayClick(e);\n\n\t\t\t// allow events within the message content\n\t\t\tif (target.parents('div.' + opts.blockMsgClass).length > 0)\n\t\t\t\treturn true;\n\n\t\t\t// allow events for content that is not being blocked\n\t\t\treturn target.parents().children().filter('div.blockUI').length === 0;\n\t\t}\n\n\t\tfunction focus(back) {\n\t\t\tif (!pageBlockEls)\n\t\t\t\treturn;\n\t\t\tvar e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];\n\t\t\tif (e)\n\t\t\t\te.focus();\n\t\t}\n\n\t\tfunction center(el, x, y) {\n\t\t\tvar p = el.parentNode, s = el.style;\n\t\t\tvar l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');\n\t\t\tvar t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');\n\t\t\tif (x) s.left = l > 0 ? (l+'px') : '0';\n\t\t\tif (y) s.top  = t > 0 ? (t+'px') : '0';\n\t\t}\n\n\t\tfunction sz(el, p) {\n\t\t\treturn parseInt($.css(el,p),10)||0;\n\t\t}\n\n\t}\n\n\n\t/*global define:true */\n\tif (typeof define === 'function' && define.amd && define.amd.jQuery) {\n\t\tdefine(['jquery'], setup);\n\t} else {\n\t\tsetup(jQuery);\n\t}\n\n})();\n"
  },
  {
    "path": "static/assets/js/jquery.core.js",
    "content": "//portlets\n!function($) {\n    \"use strict\";\n\n    /**\n    Portlet Widget\n    */\n    var Portlet = function() {\n        this.$body = $(\"body\"),\n        this.$portletIdentifier = \".portlet\",\n        this.$portletCloser = '.portlet a[data-toggle=\"remove\"]',\n        this.$portletRefresher = '.portlet a[data-toggle=\"reload\"]'\n    };\n\n    //on init\n    Portlet.prototype.init = function() {\n        // Panel closest\n        var $this = this;\n        $(document).on(\"click\",this.$portletCloser, function (ev) {\n            ev.preventDefault();\n            var $portlet = $(this).closest($this.$portletIdentifier);\n                var $portlet_parent = $portlet.parent();\n            $portlet.remove();\n            if ($portlet_parent.children().length == 0) {\n                $portlet_parent.remove();\n            }\n        });\n\n        // Panel Reload\n        $(document).on(\"click\",this.$portletRefresher, function (ev) {\n            ev.preventDefault();\n            var $portlet = $(this).closest($this.$portletIdentifier);\n            // This is just a simulation, nothing is going to be reloaded\n            $portlet.append('<div class=\"panel-disabled\"><div class=\"loader-1\"></div></div>');\n            var $pd = $portlet.find('.panel-disabled');\n            setTimeout(function () {\n                $pd.fadeOut('fast', function () {\n                    $pd.remove();\n                });\n            }, 500 + 300 * (Math.random() * 5));\n        });\n    },\n    //\n    $.Portlet = new Portlet, $.Portlet.Constructor = Portlet\n\n}(window.jQuery),\n\n/**\n * Notifications\n */\nfunction($) {\n    \"use strict\";\n\n    var Notification = function() {};\n\n    //simple notificaiton\n    Notification.prototype.notify = function(style,position, title, text) {\n        var icon = 'fa fa-adjust';\n        if(style == \"error\"){\n            icon = \"fa fa-exclamation\";\n        }else if(style == \"warning\"){\n            icon = \"fa fa-warning\";\n        }else if(style == \"success\"){\n            icon = \"fa fa-check\";\n        }else if(style == \"custom\"){\n            icon = \"md md-album\";\n        }else if(style == \"info\"){\n            icon = \"fa fa-question\";\n        }else{\n            icon = \"fa fa-adjust\";\n        }\n        $.notify({\n            title: title,\n            text: text,\n            image: \"<i class='\"+icon+\"'></i>\"\n        }, {\n            style: 'metro',\n            className: style,\n            globalPosition:position,\n            showAnimation: \"show\",\n            showDuration: 0,\n            hideDuration: 0,\n            autoHide: true,\n            clickToHide: true\n        });\n    },\n\n    //auto hide notification\n    Notification.prototype.autoHideNotify = function (style,position, title, text) {\n        var icon = \"fa fa-adjust\";\n        if(style == \"error\"){\n            icon = \"fa fa-exclamation\";\n        }else if(style == \"warning\"){\n            icon = \"fa fa-warning\";\n        }else if(style == \"success\"){\n            icon = \"fa fa-check\";\n        }else if(style == \"custom\"){\n            icon = \"md md-album\";\n        }else if(style == \"info\"){\n            icon = \"fa fa-question\";\n        }else{\n            icon = \"fa fa-adjust\";\n        }\n        $.notify({\n            title: title,\n            text: text,\n            image: \"<i class='\"+icon+\"'></i>\"\n        }, {\n            style: 'metro',\n            className: style,\n            globalPosition:position,\n            showAnimation: \"show\",\n            showDuration: 0,\n            hideDuration: 0,\n            autoHideDelay: 5000,\n            autoHide: true,\n            clickToHide: true\n        });\n    },\n    //confirmation notification\n    Notification.prototype.confirm = function(style,position, title) {\n        var icon = \"fa fa-adjust\";\n        if(style == \"error\"){\n            icon = \"fa fa-exclamation\";\n        }else if(style == \"warning\"){\n            icon = \"fa fa-warning\";\n        }else if(style == \"success\"){\n            icon = \"fa fa-check\";\n        }else if(style == \"custom\"){\n            icon = \"md md-album\";\n        }else if(style == \"info\"){\n            icon = \"fa fa-question\";\n        }else{\n            icon = \"fa fa-adjust\";\n        }\n        $.notify({\n            title: title,\n            text: 'Are you sure you want to do nothing?<div class=\"clearfix\"></div><br><a class=\"btn btn-sm btn-white yes\">Yes</a> <a class=\"btn btn-sm btn-danger no\">No</a>',\n            image: \"<i class='\"+icon+\"'></i>\"\n        }, {\n            style: 'metro',\n            className: style,\n            globalPosition:position,\n            showAnimation: \"show\",\n            showDuration: 0,\n            hideDuration: 0,\n            autoHide: false,\n            clickToHide: false\n        });\n        //listen for click events from this style\n        $(document).on('click', '.notifyjs-metro-base .no', function() {\n          //programmatically trigger propogating hide event\n          $(this).trigger('notify-hide');\n        });\n        $(document).on('click', '.notifyjs-metro-base .yes', function() {\n          //show button text\n          alert($(this).text() + \" clicked!\");\n          //hide notification\n          $(this).trigger('notify-hide');\n        });\n    },\n    //init - examples\n    Notification.prototype.init = function() {\n\n    },\n    //init\n    $.Notification = new Notification, $.Notification.Constructor = Notification\n}(window.jQuery),\n\n/**\n * Components\n */\nfunction($) {\n    \"use strict\";\n\n    var Components = function() {};\n\n    //initializing tooltip\n    Components.prototype.initTooltipPlugin = function() {\n        $.fn.tooltip && $('[data-toggle=\"tooltip\"]').tooltip()\n    },\n\n    //initializing popover\n    Components.prototype.initPopoverPlugin = function() {\n        $.fn.popover && $('[data-toggle=\"popover\"]').popover()\n    },\n\n    //initializing custom modal\n    Components.prototype.initCustomModalPlugin = function() {\n        $('[data-plugin=\"custommodal\"]').on('click', function(e) {\n        \tCustombox.open({\n                target: $(this).attr(\"href\"),\n                effect: $(this).attr(\"data-animation\"),\n                overlaySpeed: $(this).attr(\"data-overlaySpeed\"),\n                overlayColor: $(this).attr(\"data-overlayColor\")\n            });\n        \te.preventDefault();\n        });\n    },\n\n    //initializing nicescroll\n    Components.prototype.initNiceScrollPlugin = function() {\n        //You can change the color of scroll bar here\n        $.fn.niceScroll &&  $(\".nicescroll\").niceScroll({ cursorcolor: '#98a6ad',cursorwidth:'6px', cursorborderradius: '5px'});\n    },\n\n    //range slider\n    Components.prototype.initRangeSlider = function() {\n        $.fn.slider && $('[data-plugin=\"range-slider\"]').slider({});\n    },\n\n    /* -------------\n     * Form related controls\n     */\n    //switch\n    Components.prototype.initSwitchery = function() {\n        $('[data-plugin=\"switchery\"]').each(function (idx, obj) {\n            new Switchery($(this)[0], $(this).data());\n        });\n    },\n    //multiselect\n    Components.prototype.initMultiSelect = function() {\n        if($('[data-plugin=\"multiselect\"]').length > 0)\n            $('[data-plugin=\"multiselect\"]').multiSelect($(this).data());\n    },\n\n     /* -------------\n     * small charts related widgets\n     */\n     //peity charts\n     Components.prototype.initPeityCharts = function() {\n        $('[data-plugin=\"peity-pie\"]').each(function(idx, obj) {\n            var colors = $(this).attr('data-colors')?$(this).attr('data-colors').split(\",\"):[];\n            var width = $(this).attr('data-width')?$(this).attr('data-width'):20; //default is 20\n            var height = $(this).attr('data-height')?$(this).attr('data-height'):20; //default is 20\n            $(this).peity(\"pie\", {\n                fill: colors,\n                width: width,\n                height: height\n            });\n        });\n        //donut\n         $('[data-plugin=\"peity-donut\"]').each(function(idx, obj) {\n            var colors = $(this).attr('data-colors')?$(this).attr('data-colors').split(\",\"):[];\n            var width = $(this).attr('data-width')?$(this).attr('data-width'):20; //default is 20\n            var height = $(this).attr('data-height')?$(this).attr('data-height'):20; //default is 20\n            $(this).peity(\"donut\", {\n                fill: colors,\n                width: width,\n                height: height\n            });\n        });\n\n         $('[data-plugin=\"peity-donut-alt\"]').each(function(idx, obj) {\n            $(this).peity(\"donut\");\n        });\n\n         // line\n         $('[data-plugin=\"peity-line\"]').each(function(idx, obj) {\n            $(this).peity(\"line\", $(this).data());\n         });\n\n         // bar\n         $('[data-plugin=\"peity-bar\"]').each(function(idx, obj) {\n            var colors = $(this).attr('data-colors')?$(this).attr('data-colors').split(\",\"):[];\n            var width = $(this).attr('data-width')?$(this).attr('data-width'):20; //default is 20\n            var height = $(this).attr('data-height')?$(this).attr('data-height'):20; //default is 20\n            $(this).peity(\"bar\", {\n                fill: colors,\n                width: width,\n                height: height\n            });\n         });\n     },\n\n\n\n    //initilizing\n    Components.prototype.init = function() {\n        var $this = this;\n        this.initTooltipPlugin(),\n        this.initPopoverPlugin(),\n        this.initNiceScrollPlugin(),\n        this.initCustomModalPlugin(),\n        this.initRangeSlider(),\n        this.initSwitchery(),\n        this.initMultiSelect(),\n        this.initPeityCharts(),\n        //creating portles\n        $.Portlet.init();\n    },\n\n    $.Components = new Components, $.Components.Constructor = Components\n\n}(window.jQuery),\n    //initializing main application module\nfunction($) {\n    \"use strict\";\n    $.Components.init();\n}(window.jQuery);\n\n\n\n\n"
  },
  {
    "path": "static/assets/js/jquery.nicescroll.js",
    "content": "/* jquery.nicescroll 3.5.0 InuYaksa*2013 MIT http://areaaperta.com/nicescroll */(function(e){var z=!1,E=!1,L=5E3,M=2E3,y=0,N=function(){var e=document.getElementsByTagName(\"script\"),e=e[e.length-1].src.split(\"?\")[0];return 0<e.split(\"/\").length?e.split(\"/\").slice(0,-1).join(\"/\")+\"/\":\"\"}(),H=[\"ms\",\"moz\",\"webkit\",\"o\"],v=window.requestAnimationFrame||!1,w=window.cancelAnimationFrame||!1;if(!v)for(var O in H){var F=H[O];v||(v=window[F+\"RequestAnimationFrame\"]);w||(w=window[F+\"CancelAnimationFrame\"]||window[F+\"CancelRequestAnimationFrame\"])}var A=window.MutationObserver||window.WebKitMutationObserver||\n    !1,I={zindex:\"auto\",cursoropacitymin:0,cursoropacitymax:1,cursorcolor:\"#424242\",cursorwidth:\"5px\",cursorborder:\"1px solid #fff\",cursorborderradius:\"5px\",scrollspeed:60,mousescrollstep:24,touchbehavior:!1,hwacceleration:!0,usetransition:!0,boxzoom:!1,dblclickzoom:!0,gesturezoom:!0,grabcursorenabled:!0,autohidemode:!0,background:\"\",iframeautoresize:!0,cursorminheight:32,preservenativescrolling:!0,railoffset:!1,bouncescroll:!0,spacebarenabled:!0,railpadding:{top:0,right:0,left:0,bottom:0},disableoutline:!0,\n    horizrailenabled:!0,railalign:\"right\",railvalign:\"bottom\",enabletranslate3d:!0,enablemousewheel:!0,enablekeyboard:!0,smoothscroll:!0,sensitiverail:!0,enablemouselockapi:!0,cursorfixedheight:!1,directionlockdeadzone:6,hidecursordelay:400,nativeparentscrolling:!0,enablescrollonselection:!0,overflowx:!0,overflowy:!0,cursordragspeed:0.3,rtlmode:!1,cursordragontouch:!1,oneaxismousemode:\"auto\"},G=!1,P=function(){if(G)return G;var e=document.createElement(\"DIV\"),c={haspointerlock:\"pointerLockElement\"in document||\n    \"mozPointerLockElement\"in document||\"webkitPointerLockElement\"in document};c.isopera=\"opera\"in window;c.isopera12=c.isopera&&\"getUserMedia\"in navigator;c.isoperamini=\"[object OperaMini]\"===Object.prototype.toString.call(window.operamini);c.isie=\"all\"in document&&\"attachEvent\"in e&&!c.isopera;c.isieold=c.isie&&!(\"msInterpolationMode\"in e.style);c.isie7=c.isie&&!c.isieold&&(!(\"documentMode\"in document)||7==document.documentMode);c.isie8=c.isie&&\"documentMode\"in document&&8==document.documentMode;c.isie9=\n    c.isie&&\"performance\"in window&&9<=document.documentMode;c.isie10=c.isie&&\"performance\"in window&&10<=document.documentMode;c.isie9mobile=/iemobile.9/i.test(navigator.userAgent);c.isie9mobile&&(c.isie9=!1);c.isie7mobile=!c.isie9mobile&&c.isie7&&/iemobile/i.test(navigator.userAgent);c.ismozilla=\"MozAppearance\"in e.style;c.iswebkit=\"WebkitAppearance\"in e.style;c.ischrome=\"chrome\"in window;c.ischrome22=c.ischrome&&c.haspointerlock;c.ischrome26=c.ischrome&&\"transition\"in e.style;c.cantouch=\"ontouchstart\"in\n    document.documentElement||\"ontouchstart\"in window;c.hasmstouch=window.navigator.msPointerEnabled||!1;c.ismac=/^mac$/i.test(navigator.platform);c.isios=c.cantouch&&/iphone|ipad|ipod/i.test(navigator.platform);c.isios4=c.isios&&!(\"seal\"in Object);c.isandroid=/android/i.test(navigator.userAgent);c.trstyle=!1;c.hastransform=!1;c.hastranslate3d=!1;c.transitionstyle=!1;c.hastransition=!1;c.transitionend=!1;for(var k=[\"transform\",\"msTransform\",\"webkitTransform\",\"MozTransform\",\"OTransform\"],l=0;l<k.length;l++)if(\"undefined\"!=\n    typeof e.style[k[l]]){c.trstyle=k[l];break}c.hastransform=!1!=c.trstyle;c.hastransform&&(e.style[c.trstyle]=\"translate3d(1px,2px,3px)\",c.hastranslate3d=/translate3d/.test(e.style[c.trstyle]));c.transitionstyle=!1;c.prefixstyle=\"\";c.transitionend=!1;for(var k=\"transition webkitTransition MozTransition OTransition OTransition msTransition KhtmlTransition\".split(\" \"),q=\" -webkit- -moz- -o- -o -ms- -khtml-\".split(\" \"),t=\"transitionend webkitTransitionEnd transitionend otransitionend oTransitionEnd msTransitionEnd KhtmlTransitionEnd\".split(\" \"),\n                                                                                                                                                                                                                                                                     l=0;l<k.length;l++)if(k[l]in e.style){c.transitionstyle=k[l];c.prefixstyle=q[l];c.transitionend=t[l];break}c.ischrome26&&(c.prefixstyle=q[1]);c.hastransition=c.transitionstyle;a:{k=[\"-moz-grab\",\"-webkit-grab\",\"grab\"];if(c.ischrome&&!c.ischrome22||c.isie)k=[];for(l=0;l<k.length;l++)if(q=k[l],e.style.cursor=q,e.style.cursor==q){k=q;break a}k=\"url(http://www.google.com/intl/en_ALL/mapfiles/openhand.cur),n-resize\"}c.cursorgrabvalue=k;c.hasmousecapture=\"setCapture\"in e;c.hasMutationObserver=!1!==A;return G=\n    c},Q=function(h,c){function k(){var d=b.win;if(\"zIndex\"in d)return d.zIndex();for(;0<d.length&&9!=d[0].nodeType;){var c=d.css(\"zIndex\");if(!isNaN(c)&&0!=c)return parseInt(c);d=d.parent()}return!1}function l(d,c,f){c=d.css(c);d=parseFloat(c);return isNaN(d)?(d=u[c]||0,f=3==d?f?b.win.outerHeight()-b.win.innerHeight():b.win.outerWidth()-b.win.innerWidth():1,b.isie8&&d&&(d+=1),f?d:0):d}function q(d,c,f,g){b._bind(d,c,function(b){b=b?b:window.event;var g={original:b,target:b.target||b.srcElement,type:\"wheel\",\n    deltaMode:\"MozMousePixelScroll\"==b.type?0:1,deltaX:0,deltaZ:0,preventDefault:function(){b.preventDefault?b.preventDefault():b.returnValue=!1;return!1},stopImmediatePropagation:function(){b.stopImmediatePropagation?b.stopImmediatePropagation():b.cancelBubble=!0}};\"mousewheel\"==c?(g.deltaY=-0.025*b.wheelDelta,b.wheelDeltaX&&(g.deltaX=-0.025*b.wheelDeltaX)):g.deltaY=b.detail;return f.call(d,g)},g)}function t(d,c,f){var g,e;0==d.deltaMode?(g=-Math.floor(d.deltaX*(b.opt.mousescrollstep/54)),e=-Math.floor(d.deltaY*\n    (b.opt.mousescrollstep/54))):1==d.deltaMode&&(g=-Math.floor(d.deltaX*b.opt.mousescrollstep),e=-Math.floor(d.deltaY*b.opt.mousescrollstep));c&&(b.opt.oneaxismousemode&&0==g&&e)&&(g=e,e=0);g&&(b.scrollmom&&b.scrollmom.stop(),b.lastdeltax+=g,b.debounced(\"mousewheelx\",function(){var d=b.lastdeltax;b.lastdeltax=0;b.rail.drag||b.doScrollLeftBy(d)},120));if(e){if(b.opt.nativeparentscrolling&&f&&!b.ispage&&!b.zoomactive)if(0>e){if(b.getScrollTop()>=b.page.maxh)return!0}else if(0>=b.getScrollTop())return!0;\n    b.scrollmom&&b.scrollmom.stop();b.lastdeltay+=e;b.debounced(\"mousewheely\",function(){var d=b.lastdeltay;b.lastdeltay=0;b.rail.drag||b.doScrollBy(d)},120)}d.stopImmediatePropagation();return d.preventDefault()}var b=this;this.version=\"3.5.0\";this.name=\"nicescroll\";this.me=c;this.opt={doc:e(\"body\"),win:!1};e.extend(this.opt,I);this.opt.snapbackspeed=80;if(h)for(var p in b.opt)\"undefined\"!=typeof h[p]&&(b.opt[p]=h[p]);this.iddoc=(this.doc=b.opt.doc)&&this.doc[0]?this.doc[0].id||\"\":\"\";this.ispage=/BODY|HTML/.test(b.opt.win?\n    b.opt.win[0].nodeName:this.doc[0].nodeName);this.haswrapper=!1!==b.opt.win;this.win=b.opt.win||(this.ispage?e(window):this.doc);this.docscroll=this.ispage&&!this.haswrapper?e(window):this.win;this.body=e(\"body\");this.iframe=this.isfixed=this.viewport=!1;this.isiframe=\"IFRAME\"==this.doc[0].nodeName&&\"IFRAME\"==this.win[0].nodeName;this.istextarea=\"TEXTAREA\"==this.win[0].nodeName;this.forcescreen=!1;this.canshowonmouseevent=\"scroll\"!=b.opt.autohidemode;this.page=this.view=this.onzoomout=this.onzoomin=\n    this.onscrollcancel=this.onscrollend=this.onscrollstart=this.onclick=this.ongesturezoom=this.onkeypress=this.onmousewheel=this.onmousemove=this.onmouseup=this.onmousedown=!1;this.scroll={x:0,y:0};this.scrollratio={x:0,y:0};this.cursorheight=20;this.scrollvaluemax=0;this.observerremover=this.observer=this.scrollmom=this.scrollrunning=this.checkrtlmode=!1;do this.id=\"ascrail\"+M++;while(document.getElementById(this.id));this.hasmousefocus=this.hasfocus=this.zoomactive=this.zoom=this.selectiondrag=this.cursorfreezed=\n    this.cursor=this.rail=!1;this.visibility=!0;this.hidden=this.locked=!1;this.cursoractive=!0;this.overflowx=b.opt.overflowx;this.overflowy=b.opt.overflowy;this.nativescrollingarea=!1;this.checkarea=0;this.events=[];this.saved={};this.delaylist={};this.synclist={};this.lastdeltay=this.lastdeltax=0;this.detected=P();var g=e.extend({},this.detected);this.ishwscroll=(this.canhwscroll=g.hastransform&&b.opt.hwacceleration)&&b.haswrapper;this.istouchcapable=!1;g.cantouch&&(g.ischrome&&!g.isios&&!g.isandroid)&&\n(this.istouchcapable=!0,g.cantouch=!1);g.cantouch&&(g.ismozilla&&!g.isios&&!g.isandroid)&&(this.istouchcapable=!0,g.cantouch=!1);b.opt.enablemouselockapi||(g.hasmousecapture=!1,g.haspointerlock=!1);this.delayed=function(d,c,f,g){var e=b.delaylist[d],k=(new Date).getTime();if(!g&&e&&e.tt)return!1;e&&e.tt&&clearTimeout(e.tt);if(e&&e.last+f>k&&!e.tt)b.delaylist[d]={last:k+f,tt:setTimeout(function(){b.delaylist[d].tt=0;c.call()},f)};else if(!e||!e.tt)b.delaylist[d]={last:k,tt:0},setTimeout(function(){c.call()},\n    0)};this.debounced=function(d,c,f){var g=b.delaylist[d];(new Date).getTime();b.delaylist[d]=c;g||setTimeout(function(){var c=b.delaylist[d];b.delaylist[d]=!1;c.call()},f)};this.synched=function(d,c){b.synclist[d]=c;(function(){b.onsync||(v(function(){b.onsync=!1;for(d in b.synclist){var c=b.synclist[d];c&&c.call(b);b.synclist[d]=!1}}),b.onsync=!0)})();return d};this.unsynched=function(d){b.synclist[d]&&(b.synclist[d]=!1)};this.css=function(d,c){for(var f in c)b.saved.css.push([d,f,d.css(f)]),d.css(f,\n    c[f])};this.scrollTop=function(d){return\"undefined\"==typeof d?b.getScrollTop():b.setScrollTop(d)};this.scrollLeft=function(d){return\"undefined\"==typeof d?b.getScrollLeft():b.setScrollLeft(d)};BezierClass=function(b,c,f,g,e,k,l){this.st=b;this.ed=c;this.spd=f;this.p1=g||0;this.p2=e||1;this.p3=k||0;this.p4=l||1;this.ts=(new Date).getTime();this.df=this.ed-this.st};BezierClass.prototype={B2:function(b){return 3*b*b*(1-b)},B3:function(b){return 3*b*(1-b)*(1-b)},B4:function(b){return(1-b)*(1-b)*(1-b)},\n    getNow:function(){var b=1-((new Date).getTime()-this.ts)/this.spd,c=this.B2(b)+this.B3(b)+this.B4(b);return 0>b?this.ed:this.st+Math.round(this.df*c)},update:function(b,c){this.st=this.getNow();this.ed=b;this.spd=c;this.ts=(new Date).getTime();this.df=this.ed-this.st;return this}};if(this.ishwscroll){this.doc.translate={x:0,y:0,tx:\"0px\",ty:\"0px\"};g.hastranslate3d&&g.isios&&this.doc.css(\"-webkit-backface-visibility\",\"hidden\");var s=function(){var d=b.doc.css(g.trstyle);return d&&\"matrix\"==d.substr(0,\n    6)?d.replace(/^.*\\((.*)\\)$/g,\"$1\").replace(/px/g,\"\").split(/, +/):!1};this.getScrollTop=function(d){if(!d){if(d=s())return 16==d.length?-d[13]:-d[5];if(b.timerscroll&&b.timerscroll.bz)return b.timerscroll.bz.getNow()}return b.doc.translate.y};this.getScrollLeft=function(d){if(!d){if(d=s())return 16==d.length?-d[12]:-d[4];if(b.timerscroll&&b.timerscroll.bh)return b.timerscroll.bh.getNow()}return b.doc.translate.x};this.notifyScrollEvent=document.createEvent?function(b){var c=document.createEvent(\"UIEvents\");\n    c.initUIEvent(\"scroll\",!1,!0,window,1);b.dispatchEvent(c)}:document.fireEvent?function(b){var c=document.createEventObject();b.fireEvent(\"onscroll\");c.cancelBubble=!0}:function(b,c){};g.hastranslate3d&&b.opt.enabletranslate3d?(this.setScrollTop=function(d,c){b.doc.translate.y=d;b.doc.translate.ty=-1*d+\"px\";b.doc.css(g.trstyle,\"translate3d(\"+b.doc.translate.tx+\",\"+b.doc.translate.ty+\",0px)\");c||b.notifyScrollEvent(b.win[0])},this.setScrollLeft=function(d,c){b.doc.translate.x=d;b.doc.translate.tx=-1*\n    d+\"px\";b.doc.css(g.trstyle,\"translate3d(\"+b.doc.translate.tx+\",\"+b.doc.translate.ty+\",0px)\");c||b.notifyScrollEvent(b.win[0])}):(this.setScrollTop=function(d,c){b.doc.translate.y=d;b.doc.translate.ty=-1*d+\"px\";b.doc.css(g.trstyle,\"translate(\"+b.doc.translate.tx+\",\"+b.doc.translate.ty+\")\");c||b.notifyScrollEvent(b.win[0])},this.setScrollLeft=function(d,c){b.doc.translate.x=d;b.doc.translate.tx=-1*d+\"px\";b.doc.css(g.trstyle,\"translate(\"+b.doc.translate.tx+\",\"+b.doc.translate.ty+\")\");c||b.notifyScrollEvent(b.win[0])})}else this.getScrollTop=\n    function(){return b.docscroll.scrollTop()},this.setScrollTop=function(d){return b.docscroll.scrollTop(d)},this.getScrollLeft=function(){return b.docscroll.scrollLeft()},this.setScrollLeft=function(d){return b.docscroll.scrollLeft(d)};this.getTarget=function(b){return!b?!1:b.target?b.target:b.srcElement?b.srcElement:!1};this.hasParent=function(b,c){if(!b)return!1;for(var f=b.target||b.srcElement||b||!1;f&&f.id!=c;)f=f.parentNode||!1;return!1!==f};var u={thin:1,medium:3,thick:5};this.getOffset=function(){if(b.isfixed)return{top:parseFloat(b.win.css(\"top\")),\n    left:parseFloat(b.win.css(\"left\"))};if(!b.viewport)return b.win.offset();var d=b.win.offset(),c=b.viewport.offset();return{top:d.top-c.top+b.viewport.scrollTop(),left:d.left-c.left+b.viewport.scrollLeft()}};this.updateScrollBar=function(d){if(b.ishwscroll)b.rail.css({height:b.win.innerHeight()}),b.railh&&b.railh.css({width:b.win.innerWidth()});else{var c=b.getOffset(),f=c.top,g=c.left,f=f+l(b.win,\"border-top-width\",!0);b.win.outerWidth();b.win.innerWidth();var g=g+(b.rail.align?b.win.outerWidth()-\n    l(b.win,\"border-right-width\")-b.rail.width:l(b.win,\"border-left-width\")),e=b.opt.railoffset;e&&(e.top&&(f+=e.top),b.rail.align&&e.left&&(g+=e.left));b.locked||b.rail.css({top:f,left:g,height:d?d.h:b.win.innerHeight()});b.zoom&&b.zoom.css({top:f+1,left:1==b.rail.align?g-20:g+b.rail.width+4});b.railh&&!b.locked&&(f=c.top,g=c.left,d=b.railh.align?f+l(b.win,\"border-top-width\",!0)+b.win.innerHeight()-b.railh.height:f+l(b.win,\"border-top-width\",!0),g+=l(b.win,\"border-left-width\"),b.railh.css({top:d,left:g,\n    width:b.railh.width}))}};this.doRailClick=function(d,c,f){var g;b.locked||(b.cancelEvent(d),c?(c=f?b.doScrollLeft:b.doScrollTop,g=f?(d.pageX-b.railh.offset().left-b.cursorwidth/2)*b.scrollratio.x:(d.pageY-b.rail.offset().top-b.cursorheight/2)*b.scrollratio.y,c(g)):(c=f?b.doScrollLeftBy:b.doScrollBy,g=f?b.scroll.x:b.scroll.y,d=f?d.pageX-b.railh.offset().left:d.pageY-b.rail.offset().top,f=f?b.view.w:b.view.h,g>=d?c(f):c(-f)))};b.hasanimationframe=v;b.hascancelanimationframe=w;b.hasanimationframe?b.hascancelanimationframe||\n    (w=function(){b.cancelAnimationFrame=!0}):(v=function(b){return setTimeout(b,15-Math.floor(+new Date/1E3)%16)},w=clearInterval);this.init=function(){b.saved.css=[];if(g.isie7mobile||g.isoperamini)return!0;g.hasmstouch&&b.css(b.ispage?e(\"html\"):b.win,{\"-ms-touch-action\":\"none\"});b.zindex=\"auto\";b.zindex=!b.ispage&&\"auto\"==b.opt.zindex?k()||\"auto\":b.opt.zindex;!b.ispage&&\"auto\"!=b.zindex&&b.zindex>y&&(y=b.zindex);b.isie&&(0==b.zindex&&\"auto\"==b.opt.zindex)&&(b.zindex=\"auto\");if(!b.ispage||!g.cantouch&&\n    !g.isieold&&!g.isie9mobile){var d=b.docscroll;b.ispage&&(d=b.haswrapper?b.win:b.doc);g.isie9mobile||b.css(d,{\"overflow-y\":\"hidden\"});b.ispage&&g.isie7&&(\"BODY\"==b.doc[0].nodeName?b.css(e(\"html\"),{\"overflow-y\":\"hidden\"}):\"HTML\"==b.doc[0].nodeName&&b.css(e(\"body\"),{\"overflow-y\":\"hidden\"}));g.isios&&(!b.ispage&&!b.haswrapper)&&b.css(e(\"body\"),{\"-webkit-overflow-scrolling\":\"touch\"});var c=e(document.createElement(\"div\"));c.css({position:\"relative\",top:0,\"float\":\"right\",width:b.opt.cursorwidth,height:\"0px\",\n    \"background-color\":b.opt.cursorcolor,border:b.opt.cursorborder,\"background-clip\":\"padding-box\",\"-webkit-border-radius\":b.opt.cursorborderradius,\"-moz-border-radius\":b.opt.cursorborderradius,\"border-radius\":b.opt.cursorborderradius});c.hborder=parseFloat(c.outerHeight()-c.innerHeight());b.cursor=c;var f=e(document.createElement(\"div\"));f.attr(\"id\",b.id);f.addClass(\"nicescroll-rails\");var l,h,x=[\"left\",\"right\"],q;for(q in x)h=x[q],(l=b.opt.railpadding[h])?f.css(\"padding-\"+h,l+\"px\"):b.opt.railpadding[h]=\n    0;f.append(c);f.width=Math.max(parseFloat(b.opt.cursorwidth),c.outerWidth())+b.opt.railpadding.left+b.opt.railpadding.right;f.css({width:f.width+\"px\",zIndex:b.zindex,background:b.opt.background,cursor:\"default\"});f.visibility=!0;f.scrollable=!0;f.align=\"left\"==b.opt.railalign?0:1;b.rail=f;c=b.rail.drag=!1;b.opt.boxzoom&&(!b.ispage&&!g.isieold)&&(c=document.createElement(\"div\"),b.bind(c,\"click\",b.doZoom),b.zoom=e(c),b.zoom.css({cursor:\"pointer\",\"z-index\":b.zindex,backgroundImage:\"url(\"+N+\"zoomico.png)\",\n    height:18,width:18,backgroundPosition:\"0px 0px\"}),b.opt.dblclickzoom&&b.bind(b.win,\"dblclick\",b.doZoom),g.cantouch&&b.opt.gesturezoom&&(b.ongesturezoom=function(d){1.5<d.scale&&b.doZoomIn(d);0.8>d.scale&&b.doZoomOut(d);return b.cancelEvent(d)},b.bind(b.win,\"gestureend\",b.ongesturezoom)));b.railh=!1;if(b.opt.horizrailenabled){b.css(d,{\"overflow-x\":\"hidden\"});c=e(document.createElement(\"div\"));c.css({position:\"relative\",top:0,height:b.opt.cursorwidth,width:\"0px\",\"background-color\":b.opt.cursorcolor,\n    border:b.opt.cursorborder,\"background-clip\":\"padding-box\",\"-webkit-border-radius\":b.opt.cursorborderradius,\"-moz-border-radius\":b.opt.cursorborderradius,\"border-radius\":b.opt.cursorborderradius});c.wborder=parseFloat(c.outerWidth()-c.innerWidth());b.cursorh=c;var m=e(document.createElement(\"div\"));m.attr(\"id\",b.id+\"-hr\");m.addClass(\"nicescroll-rails\");m.height=Math.max(parseFloat(b.opt.cursorwidth),c.outerHeight());m.css({height:m.height+\"px\",zIndex:b.zindex,background:b.opt.background});m.append(c);\n    m.visibility=!0;m.scrollable=!0;m.align=\"top\"==b.opt.railvalign?0:1;b.railh=m;b.railh.drag=!1}b.ispage?(f.css({position:\"fixed\",top:\"0px\",height:\"100%\"}),f.align?f.css({right:\"0px\"}):f.css({left:\"0px\"}),b.body.append(f),b.railh&&(m.css({position:\"fixed\",left:\"0px\",width:\"100%\"}),m.align?m.css({bottom:\"0px\"}):m.css({top:\"0px\"}),b.body.append(m))):(b.ishwscroll?(\"static\"==b.win.css(\"position\")&&b.css(b.win,{position:\"relative\"}),d=\"HTML\"==b.win[0].nodeName?b.body:b.win,b.zoom&&(b.zoom.css({position:\"absolute\",\n    top:1,right:0,\"margin-right\":f.width+4}),d.append(b.zoom)),f.css({position:\"absolute\",top:0}),f.align?f.css({right:0}):f.css({left:0}),d.append(f),m&&(m.css({position:\"absolute\",left:0,bottom:0}),m.align?m.css({bottom:0}):m.css({top:0}),d.append(m))):(b.isfixed=\"fixed\"==b.win.css(\"position\"),d=b.isfixed?\"fixed\":\"absolute\",b.isfixed||(b.viewport=b.getViewport(b.win[0])),b.viewport&&(b.body=b.viewport,!1==/fixed|relative|absolute/.test(b.viewport.css(\"position\"))&&b.css(b.viewport,{position:\"relative\"})),\n    f.css({position:d}),b.zoom&&b.zoom.css({position:d}),b.updateScrollBar(),b.body.append(f),b.zoom&&b.body.append(b.zoom),b.railh&&(m.css({position:d}),b.body.append(m))),g.isios&&b.css(b.win,{\"-webkit-tap-highlight-color\":\"rgba(0,0,0,0)\",\"-webkit-touch-callout\":\"none\"}),g.isie&&b.opt.disableoutline&&b.win.attr(\"hideFocus\",\"true\"),g.iswebkit&&b.opt.disableoutline&&b.win.css({outline:\"none\"}));!1===b.opt.autohidemode?(b.autohidedom=!1,b.rail.css({opacity:b.opt.cursoropacitymax}),b.railh&&b.railh.css({opacity:b.opt.cursoropacitymax})):\n    !0===b.opt.autohidemode||\"leave\"===b.opt.autohidemode?(b.autohidedom=e().add(b.rail),g.isie8&&(b.autohidedom=b.autohidedom.add(b.cursor)),b.railh&&(b.autohidedom=b.autohidedom.add(b.railh)),b.railh&&g.isie8&&(b.autohidedom=b.autohidedom.add(b.cursorh))):\"scroll\"==b.opt.autohidemode?(b.autohidedom=e().add(b.rail),b.railh&&(b.autohidedom=b.autohidedom.add(b.railh))):\"cursor\"==b.opt.autohidemode?(b.autohidedom=e().add(b.cursor),b.railh&&(b.autohidedom=b.autohidedom.add(b.cursorh))):\"hidden\"==b.opt.autohidemode&&\n        (b.autohidedom=!1,b.hide(),b.locked=!1);if(g.isie9mobile)b.scrollmom=new J(b),b.onmangotouch=function(d){d=b.getScrollTop();var c=b.getScrollLeft();if(d==b.scrollmom.lastscrolly&&c==b.scrollmom.lastscrollx)return!0;var f=d-b.mangotouch.sy,g=c-b.mangotouch.sx;if(0!=Math.round(Math.sqrt(Math.pow(g,2)+Math.pow(f,2)))){var n=0>f?-1:1,e=0>g?-1:1,k=+new Date;b.mangotouch.lazy&&clearTimeout(b.mangotouch.lazy);80<k-b.mangotouch.tm||b.mangotouch.dry!=n||b.mangotouch.drx!=e?(b.scrollmom.stop(),b.scrollmom.reset(c,\n    d),b.mangotouch.sy=d,b.mangotouch.ly=d,b.mangotouch.sx=c,b.mangotouch.lx=c,b.mangotouch.dry=n,b.mangotouch.drx=e,b.mangotouch.tm=k):(b.scrollmom.stop(),b.scrollmom.update(b.mangotouch.sx-g,b.mangotouch.sy-f),b.mangotouch.tm=k,f=Math.max(Math.abs(b.mangotouch.ly-d),Math.abs(b.mangotouch.lx-c)),b.mangotouch.ly=d,b.mangotouch.lx=c,2<f&&(b.mangotouch.lazy=setTimeout(function(){b.mangotouch.lazy=!1;b.mangotouch.dry=0;b.mangotouch.drx=0;b.mangotouch.tm=0;b.scrollmom.doMomentum(30)},100)))}},f=b.getScrollTop(),\n    m=b.getScrollLeft(),b.mangotouch={sy:f,ly:f,dry:0,sx:m,lx:m,drx:0,lazy:!1,tm:0},b.bind(b.docscroll,\"scroll\",b.onmangotouch);else{if(g.cantouch||b.istouchcapable||b.opt.touchbehavior||g.hasmstouch){b.scrollmom=new J(b);b.ontouchstart=function(d){if(d.pointerType&&2!=d.pointerType)return!1;if(!b.locked){if(g.hasmstouch)for(var c=d.target?d.target:!1;c;){var f=e(c).getNiceScroll();if(0<f.length&&f[0].me==b.me)break;if(0<f.length)return!1;if(\"DIV\"==c.nodeName&&c.id==b.id)break;c=c.parentNode?c.parentNode:\n    !1}b.cancelScroll();if((c=b.getTarget(d))&&/INPUT/i.test(c.nodeName)&&/range/i.test(c.type))return b.stopPropagation(d);!(\"clientX\"in d)&&\"changedTouches\"in d&&(d.clientX=d.changedTouches[0].clientX,d.clientY=d.changedTouches[0].clientY);b.forcescreen&&(f=d,d={original:d.original?d.original:d},d.clientX=f.screenX,d.clientY=f.screenY);b.rail.drag={x:d.clientX,y:d.clientY,sx:b.scroll.x,sy:b.scroll.y,st:b.getScrollTop(),sl:b.getScrollLeft(),pt:2,dl:!1};if(b.ispage||!b.opt.directionlockdeadzone)b.rail.drag.dl=\n    \"f\";else{var f=e(window).width(),n=e(window).height(),k=Math.max(document.body.scrollWidth,document.documentElement.scrollWidth),l=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight),n=Math.max(0,l-n),f=Math.max(0,k-f);b.rail.drag.ck=!b.rail.scrollable&&b.railh.scrollable?0<n?\"v\":!1:b.rail.scrollable&&!b.railh.scrollable?0<f?\"h\":!1:!1;b.rail.drag.ck||(b.rail.drag.dl=\"f\")}b.opt.touchbehavior&&(b.isiframe&&g.isie)&&(f=b.win.position(),b.rail.drag.x+=f.left,b.rail.drag.y+=f.top);\n    b.hasmoving=!1;b.lastmouseup=!1;b.scrollmom.reset(d.clientX,d.clientY);if(!g.cantouch&&!this.istouchcapable&&!g.hasmstouch){if(!c||!/INPUT|SELECT|TEXTAREA/i.test(c.nodeName))return!b.ispage&&g.hasmousecapture&&c.setCapture(),b.opt.touchbehavior?b.cancelEvent(d):b.stopPropagation(d);/SUBMIT|CANCEL|BUTTON/i.test(e(c).attr(\"type\"))&&(pc={tg:c,click:!1},b.preventclick=pc)}}};b.ontouchend=function(d){if(d.pointerType&&2!=d.pointerType)return!1;if(b.rail.drag&&2==b.rail.drag.pt&&(b.scrollmom.doMomentum(),\n    b.rail.drag=!1,b.hasmoving&&(b.hasmoving=!1,b.lastmouseup=!0,b.hideCursor(),g.hasmousecapture&&document.releaseCapture(),!g.cantouch)))return b.cancelEvent(d)};var t=b.opt.touchbehavior&&b.isiframe&&!g.hasmousecapture;b.ontouchmove=function(d,c){if(d.pointerType&&2!=d.pointerType)return!1;if(b.rail.drag&&2==b.rail.drag.pt){if(g.cantouch&&\"undefined\"==typeof d.original)return!0;b.hasmoving=!0;b.preventclick&&!b.preventclick.click&&(b.preventclick.click=b.preventclick.tg.onclick||!1,b.preventclick.tg.onclick=\n    b.onpreventclick);d=e.extend({original:d},d);\"changedTouches\"in d&&(d.clientX=d.changedTouches[0].clientX,d.clientY=d.changedTouches[0].clientY);if(b.forcescreen){var f=d;d={original:d.original?d.original:d};d.clientX=f.screenX;d.clientY=f.screenY}f=ofy=0;if(t&&!c){var n=b.win.position(),f=-n.left;ofy=-n.top}var k=d.clientY+ofy,n=k-b.rail.drag.y,l=d.clientX+f,h=l-b.rail.drag.x,r=b.rail.drag.st-n;b.ishwscroll&&b.opt.bouncescroll?0>r?r=Math.round(r/2):r>b.page.maxh&&(r=b.page.maxh+Math.round((r-b.page.maxh)/\n    2)):(0>r&&(k=r=0),r>b.page.maxh&&(r=b.page.maxh,k=0));if(b.railh&&b.railh.scrollable){var m=b.rail.drag.sl-h;b.ishwscroll&&b.opt.bouncescroll?0>m?m=Math.round(m/2):m>b.page.maxw&&(m=b.page.maxw+Math.round((m-b.page.maxw)/2)):(0>m&&(l=m=0),m>b.page.maxw&&(m=b.page.maxw,l=0))}f=!1;if(b.rail.drag.dl)f=!0,\"v\"==b.rail.drag.dl?m=b.rail.drag.sl:\"h\"==b.rail.drag.dl&&(r=b.rail.drag.st);else{var n=Math.abs(n),h=Math.abs(h),x=b.opt.directionlockdeadzone;if(\"v\"==b.rail.drag.ck){if(n>x&&h<=0.3*n)return b.rail.drag=\n    !1,!0;h>x&&(b.rail.drag.dl=\"f\",e(\"body\").scrollTop(e(\"body\").scrollTop()))}else if(\"h\"==b.rail.drag.ck){if(h>x&&n<=0.3*h)return b.rail.drag=!1,!0;n>x&&(b.rail.drag.dl=\"f\",e(\"body\").scrollLeft(e(\"body\").scrollLeft()))}}b.synched(\"touchmove\",function(){b.rail.drag&&2==b.rail.drag.pt&&(b.prepareTransition&&b.prepareTransition(0),b.rail.scrollable&&b.setScrollTop(r),b.scrollmom.update(l,k),b.railh&&b.railh.scrollable?(b.setScrollLeft(m),b.showCursor(r,m)):b.showCursor(r),g.isie10&&document.selection.clear())});\n    g.ischrome&&b.istouchcapable&&(f=!1);if(f)return b.cancelEvent(d)}}}b.onmousedown=function(d,c){if(!(b.rail.drag&&1!=b.rail.drag.pt)){if(b.locked)return b.cancelEvent(d);b.cancelScroll();b.rail.drag={x:d.clientX,y:d.clientY,sx:b.scroll.x,sy:b.scroll.y,pt:1,hr:!!c};var f=b.getTarget(d);!b.ispage&&g.hasmousecapture&&f.setCapture();b.isiframe&&!g.hasmousecapture&&(b.saved.csspointerevents=b.doc.css(\"pointer-events\"),b.css(b.doc,{\"pointer-events\":\"none\"}));return b.cancelEvent(d)}};b.onmouseup=function(d){if(b.rail.drag&&\n    (g.hasmousecapture&&document.releaseCapture(),b.isiframe&&!g.hasmousecapture&&b.doc.css(\"pointer-events\",b.saved.csspointerevents),1==b.rail.drag.pt))return b.rail.drag=!1,b.cancelEvent(d)};b.onmousemove=function(d){if(b.rail.drag&&1==b.rail.drag.pt){if(g.ischrome&&0==d.which)return b.onmouseup(d);b.cursorfreezed=!0;if(b.rail.drag.hr){b.scroll.x=b.rail.drag.sx+(d.clientX-b.rail.drag.x);0>b.scroll.x&&(b.scroll.x=0);var c=b.scrollvaluemaxw;b.scroll.x>c&&(b.scroll.x=c)}else b.scroll.y=b.rail.drag.sy+\n    (d.clientY-b.rail.drag.y),0>b.scroll.y&&(b.scroll.y=0),c=b.scrollvaluemax,b.scroll.y>c&&(b.scroll.y=c);b.synched(\"mousemove\",function(){b.rail.drag&&1==b.rail.drag.pt&&(b.showCursor(),b.rail.drag.hr?b.doScrollLeft(Math.round(b.scroll.x*b.scrollratio.x),b.opt.cursordragspeed):b.doScrollTop(Math.round(b.scroll.y*b.scrollratio.y),b.opt.cursordragspeed))});return b.cancelEvent(d)}};if(g.cantouch||b.opt.touchbehavior)b.onpreventclick=function(d){if(b.preventclick)return b.preventclick.tg.onclick=b.preventclick.click,\n    b.preventclick=!1,b.cancelEvent(d)},b.bind(b.win,\"mousedown\",b.ontouchstart),b.onclick=g.isios?!1:function(d){return b.lastmouseup?(b.lastmouseup=!1,b.cancelEvent(d)):!0},b.opt.grabcursorenabled&&g.cursorgrabvalue&&(b.css(b.ispage?b.doc:b.win,{cursor:g.cursorgrabvalue}),b.css(b.rail,{cursor:g.cursorgrabvalue}));else{var p=function(d){if(b.selectiondrag){if(d){var c=b.win.outerHeight();d=d.pageY-b.selectiondrag.top;0<d&&d<c&&(d=0);d>=c&&(d-=c);b.selectiondrag.df=d}0!=b.selectiondrag.df&&(b.doScrollBy(2*\n    -Math.floor(b.selectiondrag.df/6)),b.debounced(\"doselectionscroll\",function(){p()},50))}};b.hasTextSelected=\"getSelection\"in document?function(){return 0<document.getSelection().rangeCount}:\"selection\"in document?function(){return\"None\"!=document.selection.type}:function(){return!1};b.onselectionstart=function(d){b.ispage||(b.selectiondrag=b.win.offset())};b.onselectionend=function(d){b.selectiondrag=!1};b.onselectiondrag=function(d){b.selectiondrag&&b.hasTextSelected()&&b.debounced(\"selectionscroll\",\n    function(){p(d)},250)}}g.hasmstouch&&(b.css(b.rail,{\"-ms-touch-action\":\"none\"}),b.css(b.cursor,{\"-ms-touch-action\":\"none\"}),b.bind(b.win,\"MSPointerDown\",b.ontouchstart),b.bind(document,\"MSPointerUp\",b.ontouchend),b.bind(document,\"MSPointerMove\",b.ontouchmove),b.bind(b.cursor,\"MSGestureHold\",function(b){b.preventDefault()}),b.bind(b.cursor,\"contextmenu\",function(b){b.preventDefault()}));this.istouchcapable&&(b.bind(b.win,\"touchstart\",b.ontouchstart),b.bind(document,\"touchend\",b.ontouchend),b.bind(document,\n    \"touchcancel\",b.ontouchend),b.bind(document,\"touchmove\",b.ontouchmove));b.bind(b.cursor,\"mousedown\",b.onmousedown);b.bind(b.cursor,\"mouseup\",b.onmouseup);b.railh&&(b.bind(b.cursorh,\"mousedown\",function(d){b.onmousedown(d,!0)}),b.bind(b.cursorh,\"mouseup\",function(d){if(!(b.rail.drag&&2==b.rail.drag.pt))return b.rail.drag=!1,b.hasmoving=!1,b.hideCursor(),g.hasmousecapture&&document.releaseCapture(),b.cancelEvent(d)}));if(b.opt.cursordragontouch||!g.cantouch&&!b.opt.touchbehavior)b.rail.css({cursor:\"default\"}),\n    b.railh&&b.railh.css({cursor:\"default\"}),b.jqbind(b.rail,\"mouseenter\",function(){b.canshowonmouseevent&&b.showCursor();b.rail.active=!0}),b.jqbind(b.rail,\"mouseleave\",function(){b.rail.active=!1;b.rail.drag||b.hideCursor()}),b.opt.sensitiverail&&(b.bind(b.rail,\"click\",function(d){b.doRailClick(d,!1,!1)}),b.bind(b.rail,\"dblclick\",function(d){b.doRailClick(d,!0,!1)}),b.bind(b.cursor,\"click\",function(d){b.cancelEvent(d)}),b.bind(b.cursor,\"dblclick\",function(d){b.cancelEvent(d)})),b.railh&&(b.jqbind(b.railh,\n    \"mouseenter\",function(){b.canshowonmouseevent&&b.showCursor();b.rail.active=!0}),b.jqbind(b.railh,\"mouseleave\",function(){b.rail.active=!1;b.rail.drag||b.hideCursor()}),b.opt.sensitiverail&&(b.bind(b.railh,\"click\",function(d){b.doRailClick(d,!1,!0)}),b.bind(b.railh,\"dblclick\",function(d){b.doRailClick(d,!0,!0)}),b.bind(b.cursorh,\"click\",function(d){b.cancelEvent(d)}),b.bind(b.cursorh,\"dblclick\",function(d){b.cancelEvent(d)})));!g.cantouch&&!b.opt.touchbehavior?(b.bind(g.hasmousecapture?b.win:document,\n    \"mouseup\",b.onmouseup),b.bind(document,\"mousemove\",b.onmousemove),b.onclick&&b.bind(document,\"click\",b.onclick),!b.ispage&&b.opt.enablescrollonselection&&(b.bind(b.win[0],\"mousedown\",b.onselectionstart),b.bind(document,\"mouseup\",b.onselectionend),b.bind(b.cursor,\"mouseup\",b.onselectionend),b.cursorh&&b.bind(b.cursorh,\"mouseup\",b.onselectionend),b.bind(document,\"mousemove\",b.onselectiondrag)),b.zoom&&(b.jqbind(b.zoom,\"mouseenter\",function(){b.canshowonmouseevent&&b.showCursor();b.rail.active=!0}),\n    b.jqbind(b.zoom,\"mouseleave\",function(){b.rail.active=!1;b.rail.drag||b.hideCursor()}))):(b.bind(g.hasmousecapture?b.win:document,\"mouseup\",b.ontouchend),b.bind(document,\"mousemove\",b.ontouchmove),b.onclick&&b.bind(document,\"click\",b.onclick),b.opt.cursordragontouch&&(b.bind(b.cursor,\"mousedown\",b.onmousedown),b.bind(b.cursor,\"mousemove\",b.onmousemove),b.cursorh&&b.bind(b.cursorh,\"mousedown\",function(d){b.onmousedown(d,!0)}),b.cursorh&&b.bind(b.cursorh,\"mousemove\",b.onmousemove)));b.opt.enablemousewheel&&\n(b.isiframe||b.bind(g.isie&&b.ispage?document:b.win,\"mousewheel\",b.onmousewheel),b.bind(b.rail,\"mousewheel\",b.onmousewheel),b.railh&&b.bind(b.railh,\"mousewheel\",b.onmousewheelhr));!b.ispage&&(!g.cantouch&&!/HTML|BODY/.test(b.win[0].nodeName))&&(b.win.attr(\"tabindex\")||b.win.attr({tabindex:L++}),b.jqbind(b.win,\"focus\",function(d){z=b.getTarget(d).id||!0;b.hasfocus=!0;b.canshowonmouseevent&&b.noticeCursor()}),b.jqbind(b.win,\"blur\",function(d){z=!1;b.hasfocus=!1}),b.jqbind(b.win,\"mouseenter\",function(d){E=\n    b.getTarget(d).id||!0;b.hasmousefocus=!0;b.canshowonmouseevent&&b.noticeCursor()}),b.jqbind(b.win,\"mouseleave\",function(){E=!1;b.hasmousefocus=!1;b.rail.drag||b.hideCursor()}))}b.onkeypress=function(d){if(b.locked&&0==b.page.maxh)return!0;d=d?d:window.e;var c=b.getTarget(d);if(c&&/INPUT|TEXTAREA|SELECT|OPTION/.test(c.nodeName)&&(!c.getAttribute(\"type\")&&!c.type||!/submit|button|cancel/i.tp))return!0;if(b.hasfocus||b.hasmousefocus&&!z||b.ispage&&!z&&!E){c=d.keyCode;if(b.locked&&27!=c)return b.cancelEvent(d);\n    var f=d.ctrlKey||!1,n=d.shiftKey||!1,g=!1;switch(c){case 38:case 63233:b.doScrollBy(72);g=!0;break;case 40:case 63235:b.doScrollBy(-72);g=!0;break;case 37:case 63232:b.railh&&(f?b.doScrollLeft(0):b.doScrollLeftBy(72),g=!0);break;case 39:case 63234:b.railh&&(f?b.doScrollLeft(b.page.maxw):b.doScrollLeftBy(-72),g=!0);break;case 33:case 63276:b.doScrollBy(b.view.h);g=!0;break;case 34:case 63277:b.doScrollBy(-b.view.h);g=!0;break;case 36:case 63273:b.railh&&f?b.doScrollPos(0,0):b.doScrollTo(0);g=!0;break;\n        case 35:case 63275:b.railh&&f?b.doScrollPos(b.page.maxw,b.page.maxh):b.doScrollTo(b.page.maxh);g=!0;break;case 32:b.opt.spacebarenabled&&(n?b.doScrollBy(b.view.h):b.doScrollBy(-b.view.h),g=!0);break;case 27:b.zoomactive&&(b.doZoom(),g=!0)}if(g)return b.cancelEvent(d)}};b.opt.enablekeyboard&&b.bind(document,g.isopera&&!g.isopera12?\"keypress\":\"keydown\",b.onkeypress);b.bind(window,\"resize\",b.lazyResize);b.bind(window,\"orientationchange\",b.lazyResize);b.bind(window,\"load\",b.lazyResize);if(g.ischrome&&\n    !b.ispage&&!b.haswrapper){var s=b.win.attr(\"style\"),f=parseFloat(b.win.css(\"width\"))+1;b.win.css(\"width\",f);b.synched(\"chromefix\",function(){b.win.attr(\"style\",s)})}b.onAttributeChange=function(d){b.lazyResize(250)};!b.ispage&&!b.haswrapper&&(!1!==A?(b.observer=new A(function(d){d.forEach(b.onAttributeChange)}),b.observer.observe(b.win[0],{childList:!0,characterData:!1,attributes:!0,subtree:!1}),b.observerremover=new A(function(d){d.forEach(function(d){if(0<d.removedNodes.length)for(var c in d.removedNodes)if(d.removedNodes[c]==\n    b.win[0])return b.remove()})}),b.observerremover.observe(b.win[0].parentNode,{childList:!0,characterData:!1,attributes:!1,subtree:!1})):(b.bind(b.win,g.isie&&!g.isie9?\"propertychange\":\"DOMAttrModified\",b.onAttributeChange),g.isie9&&b.win[0].attachEvent(\"onpropertychange\",b.onAttributeChange),b.bind(b.win,\"DOMNodeRemoved\",function(d){d.target==b.win[0]&&b.remove()})));!b.ispage&&b.opt.boxzoom&&b.bind(window,\"resize\",b.resizeZoom);b.istextarea&&b.bind(b.win,\"mouseup\",b.lazyResize);b.checkrtlmode=!0;\n    b.lazyResize(30)}if(\"IFRAME\"==this.doc[0].nodeName){var K=function(d){b.iframexd=!1;try{var c=\"contentDocument\"in this?this.contentDocument:this.contentWindow.document}catch(f){b.iframexd=!0,c=!1}if(b.iframexd)return\"console\"in window&&console.log(\"NiceScroll error: policy restriced iframe\"),!0;b.forcescreen=!0;b.isiframe&&(b.iframe={doc:e(c),html:b.doc.contents().find(\"html\")[0],body:b.doc.contents().find(\"body\")[0]},b.getContentSize=function(){return{w:Math.max(b.iframe.html.scrollWidth,b.iframe.body.scrollWidth),\n    h:Math.max(b.iframe.html.scrollHeight,b.iframe.body.scrollHeight)}},b.docscroll=e(b.iframe.body));!g.isios&&(b.opt.iframeautoresize&&!b.isiframe)&&(b.win.scrollTop(0),b.doc.height(\"\"),d=Math.max(c.getElementsByTagName(\"html\")[0].scrollHeight,c.body.scrollHeight),b.doc.height(d));b.lazyResize(30);g.isie7&&b.css(e(b.iframe.html),{\"overflow-y\":\"hidden\"});b.css(e(b.iframe.body),{\"overflow-y\":\"hidden\"});g.isios&&b.haswrapper&&b.css(e(c.body),{\"-webkit-transform\":\"translate3d(0,0,0)\"});\"contentWindow\"in\n    this?b.bind(this.contentWindow,\"scroll\",b.onscroll):b.bind(c,\"scroll\",b.onscroll);b.opt.enablemousewheel&&b.bind(c,\"mousewheel\",b.onmousewheel);b.opt.enablekeyboard&&b.bind(c,g.isopera?\"keypress\":\"keydown\",b.onkeypress);if(g.cantouch||b.opt.touchbehavior)b.bind(c,\"mousedown\",b.ontouchstart),b.bind(c,\"mousemove\",function(d){b.ontouchmove(d,!0)}),b.opt.grabcursorenabled&&g.cursorgrabvalue&&b.css(e(c.body),{cursor:g.cursorgrabvalue});b.bind(c,\"mouseup\",b.ontouchend);b.zoom&&(b.opt.dblclickzoom&&b.bind(c,\n    \"dblclick\",b.doZoom),b.ongesturezoom&&b.bind(c,\"gestureend\",b.ongesturezoom))};this.doc[0].readyState&&\"complete\"==this.doc[0].readyState&&setTimeout(function(){K.call(b.doc[0],!1)},500);b.bind(this.doc,\"load\",K)}};this.showCursor=function(d,c){b.cursortimeout&&(clearTimeout(b.cursortimeout),b.cursortimeout=0);if(b.rail){b.autohidedom&&(b.autohidedom.stop().css({opacity:b.opt.cursoropacitymax}),b.cursoractive=!0);if(!b.rail.drag||1!=b.rail.drag.pt)\"undefined\"!=typeof d&&!1!==d&&(b.scroll.y=Math.round(1*\n    d/b.scrollratio.y)),\"undefined\"!=typeof c&&(b.scroll.x=Math.round(1*c/b.scrollratio.x));b.cursor.css({height:b.cursorheight,top:b.scroll.y});b.cursorh&&(!b.rail.align&&b.rail.visibility?b.cursorh.css({width:b.cursorwidth,left:b.scroll.x+b.rail.width}):b.cursorh.css({width:b.cursorwidth,left:b.scroll.x}),b.cursoractive=!0);b.zoom&&b.zoom.stop().css({opacity:b.opt.cursoropacitymax})}};this.hideCursor=function(d){!b.cursortimeout&&(b.rail&&b.autohidedom&&!(b.hasmousefocus&&\"leave\"==b.opt.autohidemode))&&\n(b.cursortimeout=setTimeout(function(){if(!b.rail.active||!b.showonmouseevent)b.autohidedom.stop().animate({opacity:b.opt.cursoropacitymin}),b.zoom&&b.zoom.stop().animate({opacity:b.opt.cursoropacitymin}),b.cursoractive=!1;b.cursortimeout=0},d||b.opt.hidecursordelay))};this.noticeCursor=function(d,c,f){b.showCursor(c,f);b.rail.active||b.hideCursor(d)};this.getContentSize=b.ispage?function(){return{w:Math.max(document.body.scrollWidth,document.documentElement.scrollWidth),h:Math.max(document.body.scrollHeight,\n    document.documentElement.scrollHeight)}}:b.haswrapper?function(){return{w:b.doc.outerWidth()+parseInt(b.win.css(\"paddingLeft\"))+parseInt(b.win.css(\"paddingRight\")),h:b.doc.outerHeight()+parseInt(b.win.css(\"paddingTop\"))+parseInt(b.win.css(\"paddingBottom\"))}}:function(){return{w:b.docscroll[0].scrollWidth,h:b.docscroll[0].scrollHeight}};this.onResize=function(d,c){if(!b.win)return!1;if(!b.haswrapper&&!b.ispage){if(\"none\"==b.win.css(\"display\"))return b.visibility&&b.hideRail().hideRailHr(),!1;!b.hidden&&\n    !b.visibility&&b.showRail().showRailHr()}var f=b.page.maxh,g=b.page.maxw,e=b.view.w;b.view={w:b.ispage?b.win.width():parseInt(b.win[0].clientWidth),h:b.ispage?b.win.height():parseInt(b.win[0].clientHeight)};b.page=c?c:b.getContentSize();b.page.maxh=Math.max(0,b.page.h-b.view.h);b.page.maxw=Math.max(0,b.page.w-b.view.w);if(b.page.maxh==f&&b.page.maxw==g&&b.view.w==e){if(b.ispage)return b;f=b.win.offset();if(b.lastposition&&(g=b.lastposition,g.top==f.top&&g.left==f.left))return b;b.lastposition=f}0==\n    b.page.maxh?(b.hideRail(),b.scrollvaluemax=0,b.scroll.y=0,b.scrollratio.y=0,b.cursorheight=0,b.setScrollTop(0),b.rail.scrollable=!1):b.rail.scrollable=!0;0==b.page.maxw?(b.hideRailHr(),b.scrollvaluemaxw=0,b.scroll.x=0,b.scrollratio.x=0,b.cursorwidth=0,b.setScrollLeft(0),b.railh.scrollable=!1):b.railh.scrollable=!0;b.locked=0==b.page.maxh&&0==b.page.maxw;if(b.locked)return b.ispage||b.updateScrollBar(b.view),!1;!b.hidden&&!b.visibility?b.showRail().showRailHr():!b.hidden&&!b.railh.visibility&&b.showRailHr();\n    b.istextarea&&(b.win.css(\"resize\")&&\"none\"!=b.win.css(\"resize\"))&&(b.view.h-=20);b.cursorheight=Math.min(b.view.h,Math.round(b.view.h*(b.view.h/b.page.h)));b.cursorheight=b.opt.cursorfixedheight?b.opt.cursorfixedheight:Math.max(b.opt.cursorminheight,b.cursorheight);b.cursorwidth=Math.min(b.view.w,Math.round(b.view.w*(b.view.w/b.page.w)));b.cursorwidth=b.opt.cursorfixedheight?b.opt.cursorfixedheight:Math.max(b.opt.cursorminheight,b.cursorwidth);b.scrollvaluemax=b.view.h-b.cursorheight-b.cursor.hborder;\n    b.railh&&(b.railh.width=0<b.page.maxh?b.view.w-b.rail.width:b.view.w,b.scrollvaluemaxw=b.railh.width-b.cursorwidth-b.cursorh.wborder);b.checkrtlmode&&b.railh&&(b.checkrtlmode=!1,b.opt.rtlmode&&0==b.scroll.x&&b.setScrollLeft(b.page.maxw));b.ispage||b.updateScrollBar(b.view);b.scrollratio={x:b.page.maxw/b.scrollvaluemaxw,y:b.page.maxh/b.scrollvaluemax};b.getScrollTop()>b.page.maxh?b.doScrollTop(b.page.maxh):(b.scroll.y=Math.round(b.getScrollTop()*(1/b.scrollratio.y)),b.scroll.x=Math.round(b.getScrollLeft()*\n        (1/b.scrollratio.x)),b.cursoractive&&b.noticeCursor());b.scroll.y&&0==b.getScrollTop()&&b.doScrollTo(Math.floor(b.scroll.y*b.scrollratio.y));return b};this.resize=b.onResize;this.lazyResize=function(d){d=isNaN(d)?30:d;b.delayed(\"resize\",b.resize,d);return b};this._bind=function(d,c,f,g){b.events.push({e:d,n:c,f:f,b:g,q:!1});d.addEventListener?d.addEventListener(c,f,g||!1):d.attachEvent?d.attachEvent(\"on\"+c,f):d[\"on\"+c]=f};this.jqbind=function(d,c,f){b.events.push({e:d,n:c,f:f,q:!0});e(d).bind(c,f)};\n    this.bind=function(d,c,f,e){var k=\"jquery\"in d?d[0]:d;\"mousewheel\"==c?\"onwheel\"in b.win?b._bind(k,\"wheel\",f,e||!1):(d=\"undefined\"!=typeof document.onmousewheel?\"mousewheel\":\"DOMMouseScroll\",q(k,d,f,e||!1),\"DOMMouseScroll\"==d&&q(k,\"MozMousePixelScroll\",f,e||!1)):k.addEventListener?(g.cantouch&&/mouseup|mousedown|mousemove/.test(c)&&b._bind(k,\"mousedown\"==c?\"touchstart\":\"mouseup\"==c?\"touchend\":\"touchmove\",function(b){if(b.touches){if(2>b.touches.length){var d=b.touches.length?b.touches[0]:b;d.original=\n        b;f.call(this,d)}}else b.changedTouches&&(d=b.changedTouches[0],d.original=b,f.call(this,d))},e||!1),b._bind(k,c,f,e||!1),g.cantouch&&\"mouseup\"==c&&b._bind(k,\"touchcancel\",f,e||!1)):b._bind(k,c,function(d){if((d=d||window.event||!1)&&d.srcElement)d.target=d.srcElement;\"pageY\"in d||(d.pageX=d.clientX+document.documentElement.scrollLeft,d.pageY=d.clientY+document.documentElement.scrollTop);return!1===f.call(k,d)||!1===e?b.cancelEvent(d):!0})};this._unbind=function(b,c,f,g){b.removeEventListener?b.removeEventListener(c,\n        f,g):b.detachEvent?b.detachEvent(\"on\"+c,f):b[\"on\"+c]=!1};this.unbindAll=function(){for(var d=0;d<b.events.length;d++){var c=b.events[d];c.q?c.e.unbind(c.n,c.f):b._unbind(c.e,c.n,c.f,c.b)}};this.cancelEvent=function(b){b=b.original?b.original:b?b:window.event||!1;if(!b)return!1;b.preventDefault&&b.preventDefault();b.stopPropagation&&b.stopPropagation();b.preventManipulation&&b.preventManipulation();b.cancelBubble=!0;b.cancel=!0;return b.returnValue=!1};this.stopPropagation=function(b){b=b.original?\n        b.original:b?b:window.event||!1;if(!b)return!1;if(b.stopPropagation)return b.stopPropagation();b.cancelBubble&&(b.cancelBubble=!0);return!1};this.showRail=function(){if(0!=b.page.maxh&&(b.ispage||\"none\"!=b.win.css(\"display\")))b.visibility=!0,b.rail.visibility=!0,b.rail.css(\"display\",\"block\");return b};this.showRailHr=function(){if(!b.railh)return b;if(0!=b.page.maxw&&(b.ispage||\"none\"!=b.win.css(\"display\")))b.railh.visibility=!0,b.railh.css(\"display\",\"block\");return b};this.hideRail=function(){b.visibility=\n        !1;b.rail.visibility=!1;b.rail.css(\"display\",\"none\");return b};this.hideRailHr=function(){if(!b.railh)return b;b.railh.visibility=!1;b.railh.css(\"display\",\"none\");return b};this.show=function(){b.hidden=!1;b.locked=!1;return b.showRail().showRailHr()};this.hide=function(){b.hidden=!0;b.locked=!0;return b.hideRail().hideRailHr()};this.toggle=function(){return b.hidden?b.show():b.hide()};this.remove=function(){b.stop();b.cursortimeout&&clearTimeout(b.cursortimeout);b.doZoomOut();b.unbindAll();g.isie9&&\n    b.win[0].detachEvent(\"onpropertychange\",b.onAttributeChange);!1!==b.observer&&b.observer.disconnect();!1!==b.observerremover&&b.observerremover.disconnect();b.events=null;b.cursor&&b.cursor.remove();b.cursorh&&b.cursorh.remove();b.rail&&b.rail.remove();b.railh&&b.railh.remove();b.zoom&&b.zoom.remove();for(var d=0;d<b.saved.css.length;d++){var c=b.saved.css[d];c[0].css(c[1],\"undefined\"==typeof c[2]?\"\":c[2])}b.saved=!1;b.me.data(\"__nicescroll\",\"\");var f=e.nicescroll;f.each(function(d){if(this&&this.id===\n        b.id){delete f[d];for(var c=++d;c<f.length;c++,d++)f[d]=f[c];f.length--;f.length&&delete f[f.length]}});for(var k in b)b[k]=null,delete b[k];b=null};this.scrollstart=function(d){this.onscrollstart=d;return b};this.scrollend=function(d){this.onscrollend=d;return b};this.scrollcancel=function(d){this.onscrollcancel=d;return b};this.zoomin=function(d){this.onzoomin=d;return b};this.zoomout=function(d){this.onzoomout=d;return b};this.isScrollable=function(b){b=b.target?b.target:b;if(\"OPTION\"==b.nodeName)return!0;\n        for(;b&&1==b.nodeType&&!/BODY|HTML/.test(b.nodeName);){var c=e(b),c=c.css(\"overflowY\")||c.css(\"overflowX\")||c.css(\"overflow\")||\"\";if(/scroll|auto/.test(c))return b.clientHeight!=b.scrollHeight;b=b.parentNode?b.parentNode:!1}return!1};this.getViewport=function(b){for(b=b&&b.parentNode?b.parentNode:!1;b&&1==b.nodeType&&!/BODY|HTML/.test(b.nodeName);){var c=e(b);if(/fixed|absolute/.test(c.css(\"position\")))return c;var f=c.css(\"overflowY\")||c.css(\"overflowX\")||c.css(\"overflow\")||\"\";if(/scroll|auto/.test(f)&&\n        b.clientHeight!=b.scrollHeight||0<c.getNiceScroll().length)return c;b=b.parentNode?b.parentNode:!1}return!1};this.onmousewheel=function(d){if(b.locked)return b.debounced(\"checkunlock\",b.resize,250),!0;if(b.rail.drag)return b.cancelEvent(d);\"auto\"==b.opt.oneaxismousemode&&0!=d.deltaX&&(b.opt.oneaxismousemode=!1);if(b.opt.oneaxismousemode&&0==d.deltaX&&!b.rail.scrollable)return b.railh&&b.railh.scrollable?b.onmousewheelhr(d):!0;var c=+new Date,f=!1;b.opt.preservenativescrolling&&b.checkarea+600<c&&\n    (b.nativescrollingarea=b.isScrollable(d),f=!0);b.checkarea=c;if(b.nativescrollingarea)return!0;if(d=t(d,!1,f))b.checkarea=0;return d};this.onmousewheelhr=function(d){if(b.locked||!b.railh.scrollable)return!0;if(b.rail.drag)return b.cancelEvent(d);var c=+new Date,f=!1;b.opt.preservenativescrolling&&b.checkarea+600<c&&(b.nativescrollingarea=b.isScrollable(d),f=!0);b.checkarea=c;return b.nativescrollingarea?!0:b.locked?b.cancelEvent(d):t(d,!0,f)};this.stop=function(){b.cancelScroll();b.scrollmon&&b.scrollmon.stop();\n        b.cursorfreezed=!1;b.scroll.y=Math.round(b.getScrollTop()*(1/b.scrollratio.y));b.noticeCursor();return b};this.getTransitionSpeed=function(d){var c=Math.round(10*b.opt.scrollspeed);d=Math.min(c,Math.round(d/20*b.opt.scrollspeed));return 20<d?d:0};b.opt.smoothscroll?b.ishwscroll&&g.hastransition&&b.opt.usetransition?(this.prepareTransition=function(d,c){var f=c?20<d?d:0:b.getTransitionSpeed(d),e=f?g.prefixstyle+\"transform \"+f+\"ms ease-out\":\"\";if(!b.lasttransitionstyle||b.lasttransitionstyle!=e)b.lasttransitionstyle=\n        e,b.doc.css(g.transitionstyle,e);return f},this.doScrollLeft=function(c,g){var f=b.scrollrunning?b.newscrolly:b.getScrollTop();b.doScrollPos(c,f,g)},this.doScrollTop=function(c,g){var f=b.scrollrunning?b.newscrollx:b.getScrollLeft();b.doScrollPos(f,c,g)},this.doScrollPos=function(c,e,f){var k=b.getScrollTop(),l=b.getScrollLeft();(0>(b.newscrolly-k)*(e-k)||0>(b.newscrollx-l)*(c-l))&&b.cancelScroll();!1==b.opt.bouncescroll&&(0>e?e=0:e>b.page.maxh&&(e=b.page.maxh),0>c?c=0:c>b.page.maxw&&(c=b.page.maxw));\n        if(b.scrollrunning&&c==b.newscrollx&&e==b.newscrolly)return!1;b.newscrolly=e;b.newscrollx=c;b.newscrollspeed=f||!1;if(b.timer)return!1;b.timer=setTimeout(function(){var f=b.getScrollTop(),k=b.getScrollLeft(),l,h;l=c-k;h=e-f;l=Math.round(Math.sqrt(Math.pow(l,2)+Math.pow(h,2)));l=b.newscrollspeed&&1<b.newscrollspeed?b.newscrollspeed:b.getTransitionSpeed(l);b.newscrollspeed&&1>=b.newscrollspeed&&(l*=b.newscrollspeed);b.prepareTransition(l,!0);b.timerscroll&&b.timerscroll.tm&&clearInterval(b.timerscroll.tm);\n            0<l&&(!b.scrollrunning&&b.onscrollstart&&b.onscrollstart.call(b,{type:\"scrollstart\",current:{x:k,y:f},request:{x:c,y:e},end:{x:b.newscrollx,y:b.newscrolly},speed:l}),g.transitionend?b.scrollendtrapped||(b.scrollendtrapped=!0,b.bind(b.doc,g.transitionend,b.onScrollEnd,!1)):(b.scrollendtrapped&&clearTimeout(b.scrollendtrapped),b.scrollendtrapped=setTimeout(b.onScrollEnd,l)),b.timerscroll={bz:new BezierClass(f,b.newscrolly,l,0,0,0.58,1),bh:new BezierClass(k,b.newscrollx,l,0,0,0.58,1)},b.cursorfreezed||\n                (b.timerscroll.tm=setInterval(function(){b.showCursor(b.getScrollTop(),b.getScrollLeft())},60)));b.synched(\"doScroll-set\",function(){b.timer=0;b.scrollendtrapped&&(b.scrollrunning=!0);b.setScrollTop(b.newscrolly);b.setScrollLeft(b.newscrollx);if(!b.scrollendtrapped)b.onScrollEnd()})},50)},this.cancelScroll=function(){if(!b.scrollendtrapped)return!0;var c=b.getScrollTop(),e=b.getScrollLeft();b.scrollrunning=!1;g.transitionend||clearTimeout(g.transitionend);b.scrollendtrapped=!1;b._unbind(b.doc,g.transitionend,\n        b.onScrollEnd);b.prepareTransition(0);b.setScrollTop(c);b.railh&&b.setScrollLeft(e);b.timerscroll&&b.timerscroll.tm&&clearInterval(b.timerscroll.tm);b.timerscroll=!1;b.cursorfreezed=!1;b.showCursor(c,e);return b},this.onScrollEnd=function(){b.scrollendtrapped&&b._unbind(b.doc,g.transitionend,b.onScrollEnd);b.scrollendtrapped=!1;b.prepareTransition(0);b.timerscroll&&b.timerscroll.tm&&clearInterval(b.timerscroll.tm);b.timerscroll=!1;var c=b.getScrollTop(),e=b.getScrollLeft();b.setScrollTop(c);b.railh&&\n    b.setScrollLeft(e);b.noticeCursor(!1,c,e);b.cursorfreezed=!1;0>c?c=0:c>b.page.maxh&&(c=b.page.maxh);0>e?e=0:e>b.page.maxw&&(e=b.page.maxw);if(c!=b.newscrolly||e!=b.newscrollx)return b.doScrollPos(e,c,b.opt.snapbackspeed);b.onscrollend&&b.scrollrunning&&b.onscrollend.call(b,{type:\"scrollend\",current:{x:e,y:c},end:{x:b.newscrollx,y:b.newscrolly}});b.scrollrunning=!1}):(this.doScrollLeft=function(c,g){var f=b.scrollrunning?b.newscrolly:b.getScrollTop();b.doScrollPos(c,f,g)},this.doScrollTop=function(c,\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          g){var f=b.scrollrunning?b.newscrollx:b.getScrollLeft();b.doScrollPos(f,c,g)},this.doScrollPos=function(c,g,f){function e(){if(b.cancelAnimationFrame)return!0;b.scrollrunning=!0;if(p=1-p)return b.timer=v(e)||1;var c=0,d=sy=b.getScrollTop();if(b.dst.ay){var d=b.bzscroll?b.dst.py+b.bzscroll.getNow()*b.dst.ay:b.newscrolly,f=d-sy;if(0>f&&d<b.newscrolly||0<f&&d>b.newscrolly)d=b.newscrolly;b.setScrollTop(d);d==b.newscrolly&&(c=1)}else c=1;var g=sx=b.getScrollLeft();if(b.dst.ax){g=b.bzscroll?b.dst.px+b.bzscroll.getNow()*\n        b.dst.ax:b.newscrollx;f=g-sx;if(0>f&&g<b.newscrollx||0<f&&g>b.newscrollx)g=b.newscrollx;b.setScrollLeft(g);g==b.newscrollx&&(c+=1)}else c+=1;2==c?(b.timer=0,b.cursorfreezed=!1,b.bzscroll=!1,b.scrollrunning=!1,0>d?d=0:d>b.page.maxh&&(d=b.page.maxh),0>g?g=0:g>b.page.maxw&&(g=b.page.maxw),g!=b.newscrollx||d!=b.newscrolly?b.doScrollPos(g,d):b.onscrollend&&b.onscrollend.call(b,{type:\"scrollend\",current:{x:sx,y:sy},end:{x:b.newscrollx,y:b.newscrolly}})):b.timer=v(e)||1}g=\"undefined\"==typeof g||!1===g?b.getScrollTop(!0):\n        g;if(b.timer&&b.newscrolly==g&&b.newscrollx==c)return!0;b.timer&&w(b.timer);b.timer=0;var k=b.getScrollTop(),l=b.getScrollLeft();(0>(b.newscrolly-k)*(g-k)||0>(b.newscrollx-l)*(c-l))&&b.cancelScroll();b.newscrolly=g;b.newscrollx=c;if(!b.bouncescroll||!b.rail.visibility)0>b.newscrolly?b.newscrolly=0:b.newscrolly>b.page.maxh&&(b.newscrolly=b.page.maxh);if(!b.bouncescroll||!b.railh.visibility)0>b.newscrollx?b.newscrollx=0:b.newscrollx>b.page.maxw&&(b.newscrollx=b.page.maxw);b.dst={};b.dst.x=c-l;b.dst.y=\n        g-k;b.dst.px=l;b.dst.py=k;var h=Math.round(Math.sqrt(Math.pow(b.dst.x,2)+Math.pow(b.dst.y,2)));b.dst.ax=b.dst.x/h;b.dst.ay=b.dst.y/h;var m=0,q=h;0==b.dst.x?(m=k,q=g,b.dst.ay=1,b.dst.py=0):0==b.dst.y&&(m=l,q=c,b.dst.ax=1,b.dst.px=0);h=b.getTransitionSpeed(h);f&&1>=f&&(h*=f);b.bzscroll=0<h?b.bzscroll?b.bzscroll.update(q,h):new BezierClass(m,q,h,0,1,0,1):!1;if(!b.timer){(k==b.page.maxh&&g>=b.page.maxh||l==b.page.maxw&&c>=b.page.maxw)&&b.checkContentSize();var p=1;b.cancelAnimationFrame=!1;b.timer=1;\n        b.onscrollstart&&!b.scrollrunning&&b.onscrollstart.call(b,{type:\"scrollstart\",current:{x:l,y:k},request:{x:c,y:g},end:{x:b.newscrollx,y:b.newscrolly},speed:h});e();(k==b.page.maxh&&g>=k||l==b.page.maxw&&c>=l)&&b.checkContentSize();b.noticeCursor()}},this.cancelScroll=function(){b.timer&&w(b.timer);b.timer=0;b.bzscroll=!1;b.scrollrunning=!1;return b}):(this.doScrollLeft=function(c,g){var f=b.getScrollTop();b.doScrollPos(c,f,g)},this.doScrollTop=function(c,g){var f=b.getScrollLeft();b.doScrollPos(f,\n        c,g)},this.doScrollPos=function(c,g,f){var e=c>b.page.maxw?b.page.maxw:c;0>e&&(e=0);var k=g>b.page.maxh?b.page.maxh:g;0>k&&(k=0);b.synched(\"scroll\",function(){b.setScrollTop(k);b.setScrollLeft(e)})},this.cancelScroll=function(){});this.doScrollBy=function(c,g){var f=0,f=g?Math.floor((b.scroll.y-c)*b.scrollratio.y):(b.timer?b.newscrolly:b.getScrollTop(!0))-c;if(b.bouncescroll){var e=Math.round(b.view.h/2);f<-e?f=-e:f>b.page.maxh+e&&(f=b.page.maxh+e)}b.cursorfreezed=!1;py=b.getScrollTop(!0);if(0>f&&\n        0>=py)return b.noticeCursor();if(f>b.page.maxh&&py>=b.page.maxh)return b.checkContentSize(),b.noticeCursor();b.doScrollTop(f)};this.doScrollLeftBy=function(c,g){var f=0,f=g?Math.floor((b.scroll.x-c)*b.scrollratio.x):(b.timer?b.newscrollx:b.getScrollLeft(!0))-c;if(b.bouncescroll){var e=Math.round(b.view.w/2);f<-e?f=-e:f>b.page.maxw+e&&(f=b.page.maxw+e)}b.cursorfreezed=!1;px=b.getScrollLeft(!0);if(0>f&&0>=px||f>b.page.maxw&&px>=b.page.maxw)return b.noticeCursor();b.doScrollLeft(f)};this.doScrollTo=\n        function(c,g){g&&Math.round(c*b.scrollratio.y);b.cursorfreezed=!1;b.doScrollTop(c)};this.checkContentSize=function(){var c=b.getContentSize();(c.h!=b.page.h||c.w!=b.page.w)&&b.resize(!1,c)};b.onscroll=function(c){b.rail.drag||b.cursorfreezed||b.synched(\"scroll\",function(){b.scroll.y=Math.round(b.getScrollTop()*(1/b.scrollratio.y));b.railh&&(b.scroll.x=Math.round(b.getScrollLeft()*(1/b.scrollratio.x)));b.noticeCursor()})};b.bind(b.docscroll,\"scroll\",b.onscroll);this.doZoomIn=function(c){if(!b.zoomactive){b.zoomactive=\n        !0;b.zoomrestore={style:{}};var k=\"position top left zIndex backgroundColor marginTop marginBottom marginLeft marginRight\".split(\" \"),f=b.win[0].style,l;for(l in k){var h=k[l];b.zoomrestore.style[h]=\"undefined\"!=typeof f[h]?f[h]:\"\"}b.zoomrestore.style.width=b.win.css(\"width\");b.zoomrestore.style.height=b.win.css(\"height\");b.zoomrestore.padding={w:b.win.outerWidth()-b.win.width(),h:b.win.outerHeight()-b.win.height()};g.isios4&&(b.zoomrestore.scrollTop=e(window).scrollTop(),e(window).scrollTop(0));\n        b.win.css({position:g.isios4?\"absolute\":\"fixed\",top:0,left:0,\"z-index\":y+100,margin:\"0px\"});k=b.win.css(\"backgroundColor\");(\"\"==k||/transparent|rgba\\(0, 0, 0, 0\\)|rgba\\(0,0,0,0\\)/.test(k))&&b.win.css(\"backgroundColor\",\"#fff\");b.rail.css({\"z-index\":y+101});b.zoom.css({\"z-index\":y+102});b.zoom.css(\"backgroundPosition\",\"0px -18px\");b.resizeZoom();b.onzoomin&&b.onzoomin.call(b);return b.cancelEvent(c)}};this.doZoomOut=function(c){if(b.zoomactive)return b.zoomactive=!1,b.win.css(\"margin\",\"\"),b.win.css(b.zoomrestore.style),\n        g.isios4&&e(window).scrollTop(b.zoomrestore.scrollTop),b.rail.css({\"z-index\":b.zindex}),b.zoom.css({\"z-index\":b.zindex}),b.zoomrestore=!1,b.zoom.css(\"backgroundPosition\",\"0px 0px\"),b.onResize(),b.onzoomout&&b.onzoomout.call(b),b.cancelEvent(c)};this.doZoom=function(c){return b.zoomactive?b.doZoomOut(c):b.doZoomIn(c)};this.resizeZoom=function(){if(b.zoomactive){var c=b.getScrollTop();b.win.css({width:e(window).width()-b.zoomrestore.padding.w+\"px\",height:e(window).height()-b.zoomrestore.padding.h+\"px\"});\n        b.onResize();b.setScrollTop(Math.min(b.page.maxh,c))}};this.init();e.nicescroll.push(this)},J=function(e){var c=this;this.nc=e;this.steptime=this.lasttime=this.speedy=this.speedx=this.lasty=this.lastx=0;this.snapy=this.snapx=!1;this.demuly=this.demulx=0;this.lastscrolly=this.lastscrollx=-1;this.timer=this.chky=this.chkx=0;this.time=function(){return+new Date};this.reset=function(e,l){c.stop();var h=c.time();c.steptime=0;c.lasttime=h;c.speedx=0;c.speedy=0;c.lastx=e;c.lasty=l;c.lastscrollx=-1;c.lastscrolly=\n    -1};this.update=function(e,l){var h=c.time();c.steptime=h-c.lasttime;c.lasttime=h;var h=l-c.lasty,t=e-c.lastx,b=c.nc.getScrollTop(),p=c.nc.getScrollLeft(),b=b+h,p=p+t;c.snapx=0>p||p>c.nc.page.maxw;c.snapy=0>b||b>c.nc.page.maxh;c.speedx=t;c.speedy=h;c.lastx=e;c.lasty=l};this.stop=function(){c.nc.unsynched(\"domomentum2d\");c.timer&&clearTimeout(c.timer);c.timer=0;c.lastscrollx=-1;c.lastscrolly=-1};this.doSnapy=function(e,l){var h=!1;0>l?(l=0,h=!0):l>c.nc.page.maxh&&(l=c.nc.page.maxh,h=!0);0>e?(e=0,h=\n    !0):e>c.nc.page.maxw&&(e=c.nc.page.maxw,h=!0);h&&c.nc.doScrollPos(e,l,c.nc.opt.snapbackspeed)};this.doMomentum=function(e){var l=c.time(),h=e?l+e:c.lasttime;e=c.nc.getScrollLeft();var t=c.nc.getScrollTop(),b=c.nc.page.maxh,p=c.nc.page.maxw;c.speedx=0<p?Math.min(60,c.speedx):0;c.speedy=0<b?Math.min(60,c.speedy):0;h=h&&60>=l-h;if(0>t||t>b||0>e||e>p)h=!1;e=c.speedx&&h?c.speedx:!1;if(c.speedy&&h&&c.speedy||e){var g=Math.max(16,c.steptime);50<g&&(e=g/50,c.speedx*=e,c.speedy*=e,g=50);c.demulxy=0;c.lastscrollx=\n    c.nc.getScrollLeft();c.chkx=c.lastscrollx;c.lastscrolly=c.nc.getScrollTop();c.chky=c.lastscrolly;var s=c.lastscrollx,u=c.lastscrolly,d=function(){var e=600<c.time()-l?0.04:0.02;if(c.speedx&&(s=Math.floor(c.lastscrollx-c.speedx*(1-c.demulxy)),c.lastscrollx=s,0>s||s>p))e=0.1;if(c.speedy&&(u=Math.floor(c.lastscrolly-c.speedy*(1-c.demulxy)),c.lastscrolly=u,0>u||u>b))e=0.1;c.demulxy=Math.min(1,c.demulxy+e);c.nc.synched(\"domomentum2d\",function(){c.speedx&&(c.nc.getScrollLeft()!=c.chkx&&c.stop(),c.chkx=\n    s,c.nc.setScrollLeft(s));c.speedy&&(c.nc.getScrollTop()!=c.chky&&c.stop(),c.chky=u,c.nc.setScrollTop(u));c.timer||(c.nc.hideCursor(),c.doSnapy(s,u))});1>c.demulxy?c.timer=setTimeout(d,g):(c.stop(),c.nc.hideCursor(),c.doSnapy(s,u))};d()}else c.doSnapy(c.nc.getScrollLeft(),c.nc.getScrollTop())}},B=e.fn.scrollTop;e.cssHooks.pageYOffset={get:function(h,c,k){return(c=e.data(h,\"__nicescroll\")||!1)&&c.ishwscroll?c.getScrollTop():B.call(h)},set:function(h,c){var k=e.data(h,\"__nicescroll\")||!1;k&&k.ishwscroll?\n    k.setScrollTop(parseInt(c)):B.call(h,c);return this}};e.fn.scrollTop=function(h){if(\"undefined\"==typeof h){var c=this[0]?e.data(this[0],\"__nicescroll\")||!1:!1;return c&&c.ishwscroll?c.getScrollTop():B.call(this)}return this.each(function(){var c=e.data(this,\"__nicescroll\")||!1;c&&c.ishwscroll?c.setScrollTop(parseInt(h)):B.call(e(this),h)})};var C=e.fn.scrollLeft;e.cssHooks.pageXOffset={get:function(h,c,k){return(c=e.data(h,\"__nicescroll\")||!1)&&c.ishwscroll?c.getScrollLeft():C.call(h)},set:function(h,\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            c){var k=e.data(h,\"__nicescroll\")||!1;k&&k.ishwscroll?k.setScrollLeft(parseInt(c)):C.call(h,c);return this}};e.fn.scrollLeft=function(h){if(\"undefined\"==typeof h){var c=this[0]?e.data(this[0],\"__nicescroll\")||!1:!1;return c&&c.ishwscroll?c.getScrollLeft():C.call(this)}return this.each(function(){var c=e.data(this,\"__nicescroll\")||!1;c&&c.ishwscroll?c.setScrollLeft(parseInt(h)):C.call(e(this),h)})};var D=function(h){var c=this;this.length=0;this.name=\"nicescrollarray\";this.each=function(e){for(var h=\n    0,k=0;h<c.length;h++)e.call(c[h],k++);return c};this.push=function(e){c[c.length]=e;c.length++};this.eq=function(e){return c[e]};if(h)for(a=0;a<h.length;a++){var k=e.data(h[a],\"__nicescroll\")||!1;k&&(this[this.length]=k,this.length++)}return this};(function(e,c,k){for(var l=0;l<c.length;l++)k(e,c[l])})(D.prototype,\"show hide toggle onResize resize remove stop doScrollPos\".split(\" \"),function(e,c){e[c]=function(){var e=arguments;return this.each(function(){this[c].apply(this,e)})}});e.fn.getNiceScroll=\n    function(h){return\"undefined\"==typeof h?new D(this):this[h]&&e.data(this[h],\"__nicescroll\")||!1};e.extend(e.expr[\":\"],{nicescroll:function(h){return e.data(h,\"__nicescroll\")?!0:!1}});e.fn.niceScroll=function(h,c){\"undefined\"==typeof c&&(\"object\"==typeof h&&!(\"jquery\"in h))&&(c=h,h=!1);var k=new D;\"undefined\"==typeof c&&(c={});h&&(c.doc=e(h),c.win=e(this));var l=!(\"doc\"in c);!l&&!(\"win\"in c)&&(c.win=e(this));this.each(function(){var h=e(this).data(\"__nicescroll\")||!1;h||(c.doc=l?e(this):c.doc,h=new Q(c,\n    e(this)),e(this).data(\"__nicescroll\",h));k.push(h)});return 1==k.length?k[0]:k};window.NiceScroll={getjQuery:function(){return e}};e.nicescroll||(e.nicescroll=new D,e.nicescroll.options=I)})(jQuery);\n"
  },
  {
    "path": "static/assets/js/jquery.slimscroll.js",
    "content": "/*! Copyright (c) 2011 Piotr Rochala (http://rocha.la)\n * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)\n * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.\n *\n * Version: 1.3.6\n *\n */\n(function($) {\n\n  $.fn.extend({\n    slimScroll: function(options) {\n\n      var defaults = {\n\n        // width in pixels of the visible scroll area\n        width : 'auto',\n\n        // height in pixels of the visible scroll area\n        height : '250px',\n\n        // width in pixels of the scrollbar and rail\n        size : '7px',\n\n        // scrollbar color, accepts any hex/color value\n        color: '#000',\n\n        // scrollbar position - left/right\n        position : 'right',\n\n        // distance in pixels between the side edge and the scrollbar\n        distance : '1px',\n\n        // default scroll position on load - top / bottom / $('selector')\n        start : 'top',\n\n        // sets scrollbar opacity\n        opacity : .4,\n\n        // enables always-on mode for the scrollbar\n        alwaysVisible : false,\n\n        // check if we should hide the scrollbar when user is hovering over\n        disableFadeOut : false,\n\n        // sets visibility of the rail\n        railVisible : false,\n\n        // sets rail color\n        railColor : '#333',\n\n        // sets rail opacity\n        railOpacity : .2,\n\n        // whether  we should use jQuery UI Draggable to enable bar dragging\n        railDraggable : true,\n\n        // defautlt CSS class of the slimscroll rail\n        railClass : 'slimScrollRail',\n\n        // defautlt CSS class of the slimscroll bar\n        barClass : 'slimScrollBar',\n\n        // defautlt CSS class of the slimscroll wrapper\n        wrapperClass : 'slimScrollDiv',\n\n        // check if mousewheel should scroll the window if we reach top/bottom\n        allowPageScroll : false,\n\n        // scroll amount applied to each mouse wheel step\n        wheelStep : 20,\n\n        // scroll amount applied when user is using gestures\n        touchScrollStep : 200,\n\n        // sets border radius\n        borderRadius: '7px',\n\n        // sets border radius of the rail\n        railBorderRadius : '7px'\n      };\n\n      var o = $.extend(defaults, options);\n\n      // do it for every element that matches selector\n      this.each(function(){\n\n      var isOverPanel, isOverBar, isDragg, queueHide, touchDif,\n        barHeight, percentScroll, lastScroll,\n        divS = '<div></div>',\n        minBarHeight = 30,\n        releaseScroll = false;\n\n        // used in event handlers and for better minification\n        var me = $(this);\n\n        // ensure we are not binding it again\n        if (me.parent().hasClass(o.wrapperClass))\n        {\n            // start from last bar position\n            var offset = me.scrollTop();\n\n            // find bar and rail\n            bar = me.closest('.' + o.barClass);\n            rail = me.closest('.' + o.railClass);\n\n            getBarHeight();\n\n            // check if we should scroll existing instance\n            if ($.isPlainObject(options))\n            {\n              // Pass height: auto to an existing slimscroll object to force a resize after contents have changed\n              if ( 'height' in options && options.height == 'auto' ) {\n                me.parent().css('height', 'auto');\n                me.css('height', 'auto');\n                var height = me.parent().parent().height();\n                me.parent().css('height', height);\n                me.css('height', height);\n              }\n\n              if ('scrollTo' in options)\n              {\n                // jump to a static point\n                offset = parseInt(o.scrollTo);\n              }\n              else if ('scrollBy' in options)\n              {\n                // jump by value pixels\n                offset += parseInt(o.scrollBy);\n              }\n              else if ('destroy' in options)\n              {\n                // remove slimscroll elements\n                bar.remove();\n                rail.remove();\n                me.unwrap();\n                return;\n              }\n\n              // scroll content by the given offset\n              scrollContent(offset, false, true);\n            }\n\n            return;\n        }\n        else if ($.isPlainObject(options))\n        {\n            if ('destroy' in options)\n            {\n            \treturn;\n            }\n        }\n\n        // optionally set height to the parent's height\n        o.height = (o.height == 'auto') ? me.parent().height() : o.height;\n\n        // wrap content\n        var wrapper = $(divS)\n          .addClass(o.wrapperClass)\n          .css({\n            position: 'relative',\n            overflow: 'hidden',\n            width: o.width,\n            height: o.height\n          });\n\n        // update style for the div\n        me.css({\n          overflow: 'hidden',\n          width: o.width,\n          height: o.height\n        });\n\n        // create scrollbar rail\n        var rail = $(divS)\n          .addClass(o.railClass)\n          .css({\n            width: o.size,\n            height: '100%',\n            position: 'absolute',\n            top: 0,\n            display: (o.alwaysVisible && o.railVisible) ? 'block' : 'none',\n            'border-radius': o.railBorderRadius,\n            background: o.railColor,\n            opacity: o.railOpacity,\n            zIndex: 90\n          });\n\n        // create scrollbar\n        var bar = $(divS)\n          .addClass(o.barClass)\n          .css({\n            background: o.color,\n            width: o.size,\n            position: 'absolute',\n            top: 0,\n            opacity: o.opacity,\n            display: o.alwaysVisible ? 'block' : 'none',\n            'border-radius' : o.borderRadius,\n            BorderRadius: o.borderRadius,\n            MozBorderRadius: o.borderRadius,\n            WebkitBorderRadius: o.borderRadius,\n            zIndex: 99\n          });\n\n        // set position\n        var posCss = (o.position == 'right') ? { right: o.distance } : { left: o.distance };\n        rail.css(posCss);\n        bar.css(posCss);\n\n        // wrap it\n        me.wrap(wrapper);\n\n        // append to parent div\n        me.parent().append(bar);\n        me.parent().append(rail);\n\n        // make it draggable and no longer dependent on the jqueryUI\n        if (o.railDraggable){\n          bar.bind(\"mousedown\", function(e) {\n            var $doc = $(document);\n            isDragg = true;\n            t = parseFloat(bar.css('top'));\n            pageY = e.pageY;\n\n            $doc.bind(\"mousemove.slimscroll\", function(e){\n              currTop = t + e.pageY - pageY;\n              bar.css('top', currTop);\n              scrollContent(0, bar.position().top, false);// scroll content\n            });\n\n            $doc.bind(\"mouseup.slimscroll\", function(e) {\n              isDragg = false;hideBar();\n              $doc.unbind('.slimscroll');\n            });\n            return false;\n          }).bind(\"selectstart.slimscroll\", function(e){\n            e.stopPropagation();\n            e.preventDefault();\n            return false;\n          });\n        }\n\n        // on rail over\n        rail.hover(function(){\n          showBar();\n        }, function(){\n          hideBar();\n        });\n\n        // on bar over\n        bar.hover(function(){\n          isOverBar = true;\n        }, function(){\n          isOverBar = false;\n        });\n\n        // show on parent mouseover\n        me.hover(function(){\n          isOverPanel = true;\n          showBar();\n          hideBar();\n        }, function(){\n          isOverPanel = false;\n          hideBar();\n        });\n\n        // support for mobile\n        me.bind('touchstart', function(e,b){\n          if (e.originalEvent.touches.length)\n          {\n            // record where touch started\n            touchDif = e.originalEvent.touches[0].pageY;\n          }\n        });\n\n        me.bind('touchmove', function(e){\n          // prevent scrolling the page if necessary\n          if(!releaseScroll)\n          {\n  \t\t      e.originalEvent.preventDefault();\n\t\t      }\n          if (e.originalEvent.touches.length)\n          {\n            // see how far user swiped\n            var diff = (touchDif - e.originalEvent.touches[0].pageY) / o.touchScrollStep;\n            // scroll content\n            scrollContent(diff, true);\n            touchDif = e.originalEvent.touches[0].pageY;\n          }\n        });\n\n        // set up initial height\n        getBarHeight();\n\n        // check start position\n        if (o.start === 'bottom')\n        {\n          // scroll content to bottom\n          bar.css({ top: me.outerHeight() - bar.outerHeight() });\n          scrollContent(0, true);\n        }\n        else if (o.start !== 'top')\n        {\n          // assume jQuery selector\n          scrollContent($(o.start).position().top, null, true);\n\n          // make sure bar stays hidden\n          if (!o.alwaysVisible) { bar.hide(); }\n        }\n\n        // attach scroll events\n        attachWheel(this);\n\n        function _onWheel(e)\n        {\n          // use mouse wheel only when mouse is over\n          if (!isOverPanel) { return; }\n\n          var e = e || window.event;\n\n          var delta = 0;\n          if (e.wheelDelta) { delta = -e.wheelDelta/120; }\n          if (e.detail) { delta = e.detail / 3; }\n\n          var target = e.target || e.srcTarget || e.srcElement;\n          if ($(target).closest('.' + o.wrapperClass).is(me.parent())) {\n            // scroll content\n            scrollContent(delta, true);\n          }\n\n          // stop window scroll\n          if (e.preventDefault && !releaseScroll) { e.preventDefault(); }\n          if (!releaseScroll) { e.returnValue = false; }\n        }\n\n        function scrollContent(y, isWheel, isJump)\n        {\n          releaseScroll = false;\n          var delta = y;\n          var maxTop = me.outerHeight() - bar.outerHeight();\n\n          if (isWheel)\n          {\n            // move bar with mouse wheel\n            delta = parseInt(bar.css('top')) + y * parseInt(o.wheelStep) / 100 * bar.outerHeight();\n\n            // move bar, make sure it doesn't go out\n            delta = Math.min(Math.max(delta, 0), maxTop);\n\n            // if scrolling down, make sure a fractional change to the\n            // scroll position isn't rounded away when the scrollbar's CSS is set\n            // this flooring of delta would happened automatically when\n            // bar.css is set below, but we floor here for clarity\n            delta = (y > 0) ? Math.ceil(delta) : Math.floor(delta);\n\n            // scroll the scrollbar\n            bar.css({ top: delta + 'px' });\n          }\n\n          // calculate actual scroll amount\n          percentScroll = parseInt(bar.css('top')) / (me.outerHeight() - bar.outerHeight());\n          delta = percentScroll * (me[0].scrollHeight - me.outerHeight());\n\n          if (isJump)\n          {\n            delta = y;\n            var offsetTop = delta / me[0].scrollHeight * me.outerHeight();\n            offsetTop = Math.min(Math.max(offsetTop, 0), maxTop);\n            bar.css({ top: offsetTop + 'px' });\n          }\n\n          // scroll content\n          me.scrollTop(delta);\n\n          // fire scrolling event\n          me.trigger('slimscrolling', ~~delta);\n\n          // ensure bar is visible\n          showBar();\n\n          // trigger hide when scroll is stopped\n          hideBar();\n        }\n\n        function attachWheel(target)\n        {\n          if (window.addEventListener)\n          {\n            target.addEventListener('DOMMouseScroll', _onWheel, false );\n            target.addEventListener('mousewheel', _onWheel, false );\n          }\n          else\n          {\n            document.attachEvent(\"onmousewheel\", _onWheel)\n          }\n        }\n\n        function getBarHeight()\n        {\n          // calculate scrollbar height and make sure it is not too small\n          barHeight = Math.max((me.outerHeight() / me[0].scrollHeight) * me.outerHeight(), minBarHeight);\n          bar.css({ height: barHeight + 'px' });\n\n          // hide scrollbar if content is not long enough\n          var display = barHeight == me.outerHeight() ? 'none' : 'block';\n          bar.css({ display: display });\n        }\n\n        function showBar()\n        {\n          // recalculate bar height\n          getBarHeight();\n          clearTimeout(queueHide);\n\n          // when bar reached top or bottom\n          if (percentScroll == ~~percentScroll)\n          {\n            //release wheel\n            releaseScroll = o.allowPageScroll;\n\n            // publish approporiate event\n            if (lastScroll != percentScroll)\n            {\n                var msg = (~~percentScroll == 0) ? 'top' : 'bottom';\n                me.trigger('slimscroll', msg);\n            }\n          }\n          else\n          {\n            releaseScroll = false;\n          }\n          lastScroll = percentScroll;\n\n          // show only when required\n          if(barHeight >= me.outerHeight()) {\n            //allow window scroll\n            releaseScroll = true;\n            return;\n          }\n          bar.stop(true,true).fadeIn('fast');\n          if (o.railVisible) { rail.stop(true,true).fadeIn('fast'); }\n        }\n\n        function hideBar()\n        {\n          // only hide when options allow it\n          if (!o.alwaysVisible)\n          {\n            queueHide = setTimeout(function(){\n              if (!(o.disableFadeOut && isOverPanel) && !isOverBar && !isDragg)\n              {\n                bar.fadeOut('slow');\n                rail.fadeOut('slow');\n              }\n            }, 1000);\n          }\n        }\n\n      });\n\n      // maintain chainability\n      return this;\n    }\n  });\n\n  $.fn.extend({\n    slimscroll: $.fn.slimScroll\n  });\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/js/json.js",
    "content": "var formatJson = function(json, options) {\n    var reg = null,\n        formatted = '',\n        pad = 0,\n        PADDING = '    '; // one can also use '\\t' or a different number of spaces\n\n    // optional settings\n    options = options || {};\n    // remove newline where '{' or '[' follows ':'\n    options.newlineAfterColonIfBeforeBraceOrBracket = (options.newlineAfterColonIfBeforeBraceOrBracket === true) ? true : false;\n    // use a space after a colon\n    options.spaceAfterColon = (options.spaceAfterColon === false) ? false : true;\n\n    // begin formatting...\n    if (typeof json !== 'string') {\n        // make sure we start with the JSON as a string\n        json = JSON.stringify(json);\n    } else {\n        // is already a string, so parse and re-stringify in order to remove extra whitespace\n        json = JSON.parse(json);\n        json = JSON.stringify(json);\n    }\n\n    // add newline before and after curly braces\n    reg = /([\\{\\}])/g;\n    json = json.replace(reg, '\\r\\n$1\\r\\n');\n\n    // add newline before and after square brackets\n    reg = /([\\[\\]])/g;\n    json = json.replace(reg, '\\r\\n$1\\r\\n');\n\n    // add newline after comma\n    reg = /(\\,)/g;\n    json = json.replace(reg, '$1\\r\\n');\n\n    // remove multiple newlines\n    reg = /(\\r\\n\\r\\n)/g;\n    json = json.replace(reg, '\\r\\n');\n\n    // remove newlines before commas\n    reg = /\\r\\n\\,/g;\n    json = json.replace(reg, ',');\n\n    // optional formatting...\n    if (!options.newlineAfterColonIfBeforeBraceOrBracket) {\n        reg = /\\:\\r\\n\\{/g;\n        json = json.replace(reg, ':{');\n        reg = /\\:\\r\\n\\[/g;\n        json = json.replace(reg, ':[');\n    }\n    if (options.spaceAfterColon) {\n        reg = /\\:/g;\n        json = json.replace(reg, ': ');\n    }\n\n    $.each(json.split('\\r\\n'), function(index, node) {\n        var i = 0,\n            indent = 0,\n            padding = '';\n\n        if (node.match(/\\{$/) || node.match(/\\[$/)) {\n            indent = 1;\n        } else if (node.match(/\\}/) || node.match(/\\]/)) {\n            if (pad !== 0) {\n                pad -= 1;\n            }\n        } else {\n            indent = 0;\n        }\n\n        for (i = 0; i < pad; i++) {\n            padding += PADDING;\n        }\n\n        formatted += padding + node + '\\r\\n';\n        pad += indent;\n    });\n\n    return formatted;\n};"
  },
  {
    "path": "static/assets/js/json2yaml.js",
    "content": "(function (self) { \n  /*\n   * TODO, lots of concatenation (slow in js)\n   */\n  var spacing = \"  \";\n\n  function getType(obj) {\n    var type = typeof obj;\n    if (obj instanceof Array) {\n      return 'array';\n    } else if (type == 'string') {\n      return 'string';\n    } else if (type == 'boolean') {\n      return 'boolean';\n    } else if (type == 'number') {\n      return 'number';\n    } else if (type == 'undefined' || obj === null) {\n      return 'null';\n    } else {\n      return 'hash';\n    }\n  }\n\n  function convert(obj, ret) {\n    var type = getType(obj);\n\n    switch(type) {\n      case 'array':\n        convertArray(obj, ret);\n        break;\n      case 'hash':\n        convertHash(obj, ret);\n        break;\n      case 'string':\n        convertString(obj, ret);\n        break;\n      case 'null':\n        ret.push('null');\n        break;\n      case 'number':\n        ret.push(obj.toString());\n        break;\n      case 'boolean':\n        ret.push(obj ? 'true' : 'false');\n        break;\n    }\n  }\n\n  function convertArray(obj, ret) {\n    for (var i=0; i<obj.length; i++) {\n      var ele     = obj[i];\n      var recurse = [];\n      convert(ele, recurse);\n\n      for (var j=0; j<recurse.length; j++) {\n        ret.push((j == 0 ? \"- \" : spacing) + recurse[j]);\n      }\n    }\n  }\n\n  function convertHash(obj, ret) {\n    for (var k in obj) {\n      var recurse = [];\n      if (obj.hasOwnProperty(k)) {\n        var ele = obj[k];\n        convert(ele, recurse);\n        var type = getType(ele);\n        if (type == 'string' || type == 'null' || type == 'number' || type == 'boolean') {\n          ret.push(normalizeString(k) + ': ' +  recurse[0]);\n        } else {\n          ret.push(normalizeString(k) + ': ');\n          for (var i=0; i<recurse.length; i++) {\n            ret.push(spacing + recurse[i]);\n          }\n        }\n      }\n    }\n  }\n\n  function normalizeString(str) {\n    if (str.match(/^[\\w]+$/)) {\n      return str;\n    } else {\n      return '\"'+escape(str).replace(/%u/g,'\\\\u').replace(/%U/g,'\\\\U').replace(/%/g,'\\\\x')+'\"';\n    }\n  }\n\n  function convertString(obj, ret) {\n    ret.push(normalizeString(obj));\n  }\n  \n  self.json2yaml = function(obj) {\n    if (typeof obj == 'string') {\n      obj = JSON.parse(obj);\n    }\n\n    var ret = [];\n    convert(obj, ret);\n    return ret.join(\"\\n\");\n  };\n})(this);\n"
  },
  {
    "path": "static/assets/js/npm.js",
    "content": "// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.\nrequire('../../js/transition.js')\nrequire('../../js/alert.js')\nrequire('../../js/button.js')\nrequire('../../js/carousel.js')\nrequire('../../js/collapse.js')\nrequire('../../js/dropdown.js')\nrequire('../../js/modal.js')\nrequire('../../js/tooltip.js')\nrequire('../../js/popover.js')\nrequire('../../js/scrollspy.js')\nrequire('../../js/tab.js')\nrequire('../../js/affix.js')"
  },
  {
    "path": "static/assets/js/spin.js",
    "content": "/**\n * Copyright (c) 2011-2014 Felix Gnass\n * Licensed under the MIT license\n * http://spin.js.org/\n *\n * Example:\n    var opts = {\n      lines: 12,            // The number of lines to draw\n      length: 7,            // The length of each line\n      width: 5,             // The line thickness\n      radius: 10,           // The radius of the inner circle\n      scale: 1.0,           // Scales overall size of the spinner\n      corners: 1,           // Roundness (0..1)\n      color: '#000',        // #rgb or #rrggbb\n      opacity: 1/4,         // Opacity of the lines\n      rotate: 0,            // Rotation offset\n      direction: 1,         // 1: clockwise, -1: counterclockwise\n      speed: 1,             // Rounds per second\n      trail: 100,           // Afterglow percentage\n      fps: 20,              // Frames per second when using setTimeout()\n      zIndex: 2e9,          // Use a high z-index by default\n      className: 'spinner', // CSS class to assign to the element\n      top: '50%',           // center vertically\n      left: '50%',          // center horizontally\n      shadow: false,        // Whether to render a shadow\n      hwaccel: false,       // Whether to use hardware acceleration (might be buggy)\n      position: 'absolute'  // Element positioning\n    };\n    var target = document.getElementById('foo');\n    var spinner = new Spinner(opts).spin(target);\n */\n;(function(root, factory) {\n  if (typeof module == 'object' && module.exports) module.exports = factory(); // CommonJS\n  else if (typeof define == 'function' && define.amd) define(factory); // AMD module\n  else root.Spinner = factory(); // Browser global\n}\n(this, function() {\n  'use strict';\n\n  var prefixes = ['webkit', 'Moz', 'ms', 'O']; // Vendor prefixes\n  var animations = {}; // Animation rules keyed by their name\n  var useCssAnimations; // Whether to use CSS animations or setTimeout\n  var sheet; // A stylesheet to hold the @keyframe or VML rules\n\n  /**\n   * Utility function to create elements. If no tag name is given,\n   * a DIV is created. Optionally properties can be passed.\n   */\n  function createEl(tag, prop) {\n    var el = document.createElement(tag || 'div');\n    var n;\n\n    for (n in prop) el[n] = prop[n];\n    return el;\n  }\n\n  /**\n   * Appends children and returns the parent.\n   */\n  function ins(parent /* child1, child2, ...*/) {\n    for (var i = 1, n = arguments.length; i < n; i++) {\n      parent.appendChild(arguments[i]);\n    }\n\n    return parent;\n  }\n\n  /**\n   * Creates an opacity keyframe animation rule and returns its name.\n   * Since most mobile Webkits have timing issues with animation-delay,\n   * we create separate rules for each line/segment.\n   */\n  function addAnimation(alpha, trail, i, lines) {\n    var name = ['opacity', trail, ~~(alpha * 100), i, lines].join('-');\n    var start = 0.01 + i/lines * 100;\n    var z = Math.max(1 - (1-alpha) / trail * (100-start), alpha);\n    var prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase();\n    var pre = prefix && '-' + prefix + '-' || '';\n\n    if (!animations[name]) {\n      sheet.insertRule(\n        '@' + pre + 'keyframes ' + name + '{' +\n        '0%{opacity:' + z + '}' +\n        start + '%{opacity:' + alpha + '}' +\n        (start+0.01) + '%{opacity:1}' +\n        (start+trail) % 100 + '%{opacity:' + alpha + '}' +\n        '100%{opacity:' + z + '}' +\n        '}', sheet.cssRules.length);\n\n      animations[name] = 1;\n    }\n\n    return name;\n  }\n\n  /**\n   * Tries various vendor prefixes and returns the first supported property.\n   */\n  function vendor(el, prop) {\n    var s = el.style;\n    var pp;\n    var i;\n\n    prop = prop.charAt(0).toUpperCase() + prop.slice(1);\n    if (s[prop] !== undefined) return prop;\n    for (i = 0; i < prefixes.length; i++) {\n      pp = prefixes[i]+prop;\n      if (s[pp] !== undefined) return pp;\n    }\n  }\n\n  /**\n   * Sets multiple style properties at once.\n   */\n  function css(el, prop) {\n    for (var n in prop) {\n      el.style[vendor(el, n) || n] = prop[n];\n    }\n\n    return el;\n  }\n\n  /**\n   * Fills in default values.\n   */\n  function merge(obj) {\n    for (var i = 1; i < arguments.length; i++) {\n      var def = arguments[i];\n      for (var n in def) {\n        if (obj[n] === undefined) obj[n] = def[n];\n      }\n    }\n    return obj;\n  }\n\n  /**\n   * Returns the line color from the given string or array.\n   */\n  function getColor(color, idx) {\n    return typeof color == 'string' ? color : color[idx % color.length];\n  }\n\n  // Built-in defaults\n\n  var defaults = {\n    lines: 12,            // The number of lines to draw\n    length: 7,            // The length of each line\n    width: 5,             // The line thickness\n    radius: 10,           // The radius of the inner circle\n    scale: 1.0,           // Scales overall size of the spinner\n    corners: 1,           // Roundness (0..1)\n    color: '#000',        // #rgb or #rrggbb\n    opacity: 1/4,         // Opacity of the lines\n    rotate: 0,            // Rotation offset\n    direction: 1,         // 1: clockwise, -1: counterclockwise\n    speed: 1,             // Rounds per second\n    trail: 100,           // Afterglow percentage\n    fps: 20,              // Frames per second when using setTimeout()\n    zIndex: 2e9,          // Use a high z-index by default\n    className: 'spinner', // CSS class to assign to the element\n    top: '50%',           // center vertically\n    left: '50%',          // center horizontally\n    shadow: false,        // Whether to render a shadow\n    hwaccel: false,       // Whether to use hardware acceleration\n    position: 'absolute'  // Element positioning\n  };\n\n  /** The constructor */\n  function Spinner(o) {\n    this.opts = merge(o || {}, Spinner.defaults, defaults);\n  }\n\n  // Global defaults that override the built-ins:\n  Spinner.defaults = {};\n\n  merge(Spinner.prototype, {\n    /**\n     * Adds the spinner to the given target element. If this instance is already\n     * spinning, it is automatically removed from its previous target b calling\n     * stop() internally.\n     */\n    spin: function(target) {\n      this.stop();\n\n      var self = this;\n      var o = self.opts;\n      var el = self.el = createEl(null, {className: o.className});\n\n      css(el, {\n        position: o.position,\n        width: 0,\n        zIndex: o.zIndex,\n        left: o.left,\n        top: o.top\n      });\n\n      if (target) {\n        target.insertBefore(el, target.firstChild || null);\n      }\n\n      el.setAttribute('role', 'progressbar');\n      self.lines(el, self.opts);\n\n      if (!useCssAnimations) {\n        // No CSS animation support, use setTimeout() instead\n        var i = 0;\n        var start = (o.lines - 1) * (1 - o.direction) / 2;\n        var alpha;\n        var fps = o.fps;\n        var f = fps / o.speed;\n        var ostep = (1 - o.opacity) / (f * o.trail / 100);\n        var astep = f / o.lines;\n\n        (function anim() {\n          i++;\n          for (var j = 0; j < o.lines; j++) {\n            alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep, o.opacity);\n\n            self.opacity(el, j * o.direction + start, alpha, o);\n          }\n          self.timeout = self.el && setTimeout(anim, ~~(1000 / fps));\n        })();\n      }\n      return self;\n    },\n\n    /**\n     * Stops and removes the Spinner.\n     */\n    stop: function() {\n      var el = this.el;\n      if (el) {\n        clearTimeout(this.timeout);\n        if (el.parentNode) el.parentNode.removeChild(el);\n        this.el = undefined;\n      }\n      return this;\n    },\n\n    /**\n     * Internal method that draws the individual lines. Will be overwritten\n     * in VML fallback mode below.\n     */\n    lines: function(el, o) {\n      var i = 0;\n      var start = (o.lines - 1) * (1 - o.direction) / 2;\n      var seg;\n\n      function fill(color, shadow) {\n        return css(createEl(), {\n          position: 'absolute',\n          width: o.scale * (o.length + o.width) + 'px',\n          height: o.scale * o.width + 'px',\n          background: color,\n          boxShadow: shadow,\n          transformOrigin: 'left',\n          transform: 'rotate(' + ~~(360/o.lines*i + o.rotate) + 'deg) translate(' + o.scale*o.radius + 'px' + ',0)',\n          borderRadius: (o.corners * o.scale * o.width >> 1) + 'px'\n        });\n      }\n\n      for (; i < o.lines; i++) {\n        seg = css(createEl(), {\n          position: 'absolute',\n          top: 1 + ~(o.scale * o.width / 2) + 'px',\n          transform: o.hwaccel ? 'translate3d(0,0,0)' : '',\n          opacity: o.opacity,\n          animation: useCssAnimations && addAnimation(o.opacity, o.trail, start + i * o.direction, o.lines) + ' ' + 1 / o.speed + 's linear infinite'\n        });\n\n        if (o.shadow) ins(seg, css(fill('#000', '0 0 4px #000'), {top: '2px'}));\n        ins(el, ins(seg, fill(getColor(o.color, i), '0 0 1px rgba(0,0,0,.1)')));\n      }\n      return el;\n    },\n\n    /**\n     * Internal method that adjusts the opacity of a single line.\n     * Will be overwritten in VML fallback mode below.\n     */\n    opacity: function(el, i, val) {\n      if (i < el.childNodes.length) el.childNodes[i].style.opacity = val;\n    }\n\n  });\n\n\n  function initVML() {\n\n    /* Utility function to create a VML tag */\n    function vml(tag, attr) {\n      return createEl('<' + tag + ' xmlns=\"urn:schemas-microsoft.com:vml\" class=\"spin-vml\">', attr);\n    }\n\n    // No CSS transforms but VML support, add a CSS rule for VML elements:\n    sheet.addRule('.spin-vml', 'behavior:url(#default#VML)');\n\n    Spinner.prototype.lines = function(el, o) {\n      var r = o.scale * (o.length + o.width);\n      var s = o.scale * 2 * r;\n\n      function grp() {\n        return css(\n          vml('group', {\n            coordsize: s + ' ' + s,\n            coordorigin: -r + ' ' + -r\n          }),\n          { width: s, height: s }\n        );\n      }\n\n      var margin = -(o.width + o.length) * o.scale * 2 + 'px';\n      var g = css(grp(), {position: 'absolute', top: margin, left: margin});\n      var i;\n\n      function seg(i, dx, filter) {\n        ins(\n          g,\n          ins(\n            css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),\n            ins(\n              css(\n                vml('roundrect', {arcsize: o.corners}),\n                {\n                  width: r,\n                  height: o.scale * o.width,\n                  left: o.scale * o.radius,\n                  top: -o.scale * o.width >> 1,\n                  filter: filter\n                }\n              ),\n              vml('fill', {color: getColor(o.color, i), opacity: o.opacity}),\n              vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change\n            )\n          )\n        );\n      }\n\n      if (o.shadow)\n        for (i = 1; i <= o.lines; i++) {\n          seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');\n        }\n\n      for (i = 1; i <= o.lines; i++) seg(i);\n      return ins(el, g);\n    };\n\n    Spinner.prototype.opacity = function(el, i, val, o) {\n      var c = el.firstChild;\n      o = o.shadow && o.lines || 0;\n      if (c && i + o < c.childNodes.length) {\n        c = c.childNodes[i + o]; c = c && c.firstChild; c = c && c.firstChild;\n        if (c) c.opacity = val;\n      }\n    };\n  }\n\n  if (typeof document !== 'undefined') {\n    sheet = (function() {\n      var el = createEl('style', {type : 'text/css'});\n      ins(document.getElementsByTagName('head')[0], el);\n      return el.sheet || el.styleSheet;\n    }());\n\n    var probe = css(createEl('group'), {behavior: 'url(#default#VML)'});\n\n    if (!vendor(probe, 'transform') && probe.adj) initVML();\n    else useCssAnimations = vendor(probe, 'animation');\n  }\n\n  return Spinner;\n\n}));\n"
  },
  {
    "path": "static/assets/js/waves.js",
    "content": "\n\n;(function(window) {\n    'use strict';\n\n    var Waves = Waves || {};\n    var $$ = document.querySelectorAll.bind(document);\n\n    // Find exact position of element\n    function isWindow(obj) {\n        return obj !== null && obj === obj.window;\n    }\n\n    function getWindow(elem) {\n        return isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView;\n    }\n\n    function offset(elem) {\n        var docElem, win,\n            box = {top: 0, left: 0},\n            doc = elem && elem.ownerDocument;\n\n        docElem = doc.documentElement;\n\n        if (typeof elem.getBoundingClientRect !== typeof undefined) {\n            box = elem.getBoundingClientRect();\n        }\n        win = getWindow(doc);\n        return {\n            top: box.top + win.pageYOffset - docElem.clientTop,\n            left: box.left + win.pageXOffset - docElem.clientLeft\n        };\n    }\n\n    function convertStyle(obj) {\n        var style = '';\n\n        for (var a in obj) {\n            if (obj.hasOwnProperty(a)) {\n                style += (a + ':' + obj[a] + ';');\n            }\n        }\n\n        return style;\n    }\n\n    var Effect = {\n\n        // Effect delay\n        duration: 750,\n\n        show: function(e, element) {\n\n            // Disable right click\n            if (e.button === 2) {\n                return false;\n            }\n\n            var el = element || this;\n\n            // Create ripple\n            var ripple = document.createElement('div');\n            ripple.className = 'waves-ripple';\n            el.appendChild(ripple);\n\n            // Get click coordinate and element witdh\n            var pos         = offset(el);\n            var relativeY   = (e.pageY - pos.top);\n            var relativeX   = (e.pageX - pos.left);\n            var scale       = 'scale('+((el.clientWidth / 100) * 10)+')';\n\n            // Support for touch devices\n            if ('touches' in e) {\n              relativeY   = (e.touches[0].pageY - pos.top);\n              relativeX   = (e.touches[0].pageX - pos.left);\n            }\n\n            // Attach data to element\n            ripple.setAttribute('data-hold', Date.now());\n            ripple.setAttribute('data-scale', scale);\n            ripple.setAttribute('data-x', relativeX);\n            ripple.setAttribute('data-y', relativeY);\n\n            // Set ripple position\n            var rippleStyle = {\n                'top': relativeY+'px',\n                'left': relativeX+'px'\n            };\n\n            ripple.className = ripple.className + ' waves-notransition';\n            ripple.setAttribute('style', convertStyle(rippleStyle));\n            ripple.className = ripple.className.replace('waves-notransition', '');\n\n            // Scale the ripple\n            rippleStyle['-webkit-transform'] = scale;\n            rippleStyle['-moz-transform'] = scale;\n            rippleStyle['-ms-transform'] = scale;\n            rippleStyle['-o-transform'] = scale;\n            rippleStyle.transform = scale;\n            rippleStyle.opacity   = '1';\n\n            rippleStyle['-webkit-transition-duration'] = Effect.duration + 'ms';\n            rippleStyle['-moz-transition-duration']    = Effect.duration + 'ms';\n            rippleStyle['-o-transition-duration']      = Effect.duration + 'ms';\n            rippleStyle['transition-duration']         = Effect.duration + 'ms';\n\n            rippleStyle['-webkit-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';\n            rippleStyle['-moz-transition-timing-function']    = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';\n            rippleStyle['-o-transition-timing-function']      = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';\n            rippleStyle['transition-timing-function']         = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';\n\n            ripple.setAttribute('style', convertStyle(rippleStyle));\n        },\n\n        hide: function(e) {\n            TouchHandler.touchup(e);\n\n            var el = this;\n            var width = el.clientWidth * 1.4;\n\n            // Get first ripple\n            var ripple = null;\n            var ripples = el.getElementsByClassName('waves-ripple');\n            if (ripples.length > 0) {\n                ripple = ripples[ripples.length - 1];\n            } else {\n                return false;\n            }\n\n            var relativeX   = ripple.getAttribute('data-x');\n            var relativeY   = ripple.getAttribute('data-y');\n            var scale       = ripple.getAttribute('data-scale');\n\n            // Get delay beetween mousedown and mouse leave\n            var diff = Date.now() - Number(ripple.getAttribute('data-hold'));\n            var delay = 350 - diff;\n\n            if (delay < 0) {\n                delay = 0;\n            }\n\n            // Fade out ripple after delay\n            setTimeout(function() {\n                var style = {\n                    'top': relativeY+'px',\n                    'left': relativeX+'px',\n                    'opacity': '0',\n\n                    // Duration\n                    '-webkit-transition-duration': Effect.duration + 'ms',\n                    '-moz-transition-duration': Effect.duration + 'ms',\n                    '-o-transition-duration': Effect.duration + 'ms',\n                    'transition-duration': Effect.duration + 'ms',\n                    '-webkit-transform': scale,\n                    '-moz-transform': scale,\n                    '-ms-transform': scale,\n                    '-o-transform': scale,\n                    'transform': scale,\n                };\n\n                ripple.setAttribute('style', convertStyle(style));\n\n                setTimeout(function() {\n                    try {\n                        el.removeChild(ripple);\n                    } catch(e) {\n                        return false;\n                    }\n                }, Effect.duration);\n            }, delay);\n        },\n\n        // Little hack to make <input> can perform waves effect\n        wrapInput: function(elements) {\n            for (var a = 0; a < elements.length; a++) {\n                var el = elements[a];\n\n                if (el.tagName.toLowerCase() === 'input') {\n                    var parent = el.parentNode;\n\n                    // If input already have parent just pass through\n                    if (parent.tagName.toLowerCase() === 'i' && parent.className.indexOf('waves-effect') !== -1) {\n                        continue;\n                    }\n\n                    // Put element class and style to the specified parent\n                    var wrapper = document.createElement('i');\n                    wrapper.className = el.className + ' waves-input-wrapper';\n\n                    var elementStyle = el.getAttribute('style');\n\n                    if (!elementStyle) {\n                        elementStyle = '';\n                    }\n\n                    wrapper.setAttribute('style', elementStyle);\n\n                    el.className = 'waves-button-input';\n                    el.removeAttribute('style');\n\n                    // Put element as child\n                    parent.replaceChild(wrapper, el);\n                    wrapper.appendChild(el);\n                }\n            }\n        }\n    };\n\n\n    /**\n     * Disable mousedown event for 500ms during and after touch\n     */\n    var TouchHandler = {\n        /* uses an integer rather than bool so there's no issues with\n         * needing to clear timeouts if another touch event occurred\n         * within the 500ms. Cannot mouseup between touchstart and\n         * touchend, nor in the 500ms after touchend. */\n        touches: 0,\n        allowEvent: function(e) {\n            var allow = true;\n\n            if (e.type === 'touchstart') {\n                TouchHandler.touches += 1; //push\n            } else if (e.type === 'touchend' || e.type === 'touchcancel') {\n                setTimeout(function() {\n                    if (TouchHandler.touches > 0) {\n                        TouchHandler.touches -= 1; //pop after 500ms\n                    }\n                }, 500);\n            } else if (e.type === 'mousedown' && TouchHandler.touches > 0) {\n                allow = false;\n            }\n\n            return allow;\n        },\n        touchup: function(e) {\n            TouchHandler.allowEvent(e);\n        }\n    };\n\n\n    /**\n     * Delegated click handler for .waves-effect element.\n     * returns null when .waves-effect element not in \"click tree\"\n     */\n    function getWavesEffectElement(e) {\n        if (TouchHandler.allowEvent(e) === false) {\n            return null;\n        }\n\n        var element = null;\n        var target = e.target || e.srcElement;\n\n        while (target.parentElement !== null) {\n            if (!(target instanceof SVGElement) && target.className.indexOf('waves-effect') !== -1) {\n                element = target;\n                break;\n            } else if (target.classList.contains('waves-effect')) {\n                element = target;\n                break;\n            }\n            target = target.parentElement;\n        }\n\n        return element;\n    }\n\n    /**\n     * Bubble the click and show effect if .waves-effect elem was found\n     */\n    function showEffect(e) {\n        var element = getWavesEffectElement(e);\n\n        if (element !== null) {\n            Effect.show(e, element);\n\n            if ('ontouchstart' in window) {\n                element.addEventListener('touchend', Effect.hide, false);\n                element.addEventListener('touchcancel', Effect.hide, false);\n            }\n\n            element.addEventListener('mouseup', Effect.hide, false);\n            element.addEventListener('mouseleave', Effect.hide, false);\n        }\n    }\n\n    Waves.displayEffect = function(options) {\n        options = options || {};\n\n        if ('duration' in options) {\n            Effect.duration = options.duration;\n        }\n\n        //Wrap input inside <i> tag\n        Effect.wrapInput($$('.waves-effect'));\n\n        if ('ontouchstart' in window) {\n            document.body.addEventListener('touchstart', showEffect, false);\n        }\n\n        document.body.addEventListener('mousedown', showEffect, false);\n    };\n\n    /**\n     * Attach Waves to an input element (or any element which doesn't\n     * bubble mouseup/mousedown events).\n     *   Intended to be used with dynamically loaded forms/inputs, or\n     * where the user doesn't want a delegated click handler.\n     */\n    Waves.attach = function(element) {\n        //FUTURE: automatically add waves classes and allow users\n        // to specify them with an options param? Eg. light/classic/button\n        if (element.tagName.toLowerCase() === 'input') {\n            Effect.wrapInput([element]);\n            element = element.parentElement;\n        }\n\n        if ('ontouchstart' in window) {\n            element.addEventListener('touchstart', showEffect, false);\n        }\n\n        element.addEventListener('mousedown', showEffect, false);\n    };\n\n    window.Waves = Waves;\n\n    document.addEventListener('DOMContentLoaded', function() {\n        Waves.displayEffect();\n    }, false);\n\n})(window);\n\n/*\nTabs\n*/\n/*! VelocityJS.org (1.2.2). (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License */\n/*! VelocityJS.org jQuery Shim (1.0.1). (C) 2014 The jQuery Foundation. MIT @license: en.wikipedia.org/wiki/MIT_License. */\n!function(e){function t(e){var t=e.length,r=$.type(e);return\"function\"===r||$.isWindow(e)?!1:1===e.nodeType&&t?!0:\"array\"===r||0===t||\"number\"==typeof t&&t>0&&t-1 in e}if(!e.jQuery){var $=function(e,t){return new $.fn.init(e,t)};$.isWindow=function(e){return null!=e&&e==e.window},$.type=function(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?a[o.call(e)]||\"object\":typeof e},$.isArray=Array.isArray||function(e){return\"array\"===$.type(e)},$.isPlainObject=function(e){var t;if(!e||\"object\"!==$.type(e)||e.nodeType||$.isWindow(e))return!1;try{if(e.constructor&&!n.call(e,\"constructor\")&&!n.call(e.constructor.prototype,\"isPrototypeOf\"))return!1}catch(r){return!1}for(t in e);return void 0===t||n.call(e,t)},$.each=function(e,r,a){var n,o=0,i=e.length,s=t(e);if(a){if(s)for(;i>o&&(n=r.apply(e[o],a),n!==!1);o++);else for(o in e)if(n=r.apply(e[o],a),n===!1)break}else if(s)for(;i>o&&(n=r.call(e[o],o,e[o]),n!==!1);o++);else for(o in e)if(n=r.call(e[o],o,e[o]),n===!1)break;return e},$.data=function(e,t,a){if(void 0===a){var n=e[$.expando],o=n&&r[n];if(void 0===t)return o;if(o&&t in o)return o[t]}else if(void 0!==t){var n=e[$.expando]||(e[$.expando]=++$.uuid);return r[n]=r[n]||{},r[n][t]=a,a}},$.removeData=function(e,t){var a=e[$.expando],n=a&&r[a];n&&$.each(t,function(e,t){delete n[t]})},$.extend=function(){var e,t,r,a,n,o,i=arguments[0]||{},s=1,l=arguments.length,u=!1;for(\"boolean\"==typeof i&&(u=i,i=arguments[s]||{},s++),\"object\"!=typeof i&&\"function\"!==$.type(i)&&(i={}),s===l&&(i=this,s--);l>s;s++)if(null!=(n=arguments[s]))for(a in n)e=i[a],r=n[a],i!==r&&(u&&r&&($.isPlainObject(r)||(t=$.isArray(r)))?(t?(t=!1,o=e&&$.isArray(e)?e:[]):o=e&&$.isPlainObject(e)?e:{},i[a]=$.extend(u,o,r)):void 0!==r&&(i[a]=r));return i},$.queue=function(e,r,a){function n(e,r){var a=r||[];return null!=e&&(t(Object(e))?!function(e,t){for(var r=+t.length,a=0,n=e.length;r>a;)e[n++]=t[a++];if(r!==r)for(;void 0!==t[a];)e[n++]=t[a++];return e.length=n,e}(a,\"string\"==typeof e?[e]:e):[].push.call(a,e)),a}if(e){r=(r||\"fx\")+\"queue\";var o=$.data(e,r);return a?(!o||$.isArray(a)?o=$.data(e,r,n(a)):o.push(a),o):o||[]}},$.dequeue=function(e,t){$.each(e.nodeType?[e]:e,function(e,r){t=t||\"fx\";var a=$.queue(r,t),n=a.shift();\"inprogress\"===n&&(n=a.shift()),n&&(\"fx\"===t&&a.unshift(\"inprogress\"),n.call(r,function(){$.dequeue(r,t)}))})},$.fn=$.prototype={init:function(e){if(e.nodeType)return this[0]=e,this;throw new Error(\"Not a DOM node.\")},offset:function(){var t=this[0].getBoundingClientRect?this[0].getBoundingClientRect():{top:0,left:0};return{top:t.top+(e.pageYOffset||document.scrollTop||0)-(document.clientTop||0),left:t.left+(e.pageXOffset||document.scrollLeft||0)-(document.clientLeft||0)}},position:function(){function e(){for(var e=this.offsetParent||document;e&&\"html\"===!e.nodeType.toLowerCase&&\"static\"===e.style.position;)e=e.offsetParent;return e||document}var t=this[0],e=e.apply(t),r=this.offset(),a=/^(?:body|html)$/i.test(e.nodeName)?{top:0,left:0}:$(e).offset();return r.top-=parseFloat(t.style.marginTop)||0,r.left-=parseFloat(t.style.marginLeft)||0,e.style&&(a.top+=parseFloat(e.style.borderTopWidth)||0,a.left+=parseFloat(e.style.borderLeftWidth)||0),{top:r.top-a.top,left:r.left-a.left}}};var r={};$.expando=\"velocity\"+(new Date).getTime(),$.uuid=0;for(var a={},n=a.hasOwnProperty,o=a.toString,i=\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"),s=0;s<i.length;s++)a[\"[object \"+i[s]+\"]\"]=i[s].toLowerCase();$.fn.init.prototype=$.fn,e.Velocity={Utilities:$}}}(window),function(e){\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=e():\"function\"==typeof define&&define.amd?define(e):e()}(function(){return function(e,t,r,a){function n(e){for(var t=-1,r=e?e.length:0,a=[];++t<r;){var n=e[t];n&&a.push(n)}return a}function o(e){return g.isWrapped(e)?e=[].slice.call(e):g.isNode(e)&&(e=[e]),e}function i(e){var t=$.data(e,\"velocity\");return null===t?a:t}function s(e){return function(t){return Math.round(t*e)*(1/e)}}function l(e,r,a,n){function o(e,t){return 1-3*t+3*e}function i(e,t){return 3*t-6*e}function s(e){return 3*e}function l(e,t,r){return((o(t,r)*e+i(t,r))*e+s(t))*e}function u(e,t,r){return 3*o(t,r)*e*e+2*i(t,r)*e+s(t)}function c(t,r){for(var n=0;m>n;++n){var o=u(r,e,a);if(0===o)return r;var i=l(r,e,a)-t;r-=i/o}return r}function p(){for(var t=0;b>t;++t)w[t]=l(t*x,e,a)}function f(t,r,n){var o,i,s=0;do i=r+(n-r)/2,o=l(i,e,a)-t,o>0?n=i:r=i;while(Math.abs(o)>h&&++s<v);return i}function d(t){for(var r=0,n=1,o=b-1;n!=o&&w[n]<=t;++n)r+=x;--n;var i=(t-w[n])/(w[n+1]-w[n]),s=r+i*x,l=u(s,e,a);return l>=y?c(t,s):0==l?s:f(t,r,r+x)}function g(){V=!0,(e!=r||a!=n)&&p()}var m=4,y=.001,h=1e-7,v=10,b=11,x=1/(b-1),S=\"Float32Array\"in t;if(4!==arguments.length)return!1;for(var P=0;4>P;++P)if(\"number\"!=typeof arguments[P]||isNaN(arguments[P])||!isFinite(arguments[P]))return!1;e=Math.min(e,1),a=Math.min(a,1),e=Math.max(e,0),a=Math.max(a,0);var w=S?new Float32Array(b):new Array(b),V=!1,C=function(t){return V||g(),e===r&&a===n?t:0===t?0:1===t?1:l(d(t),r,n)};C.getControlPoints=function(){return[{x:e,y:r},{x:a,y:n}]};var T=\"generateBezier(\"+[e,r,a,n]+\")\";return C.toString=function(){return T},C}function u(e,t){var r=e;return g.isString(e)?v.Easings[e]||(r=!1):r=g.isArray(e)&&1===e.length?s.apply(null,e):g.isArray(e)&&2===e.length?b.apply(null,e.concat([t])):g.isArray(e)&&4===e.length?l.apply(null,e):!1,r===!1&&(r=v.Easings[v.defaults.easing]?v.defaults.easing:h),r}function c(e){if(e){var t=(new Date).getTime(),r=v.State.calls.length;r>1e4&&(v.State.calls=n(v.State.calls));for(var o=0;r>o;o++)if(v.State.calls[o]){var s=v.State.calls[o],l=s[0],u=s[2],f=s[3],d=!!f,m=null;f||(f=v.State.calls[o][3]=t-16);for(var y=Math.min((t-f)/u.duration,1),h=0,b=l.length;b>h;h++){var S=l[h],w=S.element;if(i(w)){var V=!1;if(u.display!==a&&null!==u.display&&\"none\"!==u.display){if(\"flex\"===u.display){var C=[\"-webkit-box\",\"-moz-box\",\"-ms-flexbox\",\"-webkit-flex\"];$.each(C,function(e,t){x.setPropertyValue(w,\"display\",t)})}x.setPropertyValue(w,\"display\",u.display)}u.visibility!==a&&\"hidden\"!==u.visibility&&x.setPropertyValue(w,\"visibility\",u.visibility);for(var T in S)if(\"element\"!==T){var k=S[T],A,F=g.isString(k.easing)?v.Easings[k.easing]:k.easing;if(1===y)A=k.endValue;else{var E=k.endValue-k.startValue;if(A=k.startValue+E*F(y,u,E),!d&&A===k.currentValue)continue}if(k.currentValue=A,\"tween\"===T)m=A;else{if(x.Hooks.registered[T]){var j=x.Hooks.getRoot(T),H=i(w).rootPropertyValueCache[j];H&&(k.rootPropertyValue=H)}var N=x.setPropertyValue(w,T,k.currentValue+(0===parseFloat(A)?\"\":k.unitType),k.rootPropertyValue,k.scrollData);x.Hooks.registered[T]&&(i(w).rootPropertyValueCache[j]=x.Normalizations.registered[j]?x.Normalizations.registered[j](\"extract\",null,N[1]):N[1]),\"transform\"===N[0]&&(V=!0)}}u.mobileHA&&i(w).transformCache.translate3d===a&&(i(w).transformCache.translate3d=\"(0px, 0px, 0px)\",V=!0),V&&x.flushTransformCache(w)}}u.display!==a&&\"none\"!==u.display&&(v.State.calls[o][2].display=!1),u.visibility!==a&&\"hidden\"!==u.visibility&&(v.State.calls[o][2].visibility=!1),u.progress&&u.progress.call(s[1],s[1],y,Math.max(0,f+u.duration-t),f,m),1===y&&p(o)}}v.State.isTicking&&P(c)}function p(e,t){if(!v.State.calls[e])return!1;for(var r=v.State.calls[e][0],n=v.State.calls[e][1],o=v.State.calls[e][2],s=v.State.calls[e][4],l=!1,u=0,c=r.length;c>u;u++){var p=r[u].element;if(t||o.loop||(\"none\"===o.display&&x.setPropertyValue(p,\"display\",o.display),\"hidden\"===o.visibility&&x.setPropertyValue(p,\"visibility\",o.visibility)),o.loop!==!0&&($.queue(p)[1]===a||!/\\.velocityQueueEntryFlag/i.test($.queue(p)[1]))&&i(p)){i(p).isAnimating=!1,i(p).rootPropertyValueCache={};var f=!1;$.each(x.Lists.transforms3D,function(e,t){var r=/^scale/.test(t)?1:0,n=i(p).transformCache[t];i(p).transformCache[t]!==a&&new RegExp(\"^\\\\(\"+r+\"[^.]\").test(n)&&(f=!0,delete i(p).transformCache[t])}),o.mobileHA&&(f=!0,delete i(p).transformCache.translate3d),f&&x.flushTransformCache(p),x.Values.removeClass(p,\"velocity-animating\")}if(!t&&o.complete&&!o.loop&&u===c-1)try{o.complete.call(n,n)}catch(d){setTimeout(function(){throw d},1)}s&&o.loop!==!0&&s(n),i(p)&&o.loop===!0&&!t&&($.each(i(p).tweensContainer,function(e,t){/^rotate/.test(e)&&360===parseFloat(t.endValue)&&(t.endValue=0,t.startValue=360),/^backgroundPosition/.test(e)&&100===parseFloat(t.endValue)&&\"%\"===t.unitType&&(t.endValue=0,t.startValue=100)}),v(p,\"reverse\",{loop:!0,delay:o.delay})),o.queue!==!1&&$.dequeue(p,o.queue)}v.State.calls[e]=!1;for(var g=0,m=v.State.calls.length;m>g;g++)if(v.State.calls[g]!==!1){l=!0;break}l===!1&&(v.State.isTicking=!1,delete v.State.calls,v.State.calls=[])}var f=function(){if(r.documentMode)return r.documentMode;for(var e=7;e>4;e--){var t=r.createElement(\"div\");if(t.innerHTML=\"<!--[if IE \"+e+\"]><span></span><![endif]-->\",t.getElementsByTagName(\"span\").length)return t=null,e}return a}(),d=function(){var e=0;return t.webkitRequestAnimationFrame||t.mozRequestAnimationFrame||function(t){var r=(new Date).getTime(),a;return a=Math.max(0,16-(r-e)),e=r+a,setTimeout(function(){t(r+a)},a)}}(),g={isString:function(e){return\"string\"==typeof e},isArray:Array.isArray||function(e){return\"[object Array]\"===Object.prototype.toString.call(e)},isFunction:function(e){return\"[object Function]\"===Object.prototype.toString.call(e)},isNode:function(e){return e&&e.nodeType},isNodeList:function(e){return\"object\"==typeof e&&/^\\[object (HTMLCollection|NodeList|Object)\\]$/.test(Object.prototype.toString.call(e))&&e.length!==a&&(0===e.length||\"object\"==typeof e[0]&&e[0].nodeType>0)},isWrapped:function(e){return e&&(e.jquery||t.Zepto&&t.Zepto.zepto.isZ(e))},isSVG:function(e){return t.SVGElement&&e instanceof t.SVGElement},isEmptyObject:function(e){for(var t in e)return!1;return!0}},$,m=!1;if(e.fn&&e.fn.jquery?($=e,m=!0):$=t.Velocity.Utilities,8>=f&&!m)throw new Error(\"Velocity: IE8 and below require jQuery to be loaded before Velocity.\");if(7>=f)return void(jQuery.fn.velocity=jQuery.fn.animate);var y=400,h=\"swing\",v={State:{isMobile:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),isAndroid:/Android/i.test(navigator.userAgent),isGingerbread:/Android 2\\.3\\.[3-7]/i.test(navigator.userAgent),isChrome:t.chrome,isFirefox:/Firefox/i.test(navigator.userAgent),prefixElement:r.createElement(\"div\"),prefixMatches:{},scrollAnchor:null,scrollPropertyLeft:null,scrollPropertyTop:null,isTicking:!1,calls:[]},CSS:{},Utilities:$,Redirects:{},Easings:{},Promise:t.Promise,defaults:{queue:\"\",duration:y,easing:h,begin:a,complete:a,progress:a,display:a,visibility:a,loop:!1,delay:!1,mobileHA:!0,_cacheValues:!0},init:function(e){$.data(e,\"velocity\",{isSVG:g.isSVG(e),isAnimating:!1,computedStyle:null,tweensContainer:null,rootPropertyValueCache:{},transformCache:{}})},hook:null,mock:!1,version:{major:1,minor:2,patch:2},debug:!1};t.pageYOffset!==a?(v.State.scrollAnchor=t,v.State.scrollPropertyLeft=\"pageXOffset\",v.State.scrollPropertyTop=\"pageYOffset\"):(v.State.scrollAnchor=r.documentElement||r.body.parentNode||r.body,v.State.scrollPropertyLeft=\"scrollLeft\",v.State.scrollPropertyTop=\"scrollTop\");var b=function(){function e(e){return-e.tension*e.x-e.friction*e.v}function t(t,r,a){var n={x:t.x+a.dx*r,v:t.v+a.dv*r,tension:t.tension,friction:t.friction};return{dx:n.v,dv:e(n)}}function r(r,a){var n={dx:r.v,dv:e(r)},o=t(r,.5*a,n),i=t(r,.5*a,o),s=t(r,a,i),l=1/6*(n.dx+2*(o.dx+i.dx)+s.dx),u=1/6*(n.dv+2*(o.dv+i.dv)+s.dv);return r.x=r.x+l*a,r.v=r.v+u*a,r}return function a(e,t,n){var o={x:-1,v:0,tension:null,friction:null},i=[0],s=0,l=1e-4,u=.016,c,p,f;for(e=parseFloat(e)||500,t=parseFloat(t)||20,n=n||null,o.tension=e,o.friction=t,c=null!==n,c?(s=a(e,t),p=s/n*u):p=u;;)if(f=r(f||o,p),i.push(1+f.x),s+=16,!(Math.abs(f.x)>l&&Math.abs(f.v)>l))break;return c?function(e){return i[e*(i.length-1)|0]}:s}}();v.Easings={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},spring:function(e){return 1-Math.cos(4.5*e*Math.PI)*Math.exp(6*-e)}},$.each([[\"ease\",[.25,.1,.25,1]],[\"ease-in\",[.42,0,1,1]],[\"ease-out\",[0,0,.58,1]],[\"ease-in-out\",[.42,0,.58,1]],[\"easeInSine\",[.47,0,.745,.715]],[\"easeOutSine\",[.39,.575,.565,1]],[\"easeInOutSine\",[.445,.05,.55,.95]],[\"easeInQuad\",[.55,.085,.68,.53]],[\"easeOutQuad\",[.25,.46,.45,.94]],[\"easeInOutQuad\",[.455,.03,.515,.955]],[\"easeInCubic\",[.55,.055,.675,.19]],[\"easeOutCubic\",[.215,.61,.355,1]],[\"easeInOutCubic\",[.645,.045,.355,1]],[\"easeInQuart\",[.895,.03,.685,.22]],[\"easeOutQuart\",[.165,.84,.44,1]],[\"easeInOutQuart\",[.77,0,.175,1]],[\"easeInQuint\",[.755,.05,.855,.06]],[\"easeOutQuint\",[.23,1,.32,1]],[\"easeInOutQuint\",[.86,0,.07,1]],[\"easeInExpo\",[.95,.05,.795,.035]],[\"easeOutExpo\",[.19,1,.22,1]],[\"easeInOutExpo\",[1,0,0,1]],[\"easeInCirc\",[.6,.04,.98,.335]],[\"easeOutCirc\",[.075,.82,.165,1]],[\"easeInOutCirc\",[.785,.135,.15,.86]]],function(e,t){v.Easings[t[0]]=l.apply(null,t[1])});var x=v.CSS={RegEx:{isHex:/^#([A-f\\d]{3}){1,2}$/i,valueUnwrap:/^[A-z]+\\((.*)\\)$/i,wrappedValueAlreadyExtracted:/[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/,valueSplit:/([A-z]+\\(.+\\))|(([A-z0-9#-.]+?)(?=\\s|$))/gi},Lists:{colors:[\"fill\",\"stroke\",\"stopColor\",\"color\",\"backgroundColor\",\"borderColor\",\"borderTopColor\",\"borderRightColor\",\"borderBottomColor\",\"borderLeftColor\",\"outlineColor\"],transformsBase:[\"translateX\",\"translateY\",\"scale\",\"scaleX\",\"scaleY\",\"skewX\",\"skewY\",\"rotateZ\"],transforms3D:[\"transformPerspective\",\"translateZ\",\"scaleZ\",\"rotateX\",\"rotateY\"]},Hooks:{templates:{textShadow:[\"Color X Y Blur\",\"black 0px 0px 0px\"],boxShadow:[\"Color X Y Blur Spread\",\"black 0px 0px 0px 0px\"],clip:[\"Top Right Bottom Left\",\"0px 0px 0px 0px\"],backgroundPosition:[\"X Y\",\"0% 0%\"],transformOrigin:[\"X Y Z\",\"50% 50% 0px\"],perspectiveOrigin:[\"X Y\",\"50% 50%\"]},registered:{},register:function(){for(var e=0;e<x.Lists.colors.length;e++){var t=\"color\"===x.Lists.colors[e]?\"0 0 0 1\":\"255 255 255 1\";x.Hooks.templates[x.Lists.colors[e]]=[\"Red Green Blue Alpha\",t]}var r,a,n;if(f)for(r in x.Hooks.templates){a=x.Hooks.templates[r],n=a[0].split(\" \");var o=a[1].match(x.RegEx.valueSplit);\"Color\"===n[0]&&(n.push(n.shift()),o.push(o.shift()),x.Hooks.templates[r]=[n.join(\" \"),o.join(\" \")])}for(r in x.Hooks.templates){a=x.Hooks.templates[r],n=a[0].split(\" \");for(var e in n){var i=r+n[e],s=e;x.Hooks.registered[i]=[r,s]}}},getRoot:function(e){var t=x.Hooks.registered[e];return t?t[0]:e},cleanRootPropertyValue:function(e,t){return x.RegEx.valueUnwrap.test(t)&&(t=t.match(x.RegEx.valueUnwrap)[1]),x.Values.isCSSNullValue(t)&&(t=x.Hooks.templates[e][1]),t},extractValue:function(e,t){var r=x.Hooks.registered[e];if(r){var a=r[0],n=r[1];return t=x.Hooks.cleanRootPropertyValue(a,t),t.toString().match(x.RegEx.valueSplit)[n]}return t},injectValue:function(e,t,r){var a=x.Hooks.registered[e];if(a){var n=a[0],o=a[1],i,s;return r=x.Hooks.cleanRootPropertyValue(n,r),i=r.toString().match(x.RegEx.valueSplit),i[o]=t,s=i.join(\" \")}return r}},Normalizations:{registered:{clip:function(e,t,r){switch(e){case\"name\":return\"clip\";case\"extract\":var a;return x.RegEx.wrappedValueAlreadyExtracted.test(r)?a=r:(a=r.toString().match(x.RegEx.valueUnwrap),a=a?a[1].replace(/,(\\s+)?/g,\" \"):r),a;case\"inject\":return\"rect(\"+r+\")\"}},blur:function(e,t,r){switch(e){case\"name\":return v.State.isFirefox?\"filter\":\"-webkit-filter\";case\"extract\":var a=parseFloat(r);if(!a&&0!==a){var n=r.toString().match(/blur\\(([0-9]+[A-z]+)\\)/i);a=n?n[1]:0}return a;case\"inject\":return parseFloat(r)?\"blur(\"+r+\")\":\"none\"}},opacity:function(e,t,r){if(8>=f)switch(e){case\"name\":return\"filter\";case\"extract\":var a=r.toString().match(/alpha\\(opacity=(.*)\\)/i);return r=a?a[1]/100:1;case\"inject\":return t.style.zoom=1,parseFloat(r)>=1?\"\":\"alpha(opacity=\"+parseInt(100*parseFloat(r),10)+\")\"}else switch(e){case\"name\":return\"opacity\";case\"extract\":return r;case\"inject\":return r}}},register:function(){9>=f||v.State.isGingerbread||(x.Lists.transformsBase=x.Lists.transformsBase.concat(x.Lists.transforms3D));for(var e=0;e<x.Lists.transformsBase.length;e++)!function(){var t=x.Lists.transformsBase[e];x.Normalizations.registered[t]=function(e,r,n){switch(e){case\"name\":return\"transform\";case\"extract\":return i(r)===a||i(r).transformCache[t]===a?/^scale/i.test(t)?1:0:i(r).transformCache[t].replace(/[()]/g,\"\");case\"inject\":var o=!1;switch(t.substr(0,t.length-1)){case\"translate\":o=!/(%|px|em|rem|vw|vh|\\d)$/i.test(n);break;case\"scal\":case\"scale\":v.State.isAndroid&&i(r).transformCache[t]===a&&1>n&&(n=1),o=!/(\\d)$/i.test(n);break;case\"skew\":o=!/(deg|\\d)$/i.test(n);break;case\"rotate\":o=!/(deg|\\d)$/i.test(n)}return o||(i(r).transformCache[t]=\"(\"+n+\")\"),i(r).transformCache[t]}}}();for(var e=0;e<x.Lists.colors.length;e++)!function(){var t=x.Lists.colors[e];x.Normalizations.registered[t]=function(e,r,n){switch(e){case\"name\":return t;case\"extract\":var o;if(x.RegEx.wrappedValueAlreadyExtracted.test(n))o=n;else{var i,s={black:\"rgb(0, 0, 0)\",blue:\"rgb(0, 0, 255)\",gray:\"rgb(128, 128, 128)\",green:\"rgb(0, 128, 0)\",red:\"rgb(255, 0, 0)\",white:\"rgb(255, 255, 255)\"};/^[A-z]+$/i.test(n)?i=s[n]!==a?s[n]:s.black:x.RegEx.isHex.test(n)?i=\"rgb(\"+x.Values.hexToRgb(n).join(\" \")+\")\":/^rgba?\\(/i.test(n)||(i=s.black),o=(i||n).toString().match(x.RegEx.valueUnwrap)[1].replace(/,(\\s+)?/g,\" \")}return 8>=f||3!==o.split(\" \").length||(o+=\" 1\"),o;case\"inject\":return 8>=f?4===n.split(\" \").length&&(n=n.split(/\\s+/).slice(0,3).join(\" \")):3===n.split(\" \").length&&(n+=\" 1\"),(8>=f?\"rgb\":\"rgba\")+\"(\"+n.replace(/\\s+/g,\",\").replace(/\\.(\\d)+(?=,)/g,\"\")+\")\"}}}()}},Names:{camelCase:function(e){return e.replace(/-(\\w)/g,function(e,t){return t.toUpperCase()})},SVGAttribute:function(e){var t=\"width|height|x|y|cx|cy|r|rx|ry|x1|x2|y1|y2\";return(f||v.State.isAndroid&&!v.State.isChrome)&&(t+=\"|transform\"),new RegExp(\"^(\"+t+\")$\",\"i\").test(e)},prefixCheck:function(e){if(v.State.prefixMatches[e])return[v.State.prefixMatches[e],!0];for(var t=[\"\",\"Webkit\",\"Moz\",\"ms\",\"O\"],r=0,a=t.length;a>r;r++){var n;if(n=0===r?e:t[r]+e.replace(/^\\w/,function(e){return e.toUpperCase()}),g.isString(v.State.prefixElement.style[n]))return v.State.prefixMatches[e]=n,[n,!0]}return[e,!1]}},Values:{hexToRgb:function(e){var t=/^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i,r=/^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i,a;return e=e.replace(t,function(e,t,r,a){return t+t+r+r+a+a}),a=r.exec(e),a?[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],16)]:[0,0,0]},isCSSNullValue:function(e){return 0==e||/^(none|auto|transparent|(rgba\\(0, ?0, ?0, ?0\\)))$/i.test(e)},getUnitType:function(e){return/^(rotate|skew)/i.test(e)?\"deg\":/(^(scale|scaleX|scaleY|scaleZ|alpha|flexGrow|flexHeight|zIndex|fontWeight)$)|((opacity|red|green|blue|alpha)$)/i.test(e)?\"\":\"px\"},getDisplayType:function(e){var t=e&&e.tagName.toString().toLowerCase();return/^(b|big|i|small|tt|abbr|acronym|cite|code|dfn|em|kbd|strong|samp|var|a|bdo|br|img|map|object|q|script|span|sub|sup|button|input|label|select|textarea)$/i.test(t)?\"inline\":/^(li)$/i.test(t)?\"list-item\":/^(tr)$/i.test(t)?\"table-row\":/^(table)$/i.test(t)?\"table\":/^(tbody)$/i.test(t)?\"table-row-group\":\"block\"},addClass:function(e,t){e.classList?e.classList.add(t):e.className+=(e.className.length?\" \":\"\")+t},removeClass:function(e,t){e.classList?e.classList.remove(t):e.className=e.className.toString().replace(new RegExp(\"(^|\\\\s)\"+t.split(\" \").join(\"|\")+\"(\\\\s|$)\",\"gi\"),\" \")}},getPropertyValue:function(e,r,n,o){function s(e,r){function n(){u&&x.setPropertyValue(e,\"display\",\"none\")}var l=0;if(8>=f)l=$.css(e,r);else{var u=!1;if(/^(width|height)$/.test(r)&&0===x.getPropertyValue(e,\"display\")&&(u=!0,x.setPropertyValue(e,\"display\",x.Values.getDisplayType(e))),!o){if(\"height\"===r&&\"border-box\"!==x.getPropertyValue(e,\"boxSizing\").toString().toLowerCase()){var c=e.offsetHeight-(parseFloat(x.getPropertyValue(e,\"borderTopWidth\"))||0)-(parseFloat(x.getPropertyValue(e,\"borderBottomWidth\"))||0)-(parseFloat(x.getPropertyValue(e,\"paddingTop\"))||0)-(parseFloat(x.getPropertyValue(e,\"paddingBottom\"))||0);return n(),c}if(\"width\"===r&&\"border-box\"!==x.getPropertyValue(e,\"boxSizing\").toString().toLowerCase()){var p=e.offsetWidth-(parseFloat(x.getPropertyValue(e,\"borderLeftWidth\"))||0)-(parseFloat(x.getPropertyValue(e,\"borderRightWidth\"))||0)-(parseFloat(x.getPropertyValue(e,\"paddingLeft\"))||0)-(parseFloat(x.getPropertyValue(e,\"paddingRight\"))||0);return n(),p}}var d;d=i(e)===a?t.getComputedStyle(e,null):i(e).computedStyle?i(e).computedStyle:i(e).computedStyle=t.getComputedStyle(e,null),\"borderColor\"===r&&(r=\"borderTopColor\"),l=9===f&&\"filter\"===r?d.getPropertyValue(r):d[r],(\"\"===l||null===l)&&(l=e.style[r]),n()}if(\"auto\"===l&&/^(top|right|bottom|left)$/i.test(r)){var g=s(e,\"position\");(\"fixed\"===g||\"absolute\"===g&&/top|left/i.test(r))&&(l=$(e).position()[r]+\"px\")}return l}var l;if(x.Hooks.registered[r]){var u=r,c=x.Hooks.getRoot(u);n===a&&(n=x.getPropertyValue(e,x.Names.prefixCheck(c)[0])),x.Normalizations.registered[c]&&(n=x.Normalizations.registered[c](\"extract\",e,n)),l=x.Hooks.extractValue(u,n)}else if(x.Normalizations.registered[r]){var p,d;p=x.Normalizations.registered[r](\"name\",e),\"transform\"!==p&&(d=s(e,x.Names.prefixCheck(p)[0]),x.Values.isCSSNullValue(d)&&x.Hooks.templates[r]&&(d=x.Hooks.templates[r][1])),l=x.Normalizations.registered[r](\"extract\",e,d)}if(!/^[\\d-]/.test(l))if(i(e)&&i(e).isSVG&&x.Names.SVGAttribute(r))if(/^(height|width)$/i.test(r))try{l=e.getBBox()[r]}catch(g){l=0}else l=e.getAttribute(r);else l=s(e,x.Names.prefixCheck(r)[0]);return x.Values.isCSSNullValue(l)&&(l=0),v.debug>=2&&console.log(\"Get \"+r+\": \"+l),l},setPropertyValue:function(e,r,a,n,o){var s=r;if(\"scroll\"===r)o.container?o.container[\"scroll\"+o.direction]=a:\"Left\"===o.direction?t.scrollTo(a,o.alternateValue):t.scrollTo(o.alternateValue,a);else if(x.Normalizations.registered[r]&&\"transform\"===x.Normalizations.registered[r](\"name\",e))x.Normalizations.registered[r](\"inject\",e,a),s=\"transform\",a=i(e).transformCache[r];else{if(x.Hooks.registered[r]){var l=r,u=x.Hooks.getRoot(r);n=n||x.getPropertyValue(e,u),a=x.Hooks.injectValue(l,a,n),r=u}if(x.Normalizations.registered[r]&&(a=x.Normalizations.registered[r](\"inject\",e,a),r=x.Normalizations.registered[r](\"name\",e)),s=x.Names.prefixCheck(r)[0],8>=f)try{e.style[s]=a}catch(c){v.debug&&console.log(\"Browser does not support [\"+a+\"] for [\"+s+\"]\")}else i(e)&&i(e).isSVG&&x.Names.SVGAttribute(r)?e.setAttribute(r,a):e.style[s]=a;v.debug>=2&&console.log(\"Set \"+r+\" (\"+s+\"): \"+a)}return[s,a]},flushTransformCache:function(e){function t(t){return parseFloat(x.getPropertyValue(e,t))}var r=\"\";if((f||v.State.isAndroid&&!v.State.isChrome)&&i(e).isSVG){var a={translate:[t(\"translateX\"),t(\"translateY\")],skewX:[t(\"skewX\")],skewY:[t(\"skewY\")],scale:1!==t(\"scale\")?[t(\"scale\"),t(\"scale\")]:[t(\"scaleX\"),t(\"scaleY\")],rotate:[t(\"rotateZ\"),0,0]};$.each(i(e).transformCache,function(e){/^translate/i.test(e)?e=\"translate\":/^scale/i.test(e)?e=\"scale\":/^rotate/i.test(e)&&(e=\"rotate\"),a[e]&&(r+=e+\"(\"+a[e].join(\" \")+\") \",delete a[e])})}else{var n,o;$.each(i(e).transformCache,function(t){return n=i(e).transformCache[t],\"transformPerspective\"===t?(o=n,!0):(9===f&&\"rotateZ\"===t&&(t=\"rotate\"),void(r+=t+n+\" \"))}),o&&(r=\"perspective\"+o+\" \"+r)}x.setPropertyValue(e,\"transform\",r)}};x.Hooks.register(),x.Normalizations.register(),v.hook=function(e,t,r){var n=a;return e=o(e),$.each(e,function(e,o){if(i(o)===a&&v.init(o),r===a)n===a&&(n=v.CSS.getPropertyValue(o,t));else{var s=v.CSS.setPropertyValue(o,t,r);\"transform\"===s[0]&&v.CSS.flushTransformCache(o),n=s}}),n};var S=function(){function e(){return l?T.promise||null:f}function n(){function e(e){function p(e,t){var r=a,i=a,s=a;return g.isArray(e)?(r=e[0],!g.isArray(e[1])&&/^[\\d-]/.test(e[1])||g.isFunction(e[1])||x.RegEx.isHex.test(e[1])?s=e[1]:(g.isString(e[1])&&!x.RegEx.isHex.test(e[1])||g.isArray(e[1]))&&(i=t?e[1]:u(e[1],o.duration),e[2]!==a&&(s=e[2]))):r=e,t||(i=i||o.easing),g.isFunction(r)&&(r=r.call(n,w,P)),g.isFunction(s)&&(s=s.call(n,w,P)),[r||0,i,s]}function f(e,t){var r,a;return a=(t||\"0\").toString().toLowerCase().replace(/[%A-z]+$/,function(e){return r=e,\"\"}),r||(r=x.Values.getUnitType(e)),[a,r]}function d(){var e={myParent:n.parentNode||r.body,position:x.getPropertyValue(n,\"position\"),fontSize:x.getPropertyValue(n,\"fontSize\")},a=e.position===N.lastPosition&&e.myParent===N.lastParent,o=e.fontSize===N.lastFontSize;N.lastParent=e.myParent,N.lastPosition=e.position,N.lastFontSize=e.fontSize;var s=100,l={};if(o&&a)l.emToPx=N.lastEmToPx,l.percentToPxWidth=N.lastPercentToPxWidth,l.percentToPxHeight=N.lastPercentToPxHeight;else{var u=i(n).isSVG?r.createElementNS(\"http://www.w3.org/2000/svg\",\"rect\"):r.createElement(\"div\");v.init(u),e.myParent.appendChild(u),$.each([\"overflow\",\"overflowX\",\"overflowY\"],function(e,t){v.CSS.setPropertyValue(u,t,\"hidden\")}),v.CSS.setPropertyValue(u,\"position\",e.position),v.CSS.setPropertyValue(u,\"fontSize\",e.fontSize),v.CSS.setPropertyValue(u,\"boxSizing\",\"content-box\"),$.each([\"minWidth\",\"maxWidth\",\"width\",\"minHeight\",\"maxHeight\",\"height\"],function(e,t){v.CSS.setPropertyValue(u,t,s+\"%\")}),v.CSS.setPropertyValue(u,\"paddingLeft\",s+\"em\"),l.percentToPxWidth=N.lastPercentToPxWidth=(parseFloat(x.getPropertyValue(u,\"width\",null,!0))||1)/s,l.percentToPxHeight=N.lastPercentToPxHeight=(parseFloat(x.getPropertyValue(u,\"height\",null,!0))||1)/s,l.emToPx=N.lastEmToPx=(parseFloat(x.getPropertyValue(u,\"paddingLeft\"))||1)/s,e.myParent.removeChild(u)}return null===N.remToPx&&(N.remToPx=parseFloat(x.getPropertyValue(r.body,\"fontSize\"))||16),null===N.vwToPx&&(N.vwToPx=parseFloat(t.innerWidth)/100,N.vhToPx=parseFloat(t.innerHeight)/100),l.remToPx=N.remToPx,l.vwToPx=N.vwToPx,l.vhToPx=N.vhToPx,v.debug>=1&&console.log(\"Unit ratios: \"+JSON.stringify(l),n),l}if(o.begin&&0===w)try{o.begin.call(m,m)}catch(y){setTimeout(function(){throw y},1)}if(\"scroll\"===k){var S=/^x$/i.test(o.axis)?\"Left\":\"Top\",V=parseFloat(o.offset)||0,C,A,F;o.container?g.isWrapped(o.container)||g.isNode(o.container)?(o.container=o.container[0]||o.container,C=o.container[\"scroll\"+S],F=C+$(n).position()[S.toLowerCase()]+V):o.container=null:(C=v.State.scrollAnchor[v.State[\"scrollProperty\"+S]],A=v.State.scrollAnchor[v.State[\"scrollProperty\"+(\"Left\"===S?\"Top\":\"Left\")]],F=$(n).offset()[S.toLowerCase()]+V),s={scroll:{rootPropertyValue:!1,startValue:C,currentValue:C,endValue:F,unitType:\"\",easing:o.easing,scrollData:{container:o.container,direction:S,alternateValue:A}},element:n},v.debug&&console.log(\"tweensContainer (scroll): \",s.scroll,n)}else if(\"reverse\"===k){if(!i(n).tweensContainer)return void $.dequeue(n,o.queue);\"none\"===i(n).opts.display&&(i(n).opts.display=\"auto\"),\"hidden\"===i(n).opts.visibility&&(i(n).opts.visibility=\"visible\"),i(n).opts.loop=!1,i(n).opts.begin=null,i(n).opts.complete=null,b.easing||delete o.easing,b.duration||delete o.duration,o=$.extend({},i(n).opts,o);var E=$.extend(!0,{},i(n).tweensContainer);for(var j in E)if(\"element\"!==j){var H=E[j].startValue;E[j].startValue=E[j].currentValue=E[j].endValue,E[j].endValue=H,g.isEmptyObject(b)||(E[j].easing=o.easing),v.debug&&console.log(\"reverse tweensContainer (\"+j+\"): \"+JSON.stringify(E[j]),n)}s=E}else if(\"start\"===k){var E;i(n).tweensContainer&&i(n).isAnimating===!0&&(E=i(n).tweensContainer),$.each(h,function(e,t){if(RegExp(\"^\"+x.Lists.colors.join(\"$|^\")+\"$\").test(e)){var r=p(t,!0),n=r[0],o=r[1],i=r[2];if(x.RegEx.isHex.test(n)){for(var s=[\"Red\",\"Green\",\"Blue\"],l=x.Values.hexToRgb(n),u=i?x.Values.hexToRgb(i):a,c=0;c<s.length;c++){var f=[l[c]];o&&f.push(o),u!==a&&f.push(u[c]),h[e+s[c]]=f}delete h[e]}}});for(var R in h){var O=p(h[R]),z=O[0],q=O[1],M=O[2];R=x.Names.camelCase(R);var I=x.Hooks.getRoot(R),B=!1;if(i(n).isSVG||\"tween\"===I||x.Names.prefixCheck(I)[1]!==!1||x.Normalizations.registered[I]!==a){(o.display!==a&&null!==o.display&&\"none\"!==o.display||o.visibility!==a&&\"hidden\"!==o.visibility)&&/opacity|filter/.test(R)&&!M&&0!==z&&(M=0),o._cacheValues&&E&&E[R]?(M===a&&(M=E[R].endValue+E[R].unitType),B=i(n).rootPropertyValueCache[I]):x.Hooks.registered[R]?M===a?(B=x.getPropertyValue(n,I),M=x.getPropertyValue(n,R,B)):B=x.Hooks.templates[I][1]:M===a&&(M=x.getPropertyValue(n,R));var W,G,D,X=!1;if(W=f(R,M),M=W[0],D=W[1],W=f(R,z),z=W[0].replace(/^([+-\\/*])=/,function(e,t){return X=t,\"\"}),G=W[1],M=parseFloat(M)||0,z=parseFloat(z)||0,\"%\"===G&&(/^(fontSize|lineHeight)$/.test(R)?(z/=100,G=\"em\"):/^scale/.test(R)?(z/=100,G=\"\"):/(Red|Green|Blue)$/i.test(R)&&(z=z/100*255,G=\"\")),/[\\/*]/.test(X))G=D;else if(D!==G&&0!==M)if(0===z)G=D;else{l=l||d();var Y=/margin|padding|left|right|width|text|word|letter/i.test(R)||/X$/.test(R)||\"x\"===R?\"x\":\"y\";switch(D){case\"%\":M*=\"x\"===Y?l.percentToPxWidth:l.percentToPxHeight;break;case\"px\":break;default:M*=l[D+\"ToPx\"]}switch(G){case\"%\":M*=1/(\"x\"===Y?l.percentToPxWidth:l.percentToPxHeight);break;case\"px\":break;default:M*=1/l[G+\"ToPx\"]}}switch(X){case\"+\":z=M+z;break;case\"-\":z=M-z;break;case\"*\":z=M*z;break;case\"/\":z=M/z}s[R]={rootPropertyValue:B,startValue:M,currentValue:M,endValue:z,unitType:G,easing:q},v.debug&&console.log(\"tweensContainer (\"+R+\"): \"+JSON.stringify(s[R]),n)}else v.debug&&console.log(\"Skipping [\"+I+\"] due to a lack of browser support.\")}s.element=n}s.element&&(x.Values.addClass(n,\"velocity-animating\"),L.push(s),\"\"===o.queue&&(i(n).tweensContainer=s,i(n).opts=o),i(n).isAnimating=!0,w===P-1?(v.State.calls.push([L,m,o,null,T.resolver]),v.State.isTicking===!1&&(v.State.isTicking=!0,c())):w++)}var n=this,o=$.extend({},v.defaults,b),s={},l;switch(i(n)===a&&v.init(n),parseFloat(o.delay)&&o.queue!==!1&&$.queue(n,o.queue,function(e){v.velocityQueueEntryFlag=!0,i(n).delayTimer={setTimeout:setTimeout(e,parseFloat(o.delay)),next:e}}),o.duration.toString().toLowerCase()){case\"fast\":o.duration=200;break;case\"normal\":o.duration=y;break;case\"slow\":o.duration=600;break;default:o.duration=parseFloat(o.duration)||1}v.mock!==!1&&(v.mock===!0?o.duration=o.delay=1:(o.duration*=parseFloat(v.mock)||1,o.delay*=parseFloat(v.mock)||1)),o.easing=u(o.easing,o.duration),o.begin&&!g.isFunction(o.begin)&&(o.begin=null),o.progress&&!g.isFunction(o.progress)&&(o.progress=null),o.complete&&!g.isFunction(o.complete)&&(o.complete=null),o.display!==a&&null!==o.display&&(o.display=o.display.toString().toLowerCase(),\"auto\"===o.display&&(o.display=v.CSS.Values.getDisplayType(n))),o.visibility!==a&&null!==o.visibility&&(o.visibility=o.visibility.toString().toLowerCase()),o.mobileHA=o.mobileHA&&v.State.isMobile&&!v.State.isGingerbread,o.queue===!1?o.delay?setTimeout(e,o.delay):e():$.queue(n,o.queue,function(t,r){return r===!0?(T.promise&&T.resolver(m),!0):(v.velocityQueueEntryFlag=!0,void e(t))}),\"\"!==o.queue&&\"fx\"!==o.queue||\"inprogress\"===$.queue(n)[0]||$.dequeue(n)}var s=arguments[0]&&(arguments[0].p||$.isPlainObject(arguments[0].properties)&&!arguments[0].properties.names||g.isString(arguments[0].properties)),l,f,d,m,h,b;if(g.isWrapped(this)?(l=!1,d=0,m=this,f=this):(l=!0,d=1,m=s?arguments[0].elements||arguments[0].e:arguments[0]),m=o(m)){s?(h=arguments[0].properties||arguments[0].p,b=arguments[0].options||arguments[0].o):(h=arguments[d],b=arguments[d+1]);var P=m.length,w=0;if(!/^(stop|finish)$/i.test(h)&&!$.isPlainObject(b)){var V=d+1;b={};for(var C=V;C<arguments.length;C++)g.isArray(arguments[C])||!/^(fast|normal|slow)$/i.test(arguments[C])&&!/^\\d/.test(arguments[C])?g.isString(arguments[C])||g.isArray(arguments[C])?b.easing=arguments[C]:g.isFunction(arguments[C])&&(b.complete=arguments[C]):b.duration=arguments[C]}var T={promise:null,resolver:null,rejecter:null};l&&v.Promise&&(T.promise=new v.Promise(function(e,t){T.resolver=e,T.rejecter=t}));var k;switch(h){case\"scroll\":k=\"scroll\";break;case\"reverse\":k=\"reverse\";break;case\"finish\":case\"stop\":$.each(m,function(e,t){i(t)&&i(t).delayTimer&&(clearTimeout(i(t).delayTimer.setTimeout),i(t).delayTimer.next&&i(t).delayTimer.next(),delete i(t).delayTimer)});var A=[];return $.each(v.State.calls,function(e,t){t&&$.each(t[1],function(r,n){var o=b===a?\"\":b;return o===!0||t[2].queue===o||b===a&&t[2].queue===!1?void $.each(m,function(r,a){a===n&&((b===!0||g.isString(b))&&($.each($.queue(a,g.isString(b)?b:\"\"),function(e,t){g.isFunction(t)&&t(null,!0)}),$.queue(a,g.isString(b)?b:\"\",[])),\"stop\"===h?(i(a)&&i(a).tweensContainer&&o!==!1&&$.each(i(a).tweensContainer,function(e,t){t.endValue=t.currentValue\n}),A.push(e)):\"finish\"===h&&(t[2].duration=1))}):!0})}),\"stop\"===h&&($.each(A,function(e,t){p(t,!0)}),T.promise&&T.resolver(m)),e();default:if(!$.isPlainObject(h)||g.isEmptyObject(h)){if(g.isString(h)&&v.Redirects[h]){var F=$.extend({},b),E=F.duration,j=F.delay||0;return F.backwards===!0&&(m=$.extend(!0,[],m).reverse()),$.each(m,function(e,t){parseFloat(F.stagger)?F.delay=j+parseFloat(F.stagger)*e:g.isFunction(F.stagger)&&(F.delay=j+F.stagger.call(t,e,P)),F.drag&&(F.duration=parseFloat(E)||(/^(callout|transition)/.test(h)?1e3:y),F.duration=Math.max(F.duration*(F.backwards?1-e/P:(e+1)/P),.75*F.duration,200)),v.Redirects[h].call(t,t,F||{},e,P,m,T.promise?T:a)}),e()}var H=\"Velocity: First argument (\"+h+\") was not a property map, a known action, or a registered redirect. Aborting.\";return T.promise?T.rejecter(new Error(H)):console.log(H),e()}k=\"start\"}var N={lastParent:null,lastPosition:null,lastFontSize:null,lastPercentToPxWidth:null,lastPercentToPxHeight:null,lastEmToPx:null,remToPx:null,vwToPx:null,vhToPx:null},L=[];$.each(m,function(e,t){g.isNode(t)&&n.call(t)});var F=$.extend({},v.defaults,b),R;if(F.loop=parseInt(F.loop),R=2*F.loop-1,F.loop)for(var O=0;R>O;O++){var z={delay:F.delay,progress:F.progress};O===R-1&&(z.display=F.display,z.visibility=F.visibility,z.complete=F.complete),S(m,\"reverse\",z)}return e()}};v=$.extend(S,v),v.animate=S;var P=t.requestAnimationFrame||d;return v.State.isMobile||r.hidden===a||r.addEventListener(\"visibilitychange\",function(){r.hidden?(P=function(e){return setTimeout(function(){e(!0)},16)},c()):P=t.requestAnimationFrame||d}),e.Velocity=v,e!==t&&(e.fn.velocity=S,e.fn.velocity.defaults=v.defaults),$.each([\"Down\",\"Up\"],function(e,t){v.Redirects[\"slide\"+t]=function(e,r,n,o,i,s){var l=$.extend({},r),u=l.begin,c=l.complete,p={height:\"\",marginTop:\"\",marginBottom:\"\",paddingTop:\"\",paddingBottom:\"\"},f={};l.display===a&&(l.display=\"Down\"===t?\"inline\"===v.CSS.Values.getDisplayType(e)?\"inline-block\":\"block\":\"none\"),l.begin=function(){u&&u.call(i,i);for(var r in p){f[r]=e.style[r];var a=v.CSS.getPropertyValue(e,r);p[r]=\"Down\"===t?[a,0]:[0,a]}f.overflow=e.style.overflow,e.style.overflow=\"hidden\"},l.complete=function(){for(var t in f)e.style[t]=f[t];c&&c.call(i,i),s&&s.resolver(i)},v(e,p,l)}}),$.each([\"In\",\"Out\"],function(e,t){v.Redirects[\"fade\"+t]=function(e,r,n,o,i,s){var l=$.extend({},r),u={opacity:\"In\"===t?1:0},c=l.complete;l.complete=n!==o-1?l.begin=null:function(){c&&c.call(i,i),s&&s.resolver(i)},l.display===a&&(l.display=\"In\"===t?\"auto\":\"none\"),v(this,u,l)}}),v}(window.jQuery||window.Zepto||window,window,document)});;!function(a,b,c,d){\"use strict\";function k(a,b,c){return setTimeout(q(a,c),b)}function l(a,b,c){return Array.isArray(a)?(m(a,c[b],c),!0):!1}function m(a,b,c){var e;if(a)if(a.forEach)a.forEach(b,c);else if(a.length!==d)for(e=0;e<a.length;)b.call(c,a[e],e,a),e++;else for(e in a)a.hasOwnProperty(e)&&b.call(c,a[e],e,a)}function n(a,b,c){for(var e=Object.keys(b),f=0;f<e.length;)(!c||c&&a[e[f]]===d)&&(a[e[f]]=b[e[f]]),f++;return a}function o(a,b){return n(a,b,!0)}function p(a,b,c){var e,d=b.prototype;e=a.prototype=Object.create(d),e.constructor=a,e._super=d,c&&n(e,c)}function q(a,b){return function(){return a.apply(b,arguments)}}function r(a,b){return typeof a==g?a.apply(b?b[0]||d:d,b):a}function s(a,b){return a===d?b:a}function t(a,b,c){m(x(b),function(b){a.addEventListener(b,c,!1)})}function u(a,b,c){m(x(b),function(b){a.removeEventListener(b,c,!1)})}function v(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1}function w(a,b){return a.indexOf(b)>-1}function x(a){return a.trim().split(/\\s+/g)}function y(a,b,c){if(a.indexOf&&!c)return a.indexOf(b);for(var d=0;d<a.length;){if(c&&a[d][c]==b||!c&&a[d]===b)return d;d++}return-1}function z(a){return Array.prototype.slice.call(a,0)}function A(a,b,c){for(var d=[],e=[],f=0;f<a.length;){var g=b?a[f][b]:a[f];y(e,g)<0&&d.push(a[f]),e[f]=g,f++}return c&&(d=b?d.sort(function(a,c){return a[b]>c[b]}):d.sort()),d}function B(a,b){for(var c,f,g=b[0].toUpperCase()+b.slice(1),h=0;h<e.length;){if(c=e[h],f=c?c+g:b,f in a)return f;h++}return d}function D(){return C++}function E(a){var b=a.ownerDocument;return b.defaultView||b.parentWindow}function ab(a,b){var c=this;this.manager=a,this.callback=b,this.element=a.element,this.target=a.options.inputTarget,this.domHandler=function(b){r(a.options.enable,[a])&&c.handler(b)},this.init()}function bb(a){var b,c=a.options.inputClass;return b=c?c:H?wb:I?Eb:G?Gb:rb,new b(a,cb)}function cb(a,b,c){var d=c.pointers.length,e=c.changedPointers.length,f=b&O&&0===d-e,g=b&(Q|R)&&0===d-e;c.isFirst=!!f,c.isFinal=!!g,f&&(a.session={}),c.eventType=b,db(a,c),a.emit(\"hammer.input\",c),a.recognize(c),a.session.prevInput=c}function db(a,b){var c=a.session,d=b.pointers,e=d.length;c.firstInput||(c.firstInput=gb(b)),e>1&&!c.firstMultiple?c.firstMultiple=gb(b):1===e&&(c.firstMultiple=!1);var f=c.firstInput,g=c.firstMultiple,h=g?g.center:f.center,i=b.center=hb(d);b.timeStamp=j(),b.deltaTime=b.timeStamp-f.timeStamp,b.angle=lb(h,i),b.distance=kb(h,i),eb(c,b),b.offsetDirection=jb(b.deltaX,b.deltaY),b.scale=g?nb(g.pointers,d):1,b.rotation=g?mb(g.pointers,d):0,fb(c,b);var k=a.element;v(b.srcEvent.target,k)&&(k=b.srcEvent.target),b.target=k}function eb(a,b){var c=b.center,d=a.offsetDelta||{},e=a.prevDelta||{},f=a.prevInput||{};(b.eventType===O||f.eventType===Q)&&(e=a.prevDelta={x:f.deltaX||0,y:f.deltaY||0},d=a.offsetDelta={x:c.x,y:c.y}),b.deltaX=e.x+(c.x-d.x),b.deltaY=e.y+(c.y-d.y)}function fb(a,b){var f,g,h,j,c=a.lastInterval||b,e=b.timeStamp-c.timeStamp;if(b.eventType!=R&&(e>N||c.velocity===d)){var k=c.deltaX-b.deltaX,l=c.deltaY-b.deltaY,m=ib(e,k,l);g=m.x,h=m.y,f=i(m.x)>i(m.y)?m.x:m.y,j=jb(k,l),a.lastInterval=b}else f=c.velocity,g=c.velocityX,h=c.velocityY,j=c.direction;b.velocity=f,b.velocityX=g,b.velocityY=h,b.direction=j}function gb(a){for(var b=[],c=0;c<a.pointers.length;)b[c]={clientX:h(a.pointers[c].clientX),clientY:h(a.pointers[c].clientY)},c++;return{timeStamp:j(),pointers:b,center:hb(b),deltaX:a.deltaX,deltaY:a.deltaY}}function hb(a){var b=a.length;if(1===b)return{x:h(a[0].clientX),y:h(a[0].clientY)};for(var c=0,d=0,e=0;b>e;)c+=a[e].clientX,d+=a[e].clientY,e++;return{x:h(c/b),y:h(d/b)}}function ib(a,b,c){return{x:b/a||0,y:c/a||0}}function jb(a,b){return a===b?S:i(a)>=i(b)?a>0?T:U:b>0?V:W}function kb(a,b,c){c||(c=$);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return Math.sqrt(d*d+e*e)}function lb(a,b,c){c||(c=$);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return 180*Math.atan2(e,d)/Math.PI}function mb(a,b){return lb(b[1],b[0],_)-lb(a[1],a[0],_)}function nb(a,b){return kb(b[0],b[1],_)/kb(a[0],a[1],_)}function rb(){this.evEl=pb,this.evWin=qb,this.allow=!0,this.pressed=!1,ab.apply(this,arguments)}function wb(){this.evEl=ub,this.evWin=vb,ab.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}function Ab(){this.evTarget=yb,this.evWin=zb,this.started=!1,ab.apply(this,arguments)}function Bb(a,b){var c=z(a.touches),d=z(a.changedTouches);return b&(Q|R)&&(c=A(c.concat(d),\"identifier\",!0)),[c,d]}function Eb(){this.evTarget=Db,this.targetIds={},ab.apply(this,arguments)}function Fb(a,b){var c=z(a.touches),d=this.targetIds;if(b&(O|P)&&1===c.length)return d[c[0].identifier]=!0,[c,c];var e,f,g=z(a.changedTouches),h=[],i=this.target;if(f=c.filter(function(a){return v(a.target,i)}),b===O)for(e=0;e<f.length;)d[f[e].identifier]=!0,e++;for(e=0;e<g.length;)d[g[e].identifier]&&h.push(g[e]),b&(Q|R)&&delete d[g[e].identifier],e++;return h.length?[A(f.concat(h),\"identifier\",!0),h]:void 0}function Gb(){ab.apply(this,arguments);var a=q(this.handler,this);this.touch=new Eb(this.manager,a),this.mouse=new rb(this.manager,a)}function Pb(a,b){this.manager=a,this.set(b)}function Qb(a){if(w(a,Mb))return Mb;var b=w(a,Nb),c=w(a,Ob);return b&&c?Nb+\" \"+Ob:b||c?b?Nb:Ob:w(a,Lb)?Lb:Kb}function Yb(a){this.id=D(),this.manager=null,this.options=o(a||{},this.defaults),this.options.enable=s(this.options.enable,!0),this.state=Rb,this.simultaneous={},this.requireFail=[]}function Zb(a){return a&Wb?\"cancel\":a&Ub?\"end\":a&Tb?\"move\":a&Sb?\"start\":\"\"}function $b(a){return a==W?\"down\":a==V?\"up\":a==T?\"left\":a==U?\"right\":\"\"}function _b(a,b){var c=b.manager;return c?c.get(a):a}function ac(){Yb.apply(this,arguments)}function bc(){ac.apply(this,arguments),this.pX=null,this.pY=null}function cc(){ac.apply(this,arguments)}function dc(){Yb.apply(this,arguments),this._timer=null,this._input=null}function ec(){ac.apply(this,arguments)}function fc(){ac.apply(this,arguments)}function gc(){Yb.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this._timer=null,this._input=null,this.count=0}function hc(a,b){return b=b||{},b.recognizers=s(b.recognizers,hc.defaults.preset),new kc(a,b)}function kc(a,b){b=b||{},this.options=o(b,hc.defaults),this.options.inputTarget=this.options.inputTarget||a,this.handlers={},this.session={},this.recognizers=[],this.element=a,this.input=bb(this),this.touchAction=new Pb(this,this.options.touchAction),lc(this,!0),m(b.recognizers,function(a){var b=this.add(new a[0](a[1]));a[2]&&b.recognizeWith(a[2]),a[3]&&b.requireFailure(a[3])},this)}function lc(a,b){var c=a.element;m(a.options.cssProps,function(a,d){c.style[B(c.style,d)]=b?a:\"\"})}function mc(a,c){var d=b.createEvent(\"Event\");d.initEvent(a,!0,!0),d.gesture=c,c.target.dispatchEvent(d)}var e=[\"\",\"webkit\",\"moz\",\"MS\",\"ms\",\"o\"],f=b.createElement(\"div\"),g=\"function\",h=Math.round,i=Math.abs,j=Date.now,C=1,F=/mobile|tablet|ip(ad|hone|od)|android/i,G=\"ontouchstart\"in a,H=B(a,\"PointerEvent\")!==d,I=G&&F.test(navigator.userAgent),J=\"touch\",K=\"pen\",L=\"mouse\",M=\"kinect\",N=25,O=1,P=2,Q=4,R=8,S=1,T=2,U=4,V=8,W=16,X=T|U,Y=V|W,Z=X|Y,$=[\"x\",\"y\"],_=[\"clientX\",\"clientY\"];ab.prototype={handler:function(){},init:function(){this.evEl&&t(this.element,this.evEl,this.domHandler),this.evTarget&&t(this.target,this.evTarget,this.domHandler),this.evWin&&t(E(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&u(this.element,this.evEl,this.domHandler),this.evTarget&&u(this.target,this.evTarget,this.domHandler),this.evWin&&u(E(this.element),this.evWin,this.domHandler)}};var ob={mousedown:O,mousemove:P,mouseup:Q},pb=\"mousedown\",qb=\"mousemove mouseup\";p(rb,ab,{handler:function(a){var b=ob[a.type];b&O&&0===a.button&&(this.pressed=!0),b&P&&1!==a.which&&(b=Q),this.pressed&&this.allow&&(b&Q&&(this.pressed=!1),this.callback(this.manager,b,{pointers:[a],changedPointers:[a],pointerType:L,srcEvent:a}))}});var sb={pointerdown:O,pointermove:P,pointerup:Q,pointercancel:R,pointerout:R},tb={2:J,3:K,4:L,5:M},ub=\"pointerdown\",vb=\"pointermove pointerup pointercancel\";a.MSPointerEvent&&(ub=\"MSPointerDown\",vb=\"MSPointerMove MSPointerUp MSPointerCancel\"),p(wb,ab,{handler:function(a){var b=this.store,c=!1,d=a.type.toLowerCase().replace(\"ms\",\"\"),e=sb[d],f=tb[a.pointerType]||a.pointerType,g=f==J,h=y(b,a.pointerId,\"pointerId\");e&O&&(0===a.button||g)?0>h&&(b.push(a),h=b.length-1):e&(Q|R)&&(c=!0),0>h||(b[h]=a,this.callback(this.manager,e,{pointers:b,changedPointers:[a],pointerType:f,srcEvent:a}),c&&b.splice(h,1))}});var xb={touchstart:O,touchmove:P,touchend:Q,touchcancel:R},yb=\"touchstart\",zb=\"touchstart touchmove touchend touchcancel\";p(Ab,ab,{handler:function(a){var b=xb[a.type];if(b===O&&(this.started=!0),this.started){var c=Bb.call(this,a,b);b&(Q|R)&&0===c[0].length-c[1].length&&(this.started=!1),this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:J,srcEvent:a})}}});var Cb={touchstart:O,touchmove:P,touchend:Q,touchcancel:R},Db=\"touchstart touchmove touchend touchcancel\";p(Eb,ab,{handler:function(a){var b=Cb[a.type],c=Fb.call(this,a,b);c&&this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:J,srcEvent:a})}}),p(Gb,ab,{handler:function(a,b,c){var d=c.pointerType==J,e=c.pointerType==L;if(d)this.mouse.allow=!1;else if(e&&!this.mouse.allow)return;b&(Q|R)&&(this.mouse.allow=!0),this.callback(a,b,c)},destroy:function(){this.touch.destroy(),this.mouse.destroy()}});var Hb=B(f.style,\"touchAction\"),Ib=Hb!==d,Jb=\"compute\",Kb=\"auto\",Lb=\"manipulation\",Mb=\"none\",Nb=\"pan-x\",Ob=\"pan-y\";Pb.prototype={set:function(a){a==Jb&&(a=this.compute()),Ib&&(this.manager.element.style[Hb]=a),this.actions=a.toLowerCase().trim()},update:function(){this.set(this.manager.options.touchAction)},compute:function(){var a=[];return m(this.manager.recognizers,function(b){r(b.options.enable,[b])&&(a=a.concat(b.getTouchAction()))}),Qb(a.join(\" \"))},preventDefaults:function(a){if(!Ib){var b=a.srcEvent,c=a.offsetDirection;if(this.manager.session.prevented)return b.preventDefault(),void 0;var d=this.actions,e=w(d,Mb),f=w(d,Ob),g=w(d,Nb);return e||f&&c&X||g&&c&Y?this.preventSrc(b):void 0}},preventSrc:function(a){this.manager.session.prevented=!0,a.preventDefault()}};var Rb=1,Sb=2,Tb=4,Ub=8,Vb=Ub,Wb=16,Xb=32;Yb.prototype={defaults:{},set:function(a){return n(this.options,a),this.manager&&this.manager.touchAction.update(),this},recognizeWith:function(a){if(l(a,\"recognizeWith\",this))return this;var b=this.simultaneous;return a=_b(a,this),b[a.id]||(b[a.id]=a,a.recognizeWith(this)),this},dropRecognizeWith:function(a){return l(a,\"dropRecognizeWith\",this)?this:(a=_b(a,this),delete this.simultaneous[a.id],this)},requireFailure:function(a){if(l(a,\"requireFailure\",this))return this;var b=this.requireFail;return a=_b(a,this),-1===y(b,a)&&(b.push(a),a.requireFailure(this)),this},dropRequireFailure:function(a){if(l(a,\"dropRequireFailure\",this))return this;a=_b(a,this);var b=y(this.requireFail,a);return b>-1&&this.requireFail.splice(b,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(a){return!!this.simultaneous[a.id]},emit:function(a){function d(d){b.manager.emit(b.options.event+(d?Zb(c):\"\"),a)}var b=this,c=this.state;Ub>c&&d(!0),d(),c>=Ub&&d(!0)},tryEmit:function(a){return this.canEmit()?this.emit(a):(this.state=Xb,void 0)},canEmit:function(){for(var a=0;a<this.requireFail.length;){if(!(this.requireFail[a].state&(Xb|Rb)))return!1;a++}return!0},recognize:function(a){var b=n({},a);return r(this.options.enable,[this,b])?(this.state&(Vb|Wb|Xb)&&(this.state=Rb),this.state=this.process(b),this.state&(Sb|Tb|Ub|Wb)&&this.tryEmit(b),void 0):(this.reset(),this.state=Xb,void 0)},process:function(){},getTouchAction:function(){},reset:function(){}},p(ac,Yb,{defaults:{pointers:1},attrTest:function(a){var b=this.options.pointers;return 0===b||a.pointers.length===b},process:function(a){var b=this.state,c=a.eventType,d=b&(Sb|Tb),e=this.attrTest(a);return d&&(c&R||!e)?b|Wb:d||e?c&Q?b|Ub:b&Sb?b|Tb:Sb:Xb}}),p(bc,ac,{defaults:{event:\"pan\",threshold:10,pointers:1,direction:Z},getTouchAction:function(){var a=this.options.direction,b=[];return a&X&&b.push(Ob),a&Y&&b.push(Nb),b},directionTest:function(a){var b=this.options,c=!0,d=a.distance,e=a.direction,f=a.deltaX,g=a.deltaY;return e&b.direction||(b.direction&X?(e=0===f?S:0>f?T:U,c=f!=this.pX,d=Math.abs(a.deltaX)):(e=0===g?S:0>g?V:W,c=g!=this.pY,d=Math.abs(a.deltaY))),a.direction=e,c&&d>b.threshold&&e&b.direction},attrTest:function(a){return ac.prototype.attrTest.call(this,a)&&(this.state&Sb||!(this.state&Sb)&&this.directionTest(a))},emit:function(a){this.pX=a.deltaX,this.pY=a.deltaY;var b=$b(a.direction);b&&this.manager.emit(this.options.event+b,a),this._super.emit.call(this,a)}}),p(cc,ac,{defaults:{event:\"pinch\",threshold:0,pointers:2},getTouchAction:function(){return[Mb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.scale-1)>this.options.threshold||this.state&Sb)},emit:function(a){if(this._super.emit.call(this,a),1!==a.scale){var b=a.scale<1?\"in\":\"out\";this.manager.emit(this.options.event+b,a)}}}),p(dc,Yb,{defaults:{event:\"press\",pointers:1,time:500,threshold:5},getTouchAction:function(){return[Kb]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,e=a.deltaTime>b.time;if(this._input=a,!d||!c||a.eventType&(Q|R)&&!e)this.reset();else if(a.eventType&O)this.reset(),this._timer=k(function(){this.state=Vb,this.tryEmit()},b.time,this);else if(a.eventType&Q)return Vb;return Xb},reset:function(){clearTimeout(this._timer)},emit:function(a){this.state===Vb&&(a&&a.eventType&Q?this.manager.emit(this.options.event+\"up\",a):(this._input.timeStamp=j(),this.manager.emit(this.options.event,this._input)))}}),p(ec,ac,{defaults:{event:\"rotate\",threshold:0,pointers:2},getTouchAction:function(){return[Mb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.rotation)>this.options.threshold||this.state&Sb)}}),p(fc,ac,{defaults:{event:\"swipe\",threshold:10,velocity:.65,direction:X|Y,pointers:1},getTouchAction:function(){return bc.prototype.getTouchAction.call(this)},attrTest:function(a){var c,b=this.options.direction;return b&(X|Y)?c=a.velocity:b&X?c=a.velocityX:b&Y&&(c=a.velocityY),this._super.attrTest.call(this,a)&&b&a.direction&&a.distance>this.options.threshold&&i(c)>this.options.velocity&&a.eventType&Q},emit:function(a){var b=$b(a.direction);b&&this.manager.emit(this.options.event+b,a),this.manager.emit(this.options.event,a)}}),p(gc,Yb,{defaults:{event:\"tap\",pointers:1,taps:1,interval:300,time:250,threshold:2,posThreshold:10},getTouchAction:function(){return[Lb]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,e=a.deltaTime<b.time;if(this.reset(),a.eventType&O&&0===this.count)return this.failTimeout();if(d&&e&&c){if(a.eventType!=Q)return this.failTimeout();var f=this.pTime?a.timeStamp-this.pTime<b.interval:!0,g=!this.pCenter||kb(this.pCenter,a.center)<b.posThreshold;this.pTime=a.timeStamp,this.pCenter=a.center,g&&f?this.count+=1:this.count=1,this._input=a;var h=this.count%b.taps;if(0===h)return this.hasRequireFailures()?(this._timer=k(function(){this.state=Vb,this.tryEmit()},b.interval,this),Sb):Vb}return Xb},failTimeout:function(){return this._timer=k(function(){this.state=Xb},this.options.interval,this),Xb},reset:function(){clearTimeout(this._timer)},emit:function(){this.state==Vb&&(this._input.tapCount=this.count,this.manager.emit(this.options.event,this._input))}}),hc.VERSION=\"2.0.4\",hc.defaults={domEvents:!1,touchAction:Jb,enable:!0,inputTarget:null,inputClass:null,preset:[[ec,{enable:!1}],[cc,{enable:!1},[\"rotate\"]],[fc,{direction:X}],[bc,{direction:X},[\"swipe\"]],[gc],[gc,{event:\"doubletap\",taps:2},[\"tap\"]],[dc]],cssProps:{userSelect:\"default\",touchSelect:\"none\",touchCallout:\"none\",contentZooming:\"none\",userDrag:\"none\",tapHighlightColor:\"rgba(0,0,0,0)\"}};var ic=1,jc=2;kc.prototype={set:function(a){return n(this.options,a),a.touchAction&&this.touchAction.update(),a.inputTarget&&(this.input.destroy(),this.input.target=a.inputTarget,this.input.init()),this},stop:function(a){this.session.stopped=a?jc:ic},recognize:function(a){var b=this.session;if(!b.stopped){this.touchAction.preventDefaults(a);var c,d=this.recognizers,e=b.curRecognizer;(!e||e&&e.state&Vb)&&(e=b.curRecognizer=null);for(var f=0;f<d.length;)c=d[f],b.stopped===jc||e&&c!=e&&!c.canRecognizeWith(e)?c.reset():c.recognize(a),!e&&c.state&(Sb|Tb|Ub)&&(e=b.curRecognizer=c),f++}},get:function(a){if(a instanceof Yb)return a;for(var b=this.recognizers,c=0;c<b.length;c++)if(b[c].options.event==a)return b[c];return null},add:function(a){if(l(a,\"add\",this))return this;var b=this.get(a.options.event);return b&&this.remove(b),this.recognizers.push(a),a.manager=this,this.touchAction.update(),a},remove:function(a){if(l(a,\"remove\",this))return this;var b=this.recognizers;return a=this.get(a),b.splice(y(b,a),1),this.touchAction.update(),this},on:function(a,b){var c=this.handlers;return m(x(a),function(a){c[a]=c[a]||[],c[a].push(b)}),this},off:function(a,b){var c=this.handlers;return m(x(a),function(a){b?c[a].splice(y(c[a],b),1):delete c[a]}),this},emit:function(a,b){this.options.domEvents&&mc(a,b);var c=this.handlers[a]&&this.handlers[a].slice();if(c&&c.length){b.type=a,b.preventDefault=function(){b.srcEvent.preventDefault()};for(var d=0;d<c.length;)c[d](b),d++}},destroy:function(){this.element&&lc(this,!1),this.handlers={},this.session={},this.input.destroy(),this.element=null}},n(hc,{INPUT_START:O,INPUT_MOVE:P,INPUT_END:Q,INPUT_CANCEL:R,STATE_POSSIBLE:Rb,STATE_BEGAN:Sb,STATE_CHANGED:Tb,STATE_ENDED:Ub,STATE_RECOGNIZED:Vb,STATE_CANCELLED:Wb,STATE_FAILED:Xb,DIRECTION_NONE:S,DIRECTION_LEFT:T,DIRECTION_RIGHT:U,DIRECTION_UP:V,DIRECTION_DOWN:W,DIRECTION_HORIZONTAL:X,DIRECTION_VERTICAL:Y,DIRECTION_ALL:Z,Manager:kc,Input:ab,TouchAction:Pb,TouchInput:Eb,MouseInput:rb,PointerEventInput:wb,TouchMouseInput:Gb,SingleTouchInput:Ab,Recognizer:Yb,AttrRecognizer:ac,Tap:gc,Pan:bc,Swipe:fc,Pinch:cc,Rotate:ec,Press:dc,on:t,off:u,each:m,merge:o,extend:n,inherit:p,bindFn:q,prefixed:B}),typeof define==g&&define.amd?define(function(){return hc}):\"undefined\"!=typeof module&&module.exports?module.exports=hc:a[c]=hc}(window,document,\"Hammer\");;(function(factory) {\n    if (typeof define === 'function' && define.amd) {\n        define(['jquery', 'hammerjs'], factory);\n    } else if (typeof exports === 'object') {\n        factory(require('jquery'), require('hammerjs'));\n    } else {\n        factory(jQuery, Hammer);\n    }\n}(function($, Hammer) {\n    function hammerify(el, options) {\n        var $el = $(el);\n        if(!$el.data(\"hammer\")) {\n            $el.data(\"hammer\", new Hammer($el[0], options));\n        }\n    }\n\n    $.fn.hammer = function(options) {\n        return this.each(function() {\n            hammerify(this, options);\n        });\n    };\n\n    // extend the emit method to also trigger jQuery events\n    Hammer.Manager.prototype.emit = (function(originalEmit) {\n        return function(type, data) {\n            originalEmit.call(this, type, data);\n            $(this.element).trigger({\n                type: type,\n                gesture: data\n            });\n        };\n    })(Hammer.Manager.prototype.emit);\n}));\n\n  var methods = {\n    init : function() {\n      return this.each(function() {\n\n      // For each set of tabs, we want to keep track of\n      // which tab is active and its associated content\n      var $this = $(this),\n          window_width = $(window).width();\n\n      $this.width('100%');\n      // Set Tab Width for each tab\n      var $num_tabs = $(this).children('li').length;\n      $this.children('li').each(function() {\n        $(this).width((100/$num_tabs)+'%');\n      });\n      var $active, $content, $links = $this.find('li.tab a'),\n          $tabs_width = $this.width(),\n          $tab_width = $this.find('li').first().outerWidth(),\n          $index = 0;\n\n      // If the location.hash matches one of the links, use that as the active tab.\n      $active = $($links.filter('[href=\"'+location.hash+'\"]'));\n\n      // If no match is found, use the first link or any with class 'active' as the initial active tab.\n      if ($active.length === 0) {\n          $active = $(this).find('li.tab a.active').first();\n      }\n      if ($active.length === 0) {\n        $active = $(this).find('li.tab a').first();\n      }\n\n      $active.addClass('active');\n      $index = $links.index($active);\n      if ($index < 0) {\n        $index = 0;\n      }\n\n      $content = $($active[0].hash);\n\n      // append indicator then set indicator width to tab width\n      $this.append('<div class=\"indicator\"></div>');\n      var $indicator = $this.find('.indicator');\n      if ($this.is(\":visible\")) {\n        $indicator.css({\"right\": $tabs_width - (($index + 1) * $tab_width)});\n        $indicator.css({\"left\": $index * $tab_width});\n      }\n      $(window).resize(function () {\n        $tabs_width = $this.width();\n        $tab_width = $this.find('li').first().outerWidth();\n        if ($index < 0) {\n          $index = 0;\n        }\n        if ($tab_width !== 0 && $tabs_width !== 0) {\n          $indicator.css({\"right\": $tabs_width - (($index + 1) * $tab_width)});\n          $indicator.css({\"left\": $index * $tab_width});\n        }\n      });\n\n      // Hide the remaining content\n      $links.not($active).each(function () {\n        $(this.hash).hide();\n      });\n\n\n      // Bind the click event handler\n      $this.on('click', 'a', function(e){\n        $tabs_width = $this.width();\n        $tab_width = $this.find('li').first().outerWidth();\n\n        // Make the old tab inactive.\n        $active.removeClass('active');\n        $content.hide();\n\n        // Update the variables with the new link and content\n        $active = $(this);\n        $content = $(this.hash);\n        $links = $this.find('li.tab a');\n\n        // Make the tab active.\n        $active.addClass('active');\n        var $prev_index = $index;\n        $index = $links.index($(this));\n        if ($index < 0) {\n          $index = 0;\n        }\n        // Change url to current tab\n        // window.location.hash = $active.attr('href');\n\n        $content.show();\n\n        // Update indicator\n        if (($index - $prev_index) >= 0) {\n          $indicator.velocity({\"right\": $tabs_width - (($index + 1) * $tab_width)}, { duration: 300, queue: false, easing: 'easeOutQuad'});\n          $indicator.velocity({\"left\": $index * $tab_width}, {duration: 300, queue: false, easing: 'easeOutQuad', delay: 90});\n\n        }\n        else {\n          $indicator.velocity({\"left\": $index * $tab_width}, { duration: 300, queue: false, easing: 'easeOutQuad'});\n          $indicator.velocity({\"right\": $tabs_width - (($index + 1) * $tab_width)}, {duration: 300, queue: false, easing: 'easeOutQuad', delay: 90});\n        }\n\n        // Prevent the anchor's default click action\n        e.preventDefault();\n      });\n    });\n\n    },\n    select_tab : function( id ) {\n      this.find('a[href=\"#' + id + '\"]').trigger('click');\n    }\n  };\n\n  $.fn.tabs = function(methodOrOptions) {\n    if ( methods[methodOrOptions] ) {\n      return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 ));\n    } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) {\n      // Default to \"init\"\n      return methods.init.apply( this, arguments );\n    } else {\n      $.error( 'Method ' +  methodOrOptions + ' does not exist on jQuery.tooltip' );\n    }\n  };\n\n  $(document).ready(function(){\n    $('ul.tabs').tabs();\n  });\n"
  },
  {
    "path": "static/assets/js/xterm.js",
    "content": "(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.Terminal = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\n/**\n * xterm.js: xterm, in the browser\n * Copyright (c) 2014-2016, SourceLair Private Company (www.sourcelair.com (MIT License)\n */\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n * @param {HTMLTextAreaElement} textarea The textarea that xterm uses for input.\n * @param {HTMLElement} compositionView The element to display the in-progress composition in.\n * @param {Terminal} terminal The Terminal to forward the finished composition to.\n */\nfunction CompositionHelper(textarea, compositionView, terminal) {\n  this.textarea = textarea;\n  this.compositionView = compositionView;\n  this.terminal = terminal;\n\n  // Whether input composition is currently happening, eg. via a mobile keyboard, speech input\n  // or IME. This variable determines whether the compositionText should be displayed on the UI.\n  this.isComposing = false;\n\n  // The input currently being composed, eg. via a mobile keyboard, speech input or IME.\n  this.compositionText = null;\n\n  // The position within the input textarea's value of the current composition.\n  this.compositionPosition = { start: null, end: null };\n\n  // Whether a composition is in the process of being sent, setting this to false will cancel\n  // any in-progress composition.\n  this.isSendingComposition = false;\n}\n\n/**\n * Handles the compositionstart event, activating the composition view.\n */\nCompositionHelper.prototype.compositionstart = function () {\n  this.isComposing = true;\n  this.compositionPosition.start = this.textarea.value.length;\n  this.compositionView.textContent = '';\n  this.compositionView.classList.add('active');\n};\n\n/**\n * Handles the compositionupdate event, updating the composition view.\n * @param {CompositionEvent} ev The event.\n */\nCompositionHelper.prototype.compositionupdate = function (ev) {\n  this.compositionView.textContent = ev.data;\n  this.updateCompositionElements();\n  var self = this;\n  setTimeout(function () {\n    self.compositionPosition.end = self.textarea.value.length;\n  }, 0);\n};\n\n/**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\nCompositionHelper.prototype.compositionend = function () {\n  this.finalizeComposition(true);\n};\n\n/**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @return Whether the Terminal should continue processing the keydown event.\n */\nCompositionHelper.prototype.keydown = function (ev) {\n  if (this.isComposing || this.isSendingComposition) {\n    if (ev.keyCode === 229) {\n      // Continue composing if the keyCode is the \"composition character\"\n      return false;\n    } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n      // Continue composing if the keyCode is a modifier key\n      return false;\n    } else {\n      // Finish composition immediately. This is mainly here for the case where enter is\n      // pressed and the handler needs to be triggered before the command is executed.\n      this.finalizeComposition(false);\n    }\n  }\n\n  if (ev.keyCode === 229) {\n    // If the \"composition character\" is used but gets to this point it means a non-composition\n    // character (eg. numbers and punctuation) was pressed when the IME was active.\n    this.handleAnyTextareaChanges();\n    return false;\n  }\n\n  return true;\n};\n\n/**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param {boolean} waitForPropogation Whether to wait for events to propogate before sending\n *   the input. This should be false if a non-composition keystroke is entered before the\n *   compositionend event is triggered, such as enter, so that the composition is send before\n *   the command is executed.\n */\nCompositionHelper.prototype.finalizeComposition = function (waitForPropogation) {\n  this.compositionView.classList.remove('active');\n  this.isComposing = false;\n  this.clearTextareaPosition();\n\n  if (!waitForPropogation) {\n    // Cancel any delayed composition send requests and send the input immediately.\n    this.isSendingComposition = false;\n    var input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end);\n    this.terminal.handler(input);\n  } else {\n    // Make a deep copy of the composition position here as a new compositionstart event may\n    // fire before the setTimeout executes.\n    var currentCompositionPosition = {\n      start: this.compositionPosition.start,\n      end: this.compositionPosition.end\n    };\n\n    // Since composition* events happen before the changes take place in the textarea on most\n    // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n    // complete. This ensures the correct character is retrieved, this solution was used\n    // because:\n    // - The compositionend event's data property is unreliable, at least on Chromium\n    // - The last compositionupdate event's data property does not always accurately describe\n    //   the character, a counter example being Korean where an ending consonsant can move to\n    //   the following character if the following input is a vowel.\n    var self = this;\n    this.isSendingComposition = true;\n    setTimeout(function () {\n      // Ensure that the input has not already been sent\n      if (self.isSendingComposition) {\n        self.isSendingComposition = false;\n        var input;\n        if (self.isComposing) {\n          // Use the end position to get the string if a new composition has started.\n          input = self.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);\n        } else {\n          // Don't use the end position here in order to pick up any characters after the\n          // composition has finished, for example when typing a non-composition character\n          // (eg. 2) after a composition character.\n          input = self.textarea.value.substring(currentCompositionPosition.start);\n        }\n        self.terminal.handler(input);\n      }\n    }, 0);\n  }\n};\n\n/**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\nCompositionHelper.prototype.handleAnyTextareaChanges = function () {\n  var oldValue = this.textarea.value;\n  var self = this;\n  setTimeout(function () {\n    // Ignore if a composition has started since the timeout\n    if (!self.isComposing) {\n      var newValue = self.textarea.value;\n      var diff = newValue.replace(oldValue, '');\n      if (diff.length > 0) {\n        self.terminal.handler(diff);\n      }\n    }\n  }, 0);\n};\n\n/**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n */\nCompositionHelper.prototype.updateCompositionElements = function (dontRecurse) {\n  if (!this.isComposing) {\n    return;\n  }\n  var cursor = this.terminal.element.querySelector('.terminal-cursor');\n  if (cursor) {\n    // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within\n    // the .xterm element.\n    var xtermRows = this.terminal.element.querySelector('.xterm-rows');\n    var cursorTop = xtermRows.offsetTop + cursor.offsetTop;\n\n    this.compositionView.style.left = cursor.offsetLeft + 'px';\n    this.compositionView.style.top = cursorTop + 'px';\n    this.compositionView.style.height = cursor.offsetHeight + 'px';\n    this.compositionView.style.lineHeight = cursor.offsetHeight + 'px';\n    // Sync the textarea to the exact position of the composition view so the IME knows where the\n    // text is.\n    var compositionViewBounds = this.compositionView.getBoundingClientRect();\n    this.textarea.style.left = cursor.offsetLeft + 'px';\n    this.textarea.style.top = cursorTop + 'px';\n    this.textarea.style.width = compositionViewBounds.width + 'px';\n    this.textarea.style.height = compositionViewBounds.height + 'px';\n    this.textarea.style.lineHeight = compositionViewBounds.height + 'px';\n  }\n  if (!dontRecurse) {\n    setTimeout(this.updateCompositionElements.bind(this, true), 0);\n  }\n};\n\n/**\n * Clears the textarea's position so that the cursor does not blink on IE.\n * @private\n */\nCompositionHelper.prototype.clearTextareaPosition = function () {\n  this.textarea.style.left = '';\n  this.textarea.style.top = '';\n};\n\nexports.CompositionHelper = CompositionHelper;\n\n},{}],2:[function(_dereq_,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\n/**\n * xterm.js: xterm, in the browser\n * Copyright (c) 2014-2016, SourceLair Private Company (www.sourcelair.com (MIT License)\n */\n\nfunction EventEmitter() {\n  this._events = this._events || {};\n}\n\nEventEmitter.prototype.addListener = function (type, listener) {\n  this._events[type] = this._events[type] || [];\n  this._events[type].push(listener);\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.removeListener = function (type, listener) {\n  if (!this._events[type]) return;\n\n  var obj = this._events[type],\n      i = obj.length;\n\n  while (i--) {\n    if (obj[i] === listener || obj[i].listener === listener) {\n      obj.splice(i, 1);\n      return;\n    }\n  }\n};\n\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\nEventEmitter.prototype.removeAllListeners = function (type) {\n  if (this._events[type]) delete this._events[type];\n};\n\nEventEmitter.prototype.once = function (type, listener) {\n  var self = this;\n  function on() {\n    var args = Array.prototype.slice.call(arguments);\n    this.removeListener(type, on);\n    return listener.apply(this, args);\n  }\n  on.listener = listener;\n  return this.on(type, on);\n};\n\nEventEmitter.prototype.emit = function (type) {\n  if (!this._events[type]) return;\n\n  var args = Array.prototype.slice.call(arguments, 1),\n      obj = this._events[type],\n      l = obj.length,\n      i = 0;\n\n  for (; i < l; i++) {\n    obj[i].apply(this, args);\n  }\n};\n\nEventEmitter.prototype.listeners = function (type) {\n  return this._events[type] = this._events[type] || [];\n};\n\nexports.EventEmitter = EventEmitter;\n\n},{}],3:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\n/**\n * xterm.js: xterm, in the browser\n * Copyright (c) 2014-2016, SourceLair Private Company (www.sourcelair.com (MIT License)\n */\n\n/**\n * Represents the viewport of a terminal, the visible area within the larger buffer of output.\n * Logic for the virtual scroll bar is included in this object.\n * @param {Terminal} terminal The Terminal object.\n * @param {HTMLElement} viewportElement The DOM element acting as the viewport\n * @param {HTMLElement} charMeasureElement A DOM element used to measure the character size of\n *   the terminal.\n */\nfunction Viewport(terminal, viewportElement, scrollArea, charMeasureElement) {\n  this.terminal = terminal;\n  this.viewportElement = viewportElement;\n  this.scrollArea = scrollArea;\n  this.charMeasureElement = charMeasureElement;\n  this.currentRowHeight = 0;\n  this.lastRecordedBufferLength = 0;\n  this.lastRecordedViewportHeight = 0;\n\n  this.terminal.on('scroll', this.syncScrollArea.bind(this));\n  this.terminal.on('resize', this.syncScrollArea.bind(this));\n  this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));\n\n  this.syncScrollArea();\n}\n\n/**\n * Refreshes row height, setting line-height, viewport height and scroll area height if\n * necessary.\n * @param {number|undefined} charSize A character size measurement bounding rect object, if it\n *   doesn't exist it will be created.\n */\nViewport.prototype.refresh = function (charSize) {\n  var size = charSize || this.charMeasureElement.getBoundingClientRect();\n  if (size.height > 0) {\n    var rowHeightChanged = size.height !== this.currentRowHeight;\n    if (rowHeightChanged) {\n      this.currentRowHeight = size.height;\n      this.viewportElement.style.lineHeight = size.height + 'px';\n      this.terminal.rowContainer.style.lineHeight = size.height + 'px';\n    }\n    var viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;\n    if (rowHeightChanged || viewportHeightChanged) {\n      this.lastRecordedViewportHeight = this.terminal.rows;\n      this.viewportElement.style.height = size.height * this.terminal.rows + 'px';\n    }\n    this.scrollArea.style.height = size.height * this.lastRecordedBufferLength + 'px';\n  }\n};\n\n/**\n * Updates dimensions and synchronizes the scroll area if necessary.\n */\nViewport.prototype.syncScrollArea = function () {\n  if (this.lastRecordedBufferLength !== this.terminal.lines.length) {\n    // If buffer height changed\n    this.lastRecordedBufferLength = this.terminal.lines.length;\n    this.refresh();\n  } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {\n    // If viewport height changed\n    this.refresh();\n  } else {\n    // If size has changed, refresh viewport\n    var size = this.charMeasureElement.getBoundingClientRect();\n    if (size.height !== this.currentRowHeight) {\n      this.refresh(size);\n    }\n  }\n\n  // Sync scrollTop\n  var scrollTop = this.terminal.ydisp * this.currentRowHeight;\n  if (this.viewportElement.scrollTop !== scrollTop) {\n    this.viewportElement.scrollTop = scrollTop;\n  }\n};\n\n/**\n * Handles scroll events on the viewport, calculating the new viewport and requesting the\n * terminal to scroll to it.\n * @param {Event} ev The scroll event.\n */\nViewport.prototype.onScroll = function (ev) {\n  var newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);\n  var diff = newRow - this.terminal.ydisp;\n  this.terminal.scrollDisp(diff, true);\n};\n\n/**\n * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual\n * scrolling to `onScroll`, this event needs to be attached manually by the consumer of\n * `Viewport`.\n * @param {WheelEvent} ev The mouse wheel event.\n */\nViewport.prototype.onWheel = function (ev) {\n  if (ev.deltaY === 0) {\n    // Do nothing if it's not a vertical scroll event\n    return;\n  }\n  // Fallback to WheelEvent.DOM_DELTA_PIXEL\n  var multiplier = 1;\n  if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n    multiplier = this.currentRowHeight;\n  } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n    multiplier = this.currentRowHeight * this.terminal.rows;\n  }\n  this.viewportElement.scrollTop += ev.deltaY * multiplier;\n  // Prevent the page from scrolling when the terminal scrolls\n  ev.preventDefault();\n};\n\nexports.Viewport = Viewport;\n\n},{}],4:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\n/**\n * xterm.js: xterm, in the browser\n * Copyright (c) 2016, SourceLair Private Company <www.sourcelair.com> (MIT License)\n */\n\n/**\n * Clipboard handler module. This module contains methods for handling all\n * clipboard-related events appropriately in the terminal.\n * @module xterm/handlers/Clipboard\n */\n\n/**\n * Prepares text copied from terminal selection, to be saved in the clipboard by:\n *   1. stripping all trailing white spaces\n *   2. converting all non-breaking spaces to regular spaces\n * @param {string} text The copied text that needs processing for storing in clipboard\n * @returns {string}\n */\nfunction prepareTextForClipboard(text) {\n  var space = String.fromCharCode(32),\n      nonBreakingSpace = String.fromCharCode(160),\n      allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'),\n      processedText = text.split('\\n').map(function (line) {\n    // Strip all trailing white spaces and convert all non-breaking spaces\n    // to regular spaces.\n    var processedLine = line.replace(/\\s+$/g, '').replace(allNonBreakingSpaces, space);\n\n    return processedLine;\n  }).join('\\n');\n\n  return processedText;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param {ClipboardEvent} ev The original copy event to be handled\n */\nfunction copyHandler(ev, term) {\n  var copiedText = window.getSelection().toString(),\n      text = prepareTextForClipboard(copiedText);\n\n  if (term.browser.isMSIE) {\n    window.clipboardData.setData('Text', text);\n  } else {\n    ev.clipboardData.setData('text/plain', text);\n  }\n\n  ev.preventDefault(); // Prevent or the original text will be copied.\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n * @param {ClipboardEvent} ev The original paste event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nfunction pasteHandler(ev, term) {\n  ev.stopPropagation();\n\n  var dispatchPaste = function dispatchPaste(text) {\n    term.handler(text);\n    term.textarea.value = '';\n    return term.cancel(ev);\n  };\n\n  if (term.browser.isMSIE) {\n    if (window.clipboardData) {\n      var text = window.clipboardData.getData('Text');\n      dispatchPaste(text);\n    }\n  } else {\n    if (ev.clipboardData) {\n      var text = ev.clipboardData.getData('text/plain');\n      dispatchPaste(text);\n    }\n  }\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n *\n * **Logic**\n * If text is selected and right-click happens on selected text, then\n * do nothing to allow seamless copying.\n * If no text is selected or right-click is outside of the selection\n * area, then bring the terminal's input below the cursor, in order to\n * trigger the event on the textarea and allow-right click paste, without\n * caring about disappearing selection.\n * @param {ClipboardEvent} ev The original paste event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nfunction rightClickHandler(ev, term) {\n  var s = document.getSelection(),\n      selectedText = prepareTextForClipboard(s.toString()),\n      clickIsOnSelection = false;\n\n  if (s.rangeCount) {\n    var r = s.getRangeAt(0),\n        cr = r.getClientRects(),\n        x = ev.clientX,\n        y = ev.clientY,\n        i,\n        rect;\n\n    for (i = 0; i < cr.length; i++) {\n      rect = cr[i];\n      clickIsOnSelection = x > rect.left && x < rect.right && y > rect.top && y < rect.bottom;\n\n      if (clickIsOnSelection) {\n        break;\n      }\n    }\n    // If we clicked on selection and selection is not a single space,\n    // then mark the right click as copy-only. We check for the single\n    // space selection, as this can happen when clicking on an &nbsp;\n    // and there is not much pointing in copying a single space.\n    if (selectedText.match(/^\\s$/) || !selectedText.length) {\n      clickIsOnSelection = false;\n    }\n  }\n\n  // Bring textarea at the cursor position\n  if (!clickIsOnSelection) {\n    term.textarea.style.position = 'fixed';\n    term.textarea.style.width = '20px';\n    term.textarea.style.height = '20px';\n    term.textarea.style.left = x - 10 + 'px';\n    term.textarea.style.top = y - 10 + 'px';\n    term.textarea.style.zIndex = 1000;\n    term.textarea.focus();\n\n    // Reset the terminal textarea's styling\n    setTimeout(function () {\n      term.textarea.style.position = null;\n      term.textarea.style.width = null;\n      term.textarea.style.height = null;\n      term.textarea.style.left = null;\n      term.textarea.style.top = null;\n      term.textarea.style.zIndex = null;\n    }, 4);\n  }\n}\n\nexports.prepareTextForClipboard = prepareTextForClipboard;\nexports.copyHandler = copyHandler;\nexports.pasteHandler = pasteHandler;\nexports.rightClickHandler = rightClickHandler;\n\n},{}],5:[function(_dereq_,module,exports){\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.isMSWindows = exports.isIphone = exports.isIpad = exports.isMac = exports.isMSIE = exports.isFirefox = undefined;\n\nvar _Generic = _dereq_('./Generic.js');\n\nvar isNode = typeof navigator == 'undefined' ? true : false; /**\n                                                              * xterm.js: xterm, in the browser\n                                                              * Copyright (c) 2016, SourceLair Private Company <www.sourcelair.com> (MIT License)\n                                                              */\n\n/**\n * Browser utilities module. This module contains attributes and methods to help with\n * identifying the current browser and platform.\n * @module xterm/utils/Browser\n */\n\nvar userAgent = isNode ? 'node' : navigator.userAgent;\nvar platform = isNode ? 'node' : navigator.platform;\n\nvar isFirefox = exports.isFirefox = !!~userAgent.indexOf('Firefox');\nvar isMSIE = exports.isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');\n\n// Find the users platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nvar isMac = exports.isMac = (0, _Generic.contains)(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);\nvar isIpad = exports.isIpad = platform === 'iPad';\nvar isIphone = exports.isIphone = platform === 'iPhone';\nvar isMSWindows = exports.isMSWindows = (0, _Generic.contains)(['Windows', 'Win16', 'Win32', 'WinCE'], platform);\n\n},{\"./Generic.js\":6}],6:[function(_dereq_,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\n/**\n * xterm.js: xterm, in the browser\n * Copyright (c) 2016, SourceLair Private Company <www.sourcelair.com> (MIT License)\n */\n\n/**\n * Generic utilities module. This module contains generic methods that can be helpful at\n * different parts of the code base.\n * @module xterm/utils/Generic\n */\n\n/**\n * Return if the given array contains the given element\n * @param {Array} array The array to search for the given element.\n * @param {Object} el The element to look for into the array\n */\nvar contains = exports.contains = function contains(arr, el) {\n  return arr.indexOf(el) >= 0;\n};\n\n},{}],7:[function(_dereq_,module,exports){\n'use strict';var _typeof=typeof Symbol===\"function\"&&typeof Symbol.iterator===\"symbol\"?function(obj){return typeof obj;}:function(obj){return obj&&typeof Symbol===\"function\"&&obj.constructor===Symbol&&obj!==Symbol.prototype?\"symbol\":typeof obj;};/**\n * xterm.js: xterm, in the browser\n * Copyright (c) 2014-2014, SourceLair Private Company <www.sourcelair.com> (MIT License)\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * https://github.com/chjj/term.js\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n * Originally forked from (with the author's permission):\n *   Fabrice Bellard's javascript vt100 for jslinux:\n *   http://bellard.org/jslinux/\n *   Copyright (c) 2011 Fabrice Bellard\n *   The original design remains. The terminal itself\n *   has been extended to include xterm CSI codes, among\n *   other features.\n */var _CompositionHelper=_dereq_('./CompositionHelper.js');var _EventEmitter=_dereq_('./EventEmitter.js');var _Viewport=_dereq_('./Viewport.js');var _Clipboard=_dereq_('./handlers/Clipboard.js');var _Browser=_dereq_('./utils/Browser');var Browser=_interopRequireWildcard(_Browser);function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj;}else{var newObj={};if(obj!=null){for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))newObj[key]=obj[key];}}newObj.default=obj;return newObj;}}/**\n * Terminal Emulation References:\n *   http://vt100.net/\n *   http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n *   http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n *   http://invisible-island.net/vttest/\n *   http://www.inwap.com/pdp10/ansicode.txt\n *   http://linux.die.net/man/4/console_codes\n *   http://linux.die.net/man/7/urxvt\n */// Let it work inside Node.js for automated testing purposes.\nvar document=typeof window!='undefined'?window.document:null;/**\n * States\n */var normal=0,escaped=1,csi=2,osc=3,charset=4,dcs=5,ignore=6;/**\n * Terminal\n *//**\n * Creates a new `Terminal` object.\n *\n * @param {object} options An object containing a set of options, the available options are:\n *   - `cursorBlink` (boolean): Whether the terminal cursor blinks\n *   - `cols` (number): The number of columns of the terminal (horizontal size)\n *   - `rows` (number): The number of rows of the terminal (vertical size)\n *\n * @public\n * @class Xterm Xterm\n * @alias module:xterm/src/xterm\n */function Terminal(options){var self=this;if(!(this instanceof Terminal)){return new Terminal(arguments[0],arguments[1],arguments[2]);}self.browser=Browser;self.cancel=Terminal.cancel;_EventEmitter.EventEmitter.call(this);if(typeof options==='number'){options={cols:arguments[0],rows:arguments[1],handler:arguments[2]};}options=options||{};Object.keys(Terminal.defaults).forEach(function(key){if(options[key]==null){options[key]=Terminal.options[key];if(Terminal[key]!==Terminal.defaults[key]){options[key]=Terminal[key];}}self[key]=options[key];});if(options.colors.length===8){options.colors=options.colors.concat(Terminal._colors.slice(8));}else if(options.colors.length===16){options.colors=options.colors.concat(Terminal._colors.slice(16));}else if(options.colors.length===10){options.colors=options.colors.slice(0,-2).concat(Terminal._colors.slice(8,-2),options.colors.slice(-2));}else if(options.colors.length===18){options.colors=options.colors.concat(Terminal._colors.slice(16,-2),options.colors.slice(-2));}this.colors=options.colors;this.options=options;// this.context = options.context || window;\n// this.document = options.document || document;\nthis.parent=options.body||options.parent||(document?document.getElementsByTagName('body')[0]:null);this.cols=options.cols||options.geometry[0];this.rows=options.rows||options.geometry[1];this.geometry=[this.cols,this.rows];if(options.handler){this.on('data',options.handler);}/**\n   * The scroll position of the y cursor, ie. ybase + y = the y position within the entire\n   * buffer\n   */this.ybase=0;/**\n   * The scroll position of the viewport\n   */this.ydisp=0;/**\n   * The cursor's x position after ybase\n   */this.x=0;/**\n   * The cursor's y position after ybase\n   */this.y=0;/**\n   * Used to debounce the refresh function\n   */this.isRefreshing=false;/**\n   * Whether there is a full terminal refresh queued\n   */this.cursorState=0;this.cursorHidden=false;this.convertEol;this.state=0;this.queue='';this.scrollTop=0;this.scrollBottom=this.rows-1;this.customKeydownHandler=null;// modes\nthis.applicationKeypad=false;this.applicationCursor=false;this.originMode=false;this.insertMode=false;this.wraparoundMode=true;// defaults: xterm - true, vt100 - false\nthis.normal=null;// charset\nthis.charset=null;this.gcharset=null;this.glevel=0;this.charsets=[null];// mouse properties\nthis.decLocator;this.x10Mouse;this.vt200Mouse;this.vt300Mouse;this.normalMouse;this.mouseEvents;this.sendFocus;this.utfMouse;this.sgrMouse;this.urxvtMouse;// misc\nthis.element;this.children;this.refreshStart;this.refreshEnd;this.savedX;this.savedY;this.savedCols;// stream\nthis.readable=true;this.writable=true;this.defAttr=0<<18|257<<9|256<<0;this.curAttr=this.defAttr;this.params=[];this.currentParam=0;this.prefix='';this.postfix='';// leftover surrogate high from previous write invocation\nthis.surrogate_high='';/**\n   * An array of all lines in the entire buffer, including the prompt. The lines are array of\n   * characters which are 2-length arrays where [0] is an attribute and [1] is the character.\n   */this.lines=[];var i=this.rows;while(i--){this.lines.push(this.blankLine());}this.tabs;this.setupStops();// Store if user went browsing history in scrollback\nthis.userScrolling=false;}inherits(Terminal,_EventEmitter.EventEmitter);/**\n * back_color_erase feature for xterm.\n */Terminal.prototype.eraseAttr=function(){// if (this.is('screen')) return this.defAttr;\nreturn this.defAttr&~0x1ff|this.curAttr&0x1ff;};/**\n * Colors\n */// Colors 0-15\nTerminal.tangoColors=[// dark:\n'#2e3436','#cc0000','#4e9a06','#c4a000','#3465a4','#75507b','#06989a','#d3d7cf',// bright:\n'#555753','#ef2929','#8ae234','#fce94f','#729fcf','#ad7fa8','#34e2e2','#eeeeec'];// Colors 0-15 + 16-255\n// Much thanks to TooTallNate for writing this.\nTerminal.colors=function(){var colors=Terminal.tangoColors.slice(),r=[0x00,0x5f,0x87,0xaf,0xd7,0xff],i;// 16-231\ni=0;for(;i<216;i++){out(r[i/36%6|0],r[i/6%6|0],r[i%6]);}// 232-255 (grey)\ni=0;for(;i<24;i++){r=8+i*10;out(r,r,r);}function out(r,g,b){colors.push('#'+hex(r)+hex(g)+hex(b));}function hex(c){c=c.toString(16);return c.length<2?'0'+c:c;}return colors;}();Terminal._colors=Terminal.colors.slice();Terminal.vcolors=function(){var out=[],colors=Terminal.colors,i=0,color;for(;i<256;i++){color=parseInt(colors[i].substring(1),16);out.push([color>>16&0xff,color>>8&0xff,color&0xff]);}return out;}();/**\n * Options\n */Terminal.defaults={colors:Terminal.colors,theme:'default',convertEol:false,termName:'xterm',geometry:[80,24],cursorBlink:false,visualBell:false,popOnBell:false,scrollback:1000,screenKeys:false,debug:false,cancelEvents:false// programFeatures: false,\n// focusKeys: false,\n};Terminal.options={};Terminal.focus=null;each(keys(Terminal.defaults),function(key){Terminal[key]=Terminal.defaults[key];Terminal.options[key]=Terminal.defaults[key];});/**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */Terminal.prototype.focus=function(){return this.textarea.focus();};/**\n * Retrieves an option's value from the terminal.\n * @param {string} key The option key.\n */Terminal.prototype.getOption=function(key,value){if(!(key in Terminal.defaults)){throw new Error('No option with key \"'+key+'\"');}if(typeof this.options[key]!=='undefined'){return this.options[key];}return this[key];};/**\n * Sets an option on the terminal.\n * @param {string} key The option key.\n * @param {string} value The option value.\n */Terminal.prototype.setOption=function(key,value){if(!(key in Terminal.defaults)){throw new Error('No option with key \"'+key+'\"');}this[key]=value;this.options[key]=value;};/**\n * Binds the desired focus behavior on a given terminal object.\n *\n * @static\n */Terminal.bindFocus=function(term){on(term.textarea,'focus',function(ev){if(term.sendFocus){term.send('\\x1b[I');}term.element.classList.add('focus');term.showCursor();Terminal.focus=term;term.emit('focus',{terminal:term});});};/**\n * Blur the terminal. Delegates blur handling to the terminal's DOM element.\n */Terminal.prototype.blur=function(){return this.textarea.blur();};/**\n * Binds the desired blur behavior on a given terminal object.\n *\n * @static\n */Terminal.bindBlur=function(term){on(term.textarea,'blur',function(ev){term.refresh(term.y,term.y);if(term.sendFocus){term.send('\\x1b[O');}term.element.classList.remove('focus');Terminal.focus=null;term.emit('blur',{terminal:term});});};/**\n * Initialize default behavior\n */Terminal.prototype.initGlobal=function(){var term=this;Terminal.bindKeys(this);Terminal.bindFocus(this);Terminal.bindBlur(this);// Bind clipboard functionality\non(this.element,'copy',function(ev){_Clipboard.copyHandler.call(this,ev,term);});on(this.textarea,'paste',function(ev){_Clipboard.pasteHandler.call(this,ev,term);});function rightClickHandlerWrapper(ev){_Clipboard.rightClickHandler.call(this,ev,term);}if(term.browser.isFirefox){on(this.element,'mousedown',function(ev){if(ev.button==2){rightClickHandlerWrapper(ev);}});}else{on(this.element,'contextmenu',rightClickHandlerWrapper);}};/**\n * Apply key handling to the terminal\n */Terminal.bindKeys=function(term){on(term.element,'keydown',function(ev){if(document.activeElement!=this){return;}term.keyDown(ev);},true);on(term.element,'keypress',function(ev){if(document.activeElement!=this){return;}term.keyPress(ev);},true);on(term.element,'keyup',term.focus.bind(term));on(term.textarea,'keydown',function(ev){term.keyDown(ev);},true);on(term.textarea,'keypress',function(ev){term.keyPress(ev);// Truncate the textarea's value, since it is not needed\nthis.value='';},true);on(term.textarea,'compositionstart',term.compositionHelper.compositionstart.bind(term.compositionHelper));on(term.textarea,'compositionupdate',term.compositionHelper.compositionupdate.bind(term.compositionHelper));on(term.textarea,'compositionend',term.compositionHelper.compositionend.bind(term.compositionHelper));term.on('refresh',term.compositionHelper.updateCompositionElements.bind(term.compositionHelper));};/**\n * Insert the given row to the terminal or produce a new one\n * if no row argument is passed. Return the inserted row.\n * @param {HTMLElement} row (optional) The row to append to the terminal.\n */Terminal.prototype.insertRow=function(row){if((typeof row==='undefined'?'undefined':_typeof(row))!='object'){row=document.createElement('div');}this.rowContainer.appendChild(row);this.children.push(row);return row;};/**\n * Opens the terminal within an element.\n *\n * @param {HTMLElement} parent The element to create the terminal within.\n */Terminal.prototype.open=function(parent){var self=this,i=0,div;this.parent=parent||this.parent;if(!this.parent){throw new Error('Terminal requires a parent element.');}// Grab global elements\nthis.context=this.parent.ownerDocument.defaultView;this.document=this.parent.ownerDocument;this.body=this.document.getElementsByTagName('body')[0];//Create main element container\nthis.element=this.document.createElement('div');this.element.classList.add('terminal');this.element.classList.add('xterm');this.element.classList.add('xterm-theme-'+this.theme);this.element.style.height;this.element.setAttribute('tabindex',0);this.viewportElement=document.createElement('div');this.viewportElement.classList.add('xterm-viewport');this.element.appendChild(this.viewportElement);this.viewportScrollArea=document.createElement('div');this.viewportScrollArea.classList.add('xterm-scroll-area');this.viewportElement.appendChild(this.viewportScrollArea);// Create the container that will hold the lines of the terminal and then\n// produce the lines the lines.\nthis.rowContainer=document.createElement('div');this.rowContainer.classList.add('xterm-rows');this.element.appendChild(this.rowContainer);this.children=[];// Create the container that will hold helpers like the textarea for\n// capturing DOM Events. Then produce the helpers.\nthis.helperContainer=document.createElement('div');this.helperContainer.classList.add('xterm-helpers');// TODO: This should probably be inserted once it's filled to prevent an additional layout\nthis.element.appendChild(this.helperContainer);this.textarea=document.createElement('textarea');this.textarea.classList.add('xterm-helper-textarea');this.textarea.setAttribute('autocorrect','off');this.textarea.setAttribute('autocapitalize','off');this.textarea.setAttribute('spellcheck','false');this.textarea.tabIndex=0;this.textarea.addEventListener('focus',function(){self.emit('focus',{terminal:self});});this.textarea.addEventListener('blur',function(){self.emit('blur',{terminal:self});});this.helperContainer.appendChild(this.textarea);this.compositionView=document.createElement('div');this.compositionView.classList.add('composition-view');this.compositionHelper=new _CompositionHelper.CompositionHelper(this.textarea,this.compositionView,this);this.helperContainer.appendChild(this.compositionView);this.charMeasureElement=document.createElement('div');this.charMeasureElement.classList.add('xterm-char-measure-element');this.charMeasureElement.innerHTML='W';this.helperContainer.appendChild(this.charMeasureElement);for(;i<this.rows;i++){this.insertRow();}this.parent.appendChild(this.element);this.viewport=new _Viewport.Viewport(this,this.viewportElement,this.viewportScrollArea,this.charMeasureElement);// Draw the screen.\nthis.refresh(0,this.rows-1);// Initialize global actions that\n// need to be taken on the document.\nthis.initGlobal();// Ensure there is a Terminal.focus.\nthis.focus();on(this.element,'click',function(){var selection=document.getSelection(),collapsed=selection.isCollapsed,isRange=typeof collapsed=='boolean'?!collapsed:selection.type=='Range';if(!isRange){self.focus();}});// Listen for mouse events and translate\n// them into terminal mouse protocols.\nthis.bindMouse();// Figure out whether boldness affects\n// the character width of monospace fonts.\nif(Terminal.brokenBold==null){Terminal.brokenBold=isBoldBroken(this.document);}this.emit('open');};/**\n * Attempts to load an add-on using CommonJS or RequireJS (whichever is available).\n * @param {string} addon The name of the addon to load\n * @static\n */Terminal.loadAddon=function(addon,callback){if((typeof exports==='undefined'?'undefined':_typeof(exports))==='object'&&(typeof module==='undefined'?'undefined':_typeof(module))==='object'){// CommonJS\nreturn _dereq_('../addons/'+addon);}else if(typeof define=='function'){// RequireJS\nreturn _dereq_(['../addons/'+addon+'/'+addon],callback);}else{console.error('Cannot load a module without a CommonJS or RequireJS environment.');return false;}};/**\n * XTerm mouse events\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking\n * To better understand these\n * the xterm code is very helpful:\n * Relevant files:\n *   button.c, charproc.c, misc.c\n * Relevant functions in xterm/button.c:\n *   BtnCode, EmitButtonCode, EditorButton, SendMousePosition\n */Terminal.prototype.bindMouse=function(){var el=this.element,self=this,pressed=32;// mouseup, mousedown, wheel\n// left click: ^[[M 3<^[[M#3<\n// wheel up: ^[[M`3>\nfunction sendButton(ev){var button,pos;// get the xterm-style button\nbutton=getButton(ev);// get mouse coordinates\npos=getCoords(ev);if(!pos)return;sendEvent(button,pos);switch(ev.overrideType||ev.type){case'mousedown':pressed=button;break;case'mouseup':// keep it at the left\n// button, just in case.\npressed=32;break;case'wheel':// nothing. don't\n// interfere with\n// `pressed`.\nbreak;}}// motion example of a left click:\n// ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<\nfunction sendMove(ev){var button=pressed,pos;pos=getCoords(ev);if(!pos)return;// buttons marked as motions\n// are incremented by 32\nbutton+=32;sendEvent(button,pos);}// encode button and\n// position to characters\nfunction encode(data,ch){if(!self.utfMouse){if(ch===255)return data.push(0);if(ch>127)ch=127;data.push(ch);}else{if(ch===2047)return data.push(0);if(ch<127){data.push(ch);}else{if(ch>2047)ch=2047;data.push(0xC0|ch>>6);data.push(0x80|ch&0x3F);}}}// send a mouse event:\n// regular/utf8: ^[[M Cb Cx Cy\n// urxvt: ^[[ Cb ; Cx ; Cy M\n// sgr: ^[[ Cb ; Cx ; Cy M/m\n// vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \\r\n// locator: CSI P e ; P b ; P r ; P c ; P p & w\nfunction sendEvent(button,pos){// self.emit('mouse', {\n//   x: pos.x - 32,\n//   y: pos.x - 32,\n//   button: button\n// });\nif(self.vt300Mouse){// NOTE: Unstable.\n// http://www.vt100.net/docs/vt3xx-gp/chapter15.html\nbutton&=3;pos.x-=32;pos.y-=32;var data='\\x1b[24';if(button===0)data+='1';else if(button===1)data+='3';else if(button===2)data+='5';else if(button===3)return;else data+='0';data+='~['+pos.x+','+pos.y+']\\r';self.send(data);return;}if(self.decLocator){// NOTE: Unstable.\nbutton&=3;pos.x-=32;pos.y-=32;if(button===0)button=2;else if(button===1)button=4;else if(button===2)button=6;else if(button===3)button=3;self.send('\\x1b['+button+';'+(button===3?4:0)+';'+pos.y+';'+pos.x+';'+(pos.page||0)+'&w');return;}if(self.urxvtMouse){pos.x-=32;pos.y-=32;pos.x++;pos.y++;self.send('\\x1b['+button+';'+pos.x+';'+pos.y+'M');return;}if(self.sgrMouse){pos.x-=32;pos.y-=32;self.send('\\x1b[<'+((button&3)===3?button&~3:button)+';'+pos.x+';'+pos.y+((button&3)===3?'m':'M'));return;}var data=[];encode(data,button);encode(data,pos.x);encode(data,pos.y);self.send('\\x1b[M'+String.fromCharCode.apply(String,data));}function getButton(ev){var button,shift,meta,ctrl,mod;// two low bits:\n// 0 = left\n// 1 = middle\n// 2 = right\n// 3 = release\n// wheel up/down:\n// 1, and 2 - with 64 added\nswitch(ev.overrideType||ev.type){case'mousedown':button=ev.button!=null?+ev.button:ev.which!=null?ev.which-1:null;if(self.browser.isMSIE){button=button===1?0:button===4?1:button;}break;case'mouseup':button=3;break;case'DOMMouseScroll':button=ev.detail<0?64:65;break;case'wheel':button=ev.wheelDeltaY>0?64:65;break;}// next three bits are the modifiers:\n// 4 = shift, 8 = meta, 16 = control\nshift=ev.shiftKey?4:0;meta=ev.metaKey?8:0;ctrl=ev.ctrlKey?16:0;mod=shift|meta|ctrl;// no mods\nif(self.vt200Mouse){// ctrl only\nmod&=ctrl;}else if(!self.normalMouse){mod=0;}// increment to SP\nbutton=32+(mod<<2)+button;return button;}// mouse coordinates measured in cols/rows\nfunction getCoords(ev){var x,y,w,h,el;// ignore browsers without pageX for now\nif(ev.pageX==null)return;x=ev.pageX;y=ev.pageY;el=self.element;// should probably check offsetParent\n// but this is more portable\nwhile(el&&el!==self.document.documentElement){x-=el.offsetLeft;y-=el.offsetTop;el='offsetParent'in el?el.offsetParent:el.parentNode;}// convert to cols/rows\nw=self.element.clientWidth;h=self.element.clientHeight;x=Math.ceil(x/w*self.cols);y=Math.ceil(y/h*self.rows);// be sure to avoid sending\n// bad positions to the program\nif(x<0)x=0;if(x>self.cols)x=self.cols;if(y<0)y=0;if(y>self.rows)y=self.rows;// xterm sends raw bytes and\n// starts at 32 (SP) for each.\nx+=32;y+=32;return{x:x,y:y,type:'wheel'};}on(el,'mousedown',function(ev){if(!self.mouseEvents)return;// send the button\nsendButton(ev);// ensure focus\nself.focus();// fix for odd bug\n//if (self.vt200Mouse && !self.normalMouse) {\nif(self.vt200Mouse){ev.overrideType='mouseup';sendButton(ev);return self.cancel(ev);}// bind events\nif(self.normalMouse)on(self.document,'mousemove',sendMove);// x10 compatibility mode can't send button releases\nif(!self.x10Mouse){on(self.document,'mouseup',function up(ev){sendButton(ev);if(self.normalMouse)off(self.document,'mousemove',sendMove);off(self.document,'mouseup',up);return self.cancel(ev);});}return self.cancel(ev);});//if (self.normalMouse) {\n//  on(self.document, 'mousemove', sendMove);\n//}\non(el,'wheel',function(ev){if(!self.mouseEvents)return;if(self.x10Mouse||self.vt300Mouse||self.decLocator)return;sendButton(ev);return self.cancel(ev);});// allow wheel scrolling in\n// the shell for example\non(el,'wheel',function(ev){if(self.mouseEvents)return;self.viewport.onWheel(ev);return self.cancel(ev);});};/**\n * Destroys the terminal.\n */Terminal.prototype.destroy=function(){this.readable=false;this.writable=false;this._events={};this.handler=function(){};this.write=function(){};if(this.element.parentNode){this.element.parentNode.removeChild(this.element);}//this.emit('close');\n};/**\n * Flags used to render terminal text properly\n */Terminal.flags={BOLD:1,UNDERLINE:2,BLINK:4,INVERSE:8,INVISIBLE:16};/**\n * Refreshes (re-renders) terminal content within two rows (inclusive)\n *\n * Rendering Engine:\n *\n * In the screen buffer, each character is stored as a an array with a character\n * and a 32-bit integer:\n *   - First value: a utf-16 character.\n *   - Second value:\n *   - Next 9 bits: background color (0-511).\n *   - Next 9 bits: foreground color (0-511).\n *   - Next 14 bits: a mask for misc. flags:\n *     - 1=bold\n *     - 2=underline\n *     - 4=blink\n *     - 8=inverse\n *     - 16=invisible\n *\n * @param {number} start The row to start from (between 0 and terminal's height terminal - 1)\n * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)\n * @param {boolean} queue Whether the refresh should ran right now or be queued\n */Terminal.prototype.refresh=function(start,end,queue){var self=this;// queue defaults to true\nqueue=typeof queue=='undefined'?true:queue;/**\n   * The refresh queue allows refresh to execute only approximately 30 times a second. For\n   * commands that pass a significant amount of output to the write function, this prevents the\n   * terminal from maxing out the CPU and making the UI unresponsive. While commands can still\n   * run beyond what they do on the terminal, it is far better with a debounce in place as\n   * every single terminal manipulation does not need to be constructed in the DOM.\n   *\n   * A side-effect of this is that it makes ^C to interrupt a process seem more responsive.\n   */if(queue){// If refresh should be queued, order the refresh and return.\nif(this._refreshIsQueued){// If a refresh has already been queued, just order a full refresh next\nthis._fullRefreshNext=true;}else{setTimeout(function(){self.refresh(start,end,false);},34);this._refreshIsQueued=true;}return;}// If refresh should be run right now (not be queued), release the lock\nthis._refreshIsQueued=false;// If multiple refreshes were requested, make a full refresh.\nif(this._fullRefreshNext){start=0;end=this.rows-1;this._fullRefreshNext=false;// reset lock\n}var x,y,i,line,out,ch,ch_width,width,data,attr,bg,fg,flags,row,parent,focused=document.activeElement;// If this is a big refresh, remove the terminal rows from the DOM for faster calculations\nif(end-start>=this.rows/2){parent=this.element.parentNode;if(parent){this.element.removeChild(this.rowContainer);}}width=this.cols;y=start;if(end>=this.rows.length){this.log('`end` is too large. Most likely a bad CSR.');end=this.rows.length-1;}for(;y<=end;y++){row=y+this.ydisp;line=this.lines[row];out='';if(this.y===y-(this.ybase-this.ydisp)&&this.cursorState&&!this.cursorHidden){x=this.x;}else{x=-1;}attr=this.defAttr;i=0;for(;i<width;i++){data=line[i][0];ch=line[i][1];ch_width=line[i][2];if(!ch_width)continue;if(i===x)data=-1;if(data!==attr){if(attr!==this.defAttr){out+='</span>';}if(data!==this.defAttr){if(data===-1){out+='<span class=\"reverse-video terminal-cursor';if(this.cursorBlink){out+=' blinking';}out+='\">';}else{var classNames=[];bg=data&0x1ff;fg=data>>9&0x1ff;flags=data>>18;if(flags&Terminal.flags.BOLD){if(!Terminal.brokenBold){classNames.push('xterm-bold');}// See: XTerm*boldColors\nif(fg<8)fg+=8;}if(flags&Terminal.flags.UNDERLINE){classNames.push('xterm-underline');}if(flags&Terminal.flags.BLINK){classNames.push('xterm-blink');}// If inverse flag is on, then swap the foreground and background variables.\nif(flags&Terminal.flags.INVERSE){/* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */bg=[fg,fg=bg][0];// Should inverse just be before the\n// above boldColors effect instead?\nif(flags&1&&fg<8)fg+=8;}if(flags&Terminal.flags.INVISIBLE){classNames.push('xterm-hidden');}/**\n             * Weird situation: Invert flag used black foreground and white background results\n             * in invalid background color, positioned at the 256 index of the 256 terminal\n             * color map. Pin the colors manually in such a case.\n             *\n             * Source: https://github.com/sourcelair/xterm.js/issues/57\n             */if(flags&Terminal.flags.INVERSE){if(bg==257){bg=15;}if(fg==256){fg=0;}}if(bg<256){classNames.push('xterm-bg-color-'+bg);}if(fg<256){classNames.push('xterm-color-'+fg);}out+='<span';if(classNames.length){out+=' class=\"'+classNames.join(' ')+'\"';}out+='>';}}}switch(ch){case'&':out+='&amp;';break;case'<':out+='&lt;';break;case'>':out+='&gt;';break;default:if(ch<=' '){out+='&nbsp;';}else{out+=ch;}break;}attr=data;}if(attr!==this.defAttr){out+='</span>';}this.children[y].innerHTML=out;}if(parent){this.element.appendChild(this.rowContainer);}this.emit('refresh',{element:this.element,start:start,end:end});};/**\n * Display the cursor element\n */Terminal.prototype.showCursor=function(){if(!this.cursorState){this.cursorState=1;this.refresh(this.y,this.y);}};/**\n * Scroll the terminal\n */Terminal.prototype.scroll=function(){var row;if(++this.ybase===this.scrollback){this.ybase=this.ybase/2|0;this.lines=this.lines.slice(-(this.ybase+this.rows)+1);}if(!this.userScrolling){this.ydisp=this.ybase;}// last line\nrow=this.ybase+this.rows-1;// subtract the bottom scroll region\nrow-=this.rows-1-this.scrollBottom;if(row===this.lines.length){// potential optimization:\n// pushing is faster than splicing\n// when they amount to the same\n// behavior.\nthis.lines.push(this.blankLine());}else{// add our new line\nthis.lines.splice(row,0,this.blankLine());}if(this.scrollTop!==0){if(this.ybase!==0){this.ybase--;if(!this.userScrolling){this.ydisp=this.ybase;}}this.lines.splice(this.ybase+this.scrollTop,1);}// this.maxRange();\nthis.updateRange(this.scrollTop);this.updateRange(this.scrollBottom);this.emit('scroll',this.ydisp);};/**\n * Scroll the display of the terminal\n * @param {number} disp The number of lines to scroll down (negatives scroll up).\n * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollDisp. This is used\n * to avoid unwanted events being handled by the veiwport when the event was triggered from the\n * viewport originally.\n */Terminal.prototype.scrollDisp=function(disp,suppressScrollEvent){if(disp<0){this.userScrolling=true;}else if(disp+this.ydisp>=this.ybase){this.userScrolling=false;}this.ydisp+=disp;if(this.ydisp>this.ybase){this.ydisp=this.ybase;}else if(this.ydisp<0){this.ydisp=0;}if(!suppressScrollEvent){this.emit('scroll',this.ydisp);}this.refresh(0,this.rows-1);};/**\n * Scroll the display of the terminal by a number of pages.\n * @param {number} pageCount The number of pages to scroll (negative scrolls up).\n */Terminal.prototype.scrollPages=function(pageCount){this.scrollDisp(pageCount*(this.rows-1));};/**\n * Scrolls the display of the terminal to the top.\n */Terminal.prototype.scrollToTop=function(){this.scrollDisp(-this.ydisp);};/**\n * Scrolls the display of the terminal to the bottom.\n */Terminal.prototype.scrollToBottom=function(){this.scrollDisp(this.ybase-this.ydisp);};/**\n * Writes text to the terminal.\n * @param {string} text The text to write to the terminal.\n */Terminal.prototype.write=function(data){var l=data.length,i=0,j,cs,ch,code,low,ch_width,row;this.refreshStart=this.y;this.refreshEnd=this.y;// apply leftover surrogate high from last write\nif(this.surrogate_high){data=this.surrogate_high+data;this.surrogate_high='';}for(;i<l;i++){ch=data[i];// FIXME: higher chars than 0xa0 are not allowed in escape sequences\n//        --> maybe move to default\ncode=data.charCodeAt(i);if(0xD800<=code&&code<=0xDBFF){// we got a surrogate high\n// get surrogate low (next 2 bytes)\nlow=data.charCodeAt(i+1);if(isNaN(low)){// end of data stream, save surrogate high\nthis.surrogate_high=ch;continue;}code=(code-0xD800)*0x400+(low-0xDC00)+0x10000;ch+=data.charAt(i+1);}// surrogate low - already handled above\nif(0xDC00<=code&&code<=0xDFFF)continue;switch(this.state){case normal:switch(ch){case'\\x07':this.bell();break;// '\\n', '\\v', '\\f'\ncase'\\n':case'\\x0b':case'\\x0c':if(this.convertEol){this.x=0;}this.y++;if(this.y>this.scrollBottom){this.y--;this.scroll();}break;// '\\r'\ncase'\\r':this.x=0;break;// '\\b'\ncase'\\x08':if(this.x>0){this.x--;}break;// '\\t'\ncase'\\t':this.x=this.nextStop();break;// shift out\ncase'\\x0e':this.setgLevel(1);break;// shift in\ncase'\\x0f':this.setgLevel(0);break;// '\\e'\ncase'\\x1b':this.state=escaped;break;default:// ' '\n// calculate print space\n// expensive call, therefore we save width in line buffer\nch_width=wcwidth(code);if(ch>=' '){if(this.charset&&this.charset[ch]){ch=this.charset[ch];}row=this.y+this.ybase;// insert combining char in last cell\n// FIXME: needs handling after cursor jumps\nif(!ch_width&&this.x){// dont overflow left\nif(this.lines[row][this.x-1]){if(!this.lines[row][this.x-1][2]){// found empty cell after fullwidth, need to go 2 cells back\nif(this.lines[row][this.x-2])this.lines[row][this.x-2][1]+=ch;}else{this.lines[row][this.x-1][1]+=ch;}this.updateRange(this.y);}break;}// goto next line if ch would overflow\n// TODO: needs a global min terminal width of 2\nif(this.x+ch_width-1>=this.cols){// autowrap - DECAWM\nif(this.wraparoundMode){this.x=0;this.y++;if(this.y>this.scrollBottom){this.y--;this.scroll();}}else{this.x=this.cols-1;if(ch_width===2)// FIXME: check for xterm behavior\ncontinue;}}row=this.y+this.ybase;// insert mode: move characters to right\nif(this.insertMode){// do this twice for a fullwidth char\nfor(var moves=0;moves<ch_width;++moves){// remove last cell, if it's width is 0\n// we have to adjust the second last cell as well\nvar removed=this.lines[this.y+this.ybase].pop();if(removed[2]===0&&this.lines[row][this.cols-2]&&this.lines[row][this.cols-2][2]===2)this.lines[row][this.cols-2]=[this.curAttr,' ',1];// insert empty cell at cursor\nthis.lines[row].splice(this.x,0,[this.curAttr,' ',1]);}}this.lines[row][this.x]=[this.curAttr,ch,ch_width];this.x++;this.updateRange(this.y);// fullwidth char - set next cell width to zero and advance cursor\nif(ch_width===2){this.lines[row][this.x]=[this.curAttr,'',0];this.x++;}}break;}break;case escaped:switch(ch){// ESC [ Control Sequence Introducer ( CSI is 0x9b).\ncase'[':this.params=[];this.currentParam=0;this.state=csi;break;// ESC ] Operating System Command ( OSC is 0x9d).\ncase']':this.params=[];this.currentParam=0;this.state=osc;break;// ESC P Device Control String ( DCS is 0x90).\ncase'P':this.params=[];this.currentParam=0;this.state=dcs;break;// ESC _ Application Program Command ( APC is 0x9f).\ncase'_':this.state=ignore;break;// ESC ^ Privacy Message ( PM is 0x9e).\ncase'^':this.state=ignore;break;// ESC c Full Reset (RIS).\ncase'c':this.reset();break;// ESC E Next Line ( NEL is 0x85).\n// ESC D Index ( IND is 0x84).\ncase'E':this.x=0;;case'D':this.index();break;// ESC M Reverse Index ( RI is 0x8d).\ncase'M':this.reverseIndex();break;// ESC % Select default/utf-8 character set.\n// @ = default, G = utf-8\ncase'%'://this.charset = null;\nthis.setgLevel(0);this.setgCharset(0,Terminal.charsets.US);this.state=normal;i++;break;// ESC (,),*,+,-,. Designate G0-G2 Character Set.\ncase'(':// <-- this seems to get all the attention\ncase')':case'*':case'+':case'-':case'.':switch(ch){case'(':this.gcharset=0;break;case')':this.gcharset=1;break;case'*':this.gcharset=2;break;case'+':this.gcharset=3;break;case'-':this.gcharset=1;break;case'.':this.gcharset=2;break;}this.state=charset;break;// Designate G3 Character Set (VT300).\n// A = ISO Latin-1 Supplemental.\n// Not implemented.\ncase'/':this.gcharset=3;this.state=charset;i--;break;// ESC N\n// Single Shift Select of G2 Character Set\n// ( SS2 is 0x8e). This affects next character only.\ncase'N':break;// ESC O\n// Single Shift Select of G3 Character Set\n// ( SS3 is 0x8f). This affects next character only.\ncase'O':break;// ESC n\n// Invoke the G2 Character Set as GL (LS2).\ncase'n':this.setgLevel(2);break;// ESC o\n// Invoke the G3 Character Set as GL (LS3).\ncase'o':this.setgLevel(3);break;// ESC |\n// Invoke the G3 Character Set as GR (LS3R).\ncase'|':this.setgLevel(3);break;// ESC }\n// Invoke the G2 Character Set as GR (LS2R).\ncase'}':this.setgLevel(2);break;// ESC ~\n// Invoke the G1 Character Set as GR (LS1R).\ncase'~':this.setgLevel(1);break;// ESC 7 Save Cursor (DECSC).\ncase'7':this.saveCursor();this.state=normal;break;// ESC 8 Restore Cursor (DECRC).\ncase'8':this.restoreCursor();this.state=normal;break;// ESC # 3 DEC line height/width\ncase'#':this.state=normal;i++;break;// ESC H Tab Set (HTS is 0x88).\ncase'H':this.tabSet();break;// ESC = Application Keypad (DECKPAM).\ncase'=':this.log('Serial port requested application keypad.');this.applicationKeypad=true;this.viewport.syncScrollArea();this.state=normal;break;// ESC > Normal Keypad (DECKPNM).\ncase'>':this.log('Switching back to normal keypad.');this.applicationKeypad=false;this.viewport.syncScrollArea();this.state=normal;break;default:this.state=normal;this.error('Unknown ESC control: %s.',ch);break;}break;case charset:switch(ch){case'0':// DEC Special Character and Line Drawing Set.\ncs=Terminal.charsets.SCLD;break;case'A':// UK\ncs=Terminal.charsets.UK;break;case'B':// United States (USASCII).\ncs=Terminal.charsets.US;break;case'4':// Dutch\ncs=Terminal.charsets.Dutch;break;case'C':// Finnish\ncase'5':cs=Terminal.charsets.Finnish;break;case'R':// French\ncs=Terminal.charsets.French;break;case'Q':// FrenchCanadian\ncs=Terminal.charsets.FrenchCanadian;break;case'K':// German\ncs=Terminal.charsets.German;break;case'Y':// Italian\ncs=Terminal.charsets.Italian;break;case'E':// NorwegianDanish\ncase'6':cs=Terminal.charsets.NorwegianDanish;break;case'Z':// Spanish\ncs=Terminal.charsets.Spanish;break;case'H':// Swedish\ncase'7':cs=Terminal.charsets.Swedish;break;case'=':// Swiss\ncs=Terminal.charsets.Swiss;break;case'/':// ISOLatin (actually /A)\ncs=Terminal.charsets.ISOLatin;i++;break;default:// Default\ncs=Terminal.charsets.US;break;}this.setgCharset(this.gcharset,cs);this.gcharset=null;this.state=normal;break;case osc:// OSC Ps ; Pt ST\n// OSC Ps ; Pt BEL\n//   Set Text Parameters.\nif(ch==='\\x1b'||ch==='\\x07'){if(ch==='\\x1b')i++;this.params.push(this.currentParam);switch(this.params[0]){case 0:case 1:case 2:if(this.params[1]){this.title=this.params[1];this.handleTitle(this.title);}break;case 3:// set X property\nbreak;case 4:case 5:// change dynamic colors\nbreak;case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:// change dynamic ui colors\nbreak;case 46:// change log file\nbreak;case 50:// dynamic font\nbreak;case 51:// emacs shell\nbreak;case 52:// manipulate selection data\nbreak;case 104:case 105:case 110:case 111:case 112:case 113:case 114:case 115:case 116:case 117:case 118:// reset colors\nbreak;}this.params=[];this.currentParam=0;this.state=normal;}else{if(!this.params.length){if(ch>='0'&&ch<='9'){this.currentParam=this.currentParam*10+ch.charCodeAt(0)-48;}else if(ch===';'){this.params.push(this.currentParam);this.currentParam='';}}else{this.currentParam+=ch;}}break;case csi:// '?', '>', '!'\nif(ch==='?'||ch==='>'||ch==='!'){this.prefix=ch;break;}// 0 - 9\nif(ch>='0'&&ch<='9'){this.currentParam=this.currentParam*10+ch.charCodeAt(0)-48;break;}// '$', '\"', ' ', '\\''\nif(ch==='$'||ch==='\"'||ch===' '||ch==='\\''){this.postfix=ch;break;}this.params.push(this.currentParam);this.currentParam=0;// ';'\nif(ch===';')break;this.state=normal;switch(ch){// CSI Ps A\n// Cursor Up Ps Times (default = 1) (CUU).\ncase'A':this.cursorUp(this.params);break;// CSI Ps B\n// Cursor Down Ps Times (default = 1) (CUD).\ncase'B':this.cursorDown(this.params);break;// CSI Ps C\n// Cursor Forward Ps Times (default = 1) (CUF).\ncase'C':this.cursorForward(this.params);break;// CSI Ps D\n// Cursor Backward Ps Times (default = 1) (CUB).\ncase'D':this.cursorBackward(this.params);break;// CSI Ps ; Ps H\n// Cursor Position [row;column] (default = [1,1]) (CUP).\ncase'H':this.cursorPos(this.params);break;// CSI Ps J  Erase in Display (ED).\ncase'J':this.eraseInDisplay(this.params);break;// CSI Ps K  Erase in Line (EL).\ncase'K':this.eraseInLine(this.params);break;// CSI Pm m  Character Attributes (SGR).\ncase'm':if(!this.prefix){this.charAttributes(this.params);}break;// CSI Ps n  Device Status Report (DSR).\ncase'n':if(!this.prefix){this.deviceStatus(this.params);}break;/**\n             * Additions\n             */// CSI Ps @\n// Insert Ps (Blank) Character(s) (default = 1) (ICH).\ncase'@':this.insertChars(this.params);break;// CSI Ps E\n// Cursor Next Line Ps Times (default = 1) (CNL).\ncase'E':this.cursorNextLine(this.params);break;// CSI Ps F\n// Cursor Preceding Line Ps Times (default = 1) (CNL).\ncase'F':this.cursorPrecedingLine(this.params);break;// CSI Ps G\n// Cursor Character Absolute  [column] (default = [row,1]) (CHA).\ncase'G':this.cursorCharAbsolute(this.params);break;// CSI Ps L\n// Insert Ps Line(s) (default = 1) (IL).\ncase'L':this.insertLines(this.params);break;// CSI Ps M\n// Delete Ps Line(s) (default = 1) (DL).\ncase'M':this.deleteLines(this.params);break;// CSI Ps P\n// Delete Ps Character(s) (default = 1) (DCH).\ncase'P':this.deleteChars(this.params);break;// CSI Ps X\n// Erase Ps Character(s) (default = 1) (ECH).\ncase'X':this.eraseChars(this.params);break;// CSI Pm `  Character Position Absolute\n//   [column] (default = [row,1]) (HPA).\ncase'`':this.charPosAbsolute(this.params);break;// 141 61 a * HPR -\n// Horizontal Position Relative\ncase'a':this.HPositionRelative(this.params);break;// CSI P s c\n// Send Device Attributes (Primary DA).\n// CSI > P s c\n// Send Device Attributes (Secondary DA)\ncase'c':this.sendDeviceAttributes(this.params);break;// CSI Pm d\n// Line Position Absolute  [row] (default = [1,column]) (VPA).\ncase'd':this.linePosAbsolute(this.params);break;// 145 65 e * VPR - Vertical Position Relative\ncase'e':this.VPositionRelative(this.params);break;// CSI Ps ; Ps f\n//   Horizontal and Vertical Position [row;column] (default =\n//   [1,1]) (HVP).\ncase'f':this.HVPosition(this.params);break;// CSI Pm h  Set Mode (SM).\n// CSI ? Pm h - mouse escape codes, cursor escape codes\ncase'h':this.setMode(this.params);break;// CSI Pm l  Reset Mode (RM).\n// CSI ? Pm l\ncase'l':this.resetMode(this.params);break;// CSI Ps ; Ps r\n//   Set Scrolling Region [top;bottom] (default = full size of win-\n//   dow) (DECSTBM).\n// CSI ? Pm r\ncase'r':this.setScrollRegion(this.params);break;// CSI s\n//   Save cursor (ANSI.SYS).\ncase's':this.saveCursor(this.params);break;// CSI u\n//   Restore cursor (ANSI.SYS).\ncase'u':this.restoreCursor(this.params);break;/**\n             * Lesser Used\n             */// CSI Ps I\n// Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\ncase'I':this.cursorForwardTab(this.params);break;// CSI Ps S  Scroll up Ps lines (default = 1) (SU).\ncase'S':this.scrollUp(this.params);break;// CSI Ps T  Scroll down Ps lines (default = 1) (SD).\n// CSI Ps ; Ps ; Ps ; Ps ; Ps T\n// CSI > Ps; Ps T\ncase'T':// if (this.prefix === '>') {\n//   this.resetTitleModes(this.params);\n//   break;\n// }\n// if (this.params.length > 2) {\n//   this.initMouseTracking(this.params);\n//   break;\n// }\nif(this.params.length<2&&!this.prefix){this.scrollDown(this.params);}break;// CSI Ps Z\n// Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\ncase'Z':this.cursorBackwardTab(this.params);break;// CSI Ps b  Repeat the preceding graphic character Ps times (REP).\ncase'b':this.repeatPrecedingCharacter(this.params);break;// CSI Ps g  Tab Clear (TBC).\ncase'g':this.tabClear(this.params);break;// CSI Pm i  Media Copy (MC).\n// CSI ? Pm i\n// case 'i':\n//   this.mediaCopy(this.params);\n//   break;\n// CSI Pm m  Character Attributes (SGR).\n// CSI > Ps; Ps m\n// case 'm': // duplicate\n//   if (this.prefix === '>') {\n//     this.setResources(this.params);\n//   } else {\n//     this.charAttributes(this.params);\n//   }\n//   break;\n// CSI Ps n  Device Status Report (DSR).\n// CSI > Ps n\n// case 'n': // duplicate\n//   if (this.prefix === '>') {\n//     this.disableModifiers(this.params);\n//   } else {\n//     this.deviceStatus(this.params);\n//   }\n//   break;\n// CSI > Ps p  Set pointer mode.\n// CSI ! p   Soft terminal reset (DECSTR).\n// CSI Ps$ p\n//   Request ANSI mode (DECRQM).\n// CSI ? Ps$ p\n//   Request DEC private mode (DECRQM).\n// CSI Ps ; Ps \" p\ncase'p':switch(this.prefix){// case '>':\n//   this.setPointerMode(this.params);\n//   break;\ncase'!':this.softReset(this.params);break;// case '?':\n//   if (this.postfix === '$') {\n//     this.requestPrivateMode(this.params);\n//   }\n//   break;\n// default:\n//   if (this.postfix === '\"') {\n//     this.setConformanceLevel(this.params);\n//   } else if (this.postfix === '$') {\n//     this.requestAnsiMode(this.params);\n//   }\n//   break;\n}break;// CSI Ps q  Load LEDs (DECLL).\n// CSI Ps SP q\n// CSI Ps \" q\n// case 'q':\n//   if (this.postfix === ' ') {\n//     this.setCursorStyle(this.params);\n//     break;\n//   }\n//   if (this.postfix === '\"') {\n//     this.setCharProtectionAttr(this.params);\n//     break;\n//   }\n//   this.loadLEDs(this.params);\n//   break;\n// CSI Ps ; Ps r\n//   Set Scrolling Region [top;bottom] (default = full size of win-\n//   dow) (DECSTBM).\n// CSI ? Pm r\n// CSI Pt; Pl; Pb; Pr; Ps$ r\n// case 'r': // duplicate\n//   if (this.prefix === '?') {\n//     this.restorePrivateValues(this.params);\n//   } else if (this.postfix === '$') {\n//     this.setAttrInRectangle(this.params);\n//   } else {\n//     this.setScrollRegion(this.params);\n//   }\n//   break;\n// CSI s     Save cursor (ANSI.SYS).\n// CSI ? Pm s\n// case 's': // duplicate\n//   if (this.prefix === '?') {\n//     this.savePrivateValues(this.params);\n//   } else {\n//     this.saveCursor(this.params);\n//   }\n//   break;\n// CSI Ps ; Ps ; Ps t\n// CSI Pt; Pl; Pb; Pr; Ps$ t\n// CSI > Ps; Ps t\n// CSI Ps SP t\n// case 't':\n//   if (this.postfix === '$') {\n//     this.reverseAttrInRectangle(this.params);\n//   } else if (this.postfix === ' ') {\n//     this.setWarningBellVolume(this.params);\n//   } else {\n//     if (this.prefix === '>') {\n//       this.setTitleModeFeature(this.params);\n//     } else {\n//       this.manipulateWindow(this.params);\n//     }\n//   }\n//   break;\n// CSI u     Restore cursor (ANSI.SYS).\n// CSI Ps SP u\n// case 'u': // duplicate\n//   if (this.postfix === ' ') {\n//     this.setMarginBellVolume(this.params);\n//   } else {\n//     this.restoreCursor(this.params);\n//   }\n//   break;\n// CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v\n// case 'v':\n//   if (this.postfix === '$') {\n//     this.copyRectagle(this.params);\n//   }\n//   break;\n// CSI Pt ; Pl ; Pb ; Pr ' w\n// case 'w':\n//   if (this.postfix === '\\'') {\n//     this.enableFilterRectangle(this.params);\n//   }\n//   break;\n// CSI Ps x  Request Terminal Parameters (DECREQTPARM).\n// CSI Ps x  Select Attribute Change Extent (DECSACE).\n// CSI Pc; Pt; Pl; Pb; Pr$ x\n// case 'x':\n//   if (this.postfix === '$') {\n//     this.fillRectangle(this.params);\n//   } else {\n//     this.requestParameters(this.params);\n//     //this.__(this.params);\n//   }\n//   break;\n// CSI Ps ; Pu ' z\n// CSI Pt; Pl; Pb; Pr$ z\n// case 'z':\n//   if (this.postfix === '\\'') {\n//     this.enableLocatorReporting(this.params);\n//   } else if (this.postfix === '$') {\n//     this.eraseRectangle(this.params);\n//   }\n//   break;\n// CSI Pm ' {\n// CSI Pt; Pl; Pb; Pr$ {\n// case '{':\n//   if (this.postfix === '\\'') {\n//     this.setLocatorEvents(this.params);\n//   } else if (this.postfix === '$') {\n//     this.selectiveEraseRectangle(this.params);\n//   }\n//   break;\n// CSI Ps ' |\n// case '|':\n//   if (this.postfix === '\\'') {\n//     this.requestLocatorPosition(this.params);\n//   }\n//   break;\n// CSI P m SP }\n// Insert P s Column(s) (default = 1) (DECIC), VT420 and up.\n// case '}':\n//   if (this.postfix === ' ') {\n//     this.insertColumns(this.params);\n//   }\n//   break;\n// CSI P m SP ~\n// Delete P s Column(s) (default = 1) (DECDC), VT420 and up\n// case '~':\n//   if (this.postfix === ' ') {\n//     this.deleteColumns(this.params);\n//   }\n//   break;\ndefault:this.error('Unknown CSI code: %s.',ch);break;}this.prefix='';this.postfix='';break;case dcs:if(ch==='\\x1b'||ch==='\\x07'){if(ch==='\\x1b')i++;switch(this.prefix){// User-Defined Keys (DECUDK).\ncase'':break;// Request Status String (DECRQSS).\n// test: echo -e '\\eP$q\"p\\e\\\\'\ncase'$q':var pt=this.currentParam,valid=false;switch(pt){// DECSCA\ncase'\"q':pt='0\"q';break;// DECSCL\ncase'\"p':pt='61\"p';break;// DECSTBM\ncase'r':pt=''+(this.scrollTop+1)+';'+(this.scrollBottom+1)+'r';break;// SGR\ncase'm':pt='0m';break;default:this.error('Unknown DCS Pt: %s.',pt);pt='';break;}this.send('\\x1bP'+ +valid+'$r'+pt+'\\x1b\\\\');break;// Set Termcap/Terminfo Data (xterm, experimental).\ncase'+p':break;// Request Termcap/Terminfo String (xterm, experimental)\n// Regular xterm does not even respond to this sequence.\n// This can cause a small glitch in vim.\n// test: echo -ne '\\eP+q6b64\\e\\\\'\ncase'+q':var pt=this.currentParam,valid=false;this.send('\\x1bP'+ +valid+'+r'+pt+'\\x1b\\\\');break;default:this.error('Unknown DCS prefix: %s.',this.prefix);break;}this.currentParam=0;this.prefix='';this.state=normal;}else if(!this.currentParam){if(!this.prefix&&ch!=='$'&&ch!=='+'){this.currentParam=ch;}else if(this.prefix.length===2){this.currentParam=ch;}else{this.prefix+=ch;}}else{this.currentParam+=ch;}break;case ignore:// For PM and APC.\nif(ch==='\\x1b'||ch==='\\x07'){if(ch==='\\x1b')i++;this.state=normal;}break;}}this.updateRange(this.y);this.refresh(this.refreshStart,this.refreshEnd);};/**\n * Writes text to the terminal, followed by a break line character (\\n).\n * @param {string} text The text to write to the terminal.\n */Terminal.prototype.writeln=function(data){this.write(data+'\\r\\n');};/**\n * Attaches a custom keydown handler which is run before keys are processed, giving consumers of\n * xterm.js ultimate control as to what keys should be processed by the terminal and what keys\n * should not.\n * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a\n *   function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent\n *   the default action. The function returns whether the event should be processed by xterm.js.\n */Terminal.prototype.attachCustomKeydownHandler=function(customKeydownHandler){this.customKeydownHandler=customKeydownHandler;};/**\n * Handle a keydown event\n * Key Resources:\n *   - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keydown event to be handled.\n */Terminal.prototype.keyDown=function(ev){// Scroll down to prompt, whenever the user presses a key.\nif(this.ybase!==this.ydisp){this.scrollToBottom();}if(this.customKeydownHandler&&this.customKeydownHandler(ev)===false){return false;}if(!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)){return false;}var self=this;var result=this.evaluateKeyEscapeSequence(ev);if(result.scrollDisp){this.scrollDisp(result.scrollDisp);return this.cancel(ev,true);}if(isThirdLevelShift(this,ev)){return true;}if(result.cancel){// The event is canceled at the end already, is this necessary?\nthis.cancel(ev,true);}if(!result.key){return true;}this.emit('keydown',ev);this.emit('key',result.key,ev);this.showCursor();this.handler(result.key);return this.cancel(ev,true);};/**\n * Returns an object that determines how a KeyboardEvent should be handled. The key of the\n * returned value is the new key code to pass to the PTY.\n *\n * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence.\n */Terminal.prototype.evaluateKeyEscapeSequence=function(ev){var result={// Whether to cancel event propogation (NOTE: this may not be needed since the event is\n// canceled at the end of keyDown\ncancel:false,// The new key even to emit\nkey:undefined,// The number of characters to scroll, if this is defined it will cancel the event\nscrollDisp:undefined};var modifiers=ev.shiftKey<<0|ev.altKey<<1|ev.ctrlKey<<2|ev.metaKey<<3;switch(ev.keyCode){case 8:// backspace\nif(ev.shiftKey){result.key='\\x08';// ^H\nbreak;}result.key='\\x7f';// ^?\nbreak;case 9:// tab\nif(ev.shiftKey){result.key='\\x1b[Z';break;}result.key='\\t';result.cancel=true;break;case 13:// return/enter\nresult.key='\\r';result.cancel=true;break;case 27:// escape\nresult.key='\\x1b';result.cancel=true;break;case 37:// left-arrow\nif(modifiers){result.key='\\x1b[1;'+(modifiers+1)+'D';// HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards\n// http://unix.stackexchange.com/a/108106\nif(result.key=='\\x1b[1;3D'){result.key='\\x1b[1;5D';}}else if(this.applicationCursor){result.key='\\x1bOD';}else{result.key='\\x1b[D';}break;case 39:// right-arrow\nif(modifiers){result.key='\\x1b[1;'+(modifiers+1)+'C';// HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward\n// http://unix.stackexchange.com/a/108106\nif(result.key=='\\x1b[1;3C'){result.key='\\x1b[1;5C';}}else if(this.applicationCursor){result.key='\\x1bOC';}else{result.key='\\x1b[C';}break;case 38:// up-arrow\nif(modifiers){result.key='\\x1b[1;'+(modifiers+1)+'A';// HACK: Make Alt + up-arrow behave like Ctrl + up-arrow\n// http://unix.stackexchange.com/a/108106\nif(result.key=='\\x1b[1;3A'){result.key='\\x1b[1;5A';}}else if(this.applicationCursor){result.key='\\x1bOA';}else{result.key='\\x1b[A';}break;case 40:// down-arrow\nif(modifiers){result.key='\\x1b[1;'+(modifiers+1)+'B';// HACK: Make Alt + down-arrow behave like Ctrl + down-arrow\n// http://unix.stackexchange.com/a/108106\nif(result.key=='\\x1b[1;3B'){result.key='\\x1b[1;5B';}}else if(this.applicationCursor){result.key='\\x1bOB';}else{result.key='\\x1b[B';}break;case 45:// insert\nif(!ev.shiftKey&&!ev.ctrlKey){// <Ctrl> or <Shift> + <Insert> are used to\n// copy-paste on some systems.\nresult.key='\\x1b[2~';}break;case 46:// delete\nif(modifiers){result.key='\\x1b[3;'+(modifiers+1)+'~';}else{result.key='\\x1b[3~';}break;case 36:// home\nif(modifiers)result.key='\\x1b[1;'+(modifiers+1)+'H';else if(this.applicationCursor)result.key='\\x1bOH';else result.key='\\x1b[H';break;case 35:// end\nif(modifiers)result.key='\\x1b[1;'+(modifiers+1)+'F';else if(this.applicationCursor)result.key='\\x1bOF';else result.key='\\x1b[F';break;case 33:// page up\nif(ev.shiftKey){result.scrollDisp=-(this.rows-1);}else{result.key='\\x1b[5~';}break;case 34:// page down\nif(ev.shiftKey){result.scrollDisp=this.rows-1;}else{result.key='\\x1b[6~';}break;case 112:// F1-F12\nif(modifiers){result.key='\\x1b[1;'+(modifiers+1)+'P';}else{result.key='\\x1bOP';}break;case 113:if(modifiers){result.key='\\x1b[1;'+(modifiers+1)+'Q';}else{result.key='\\x1bOQ';}break;case 114:if(modifiers){result.key='\\x1b[1;'+(modifiers+1)+'R';}else{result.key='\\x1bOR';}break;case 115:if(modifiers){result.key='\\x1b[1;'+(modifiers+1)+'S';}else{result.key='\\x1bOS';}break;case 116:if(modifiers){result.key='\\x1b[15;'+(modifiers+1)+'~';}else{result.key='\\x1b[15~';}break;case 117:if(modifiers){result.key='\\x1b[17;'+(modifiers+1)+'~';}else{result.key='\\x1b[17~';}break;case 118:if(modifiers){result.key='\\x1b[18;'+(modifiers+1)+'~';}else{result.key='\\x1b[18~';}break;case 119:if(modifiers){result.key='\\x1b[19;'+(modifiers+1)+'~';}else{result.key='\\x1b[19~';}break;case 120:if(modifiers){result.key='\\x1b[20;'+(modifiers+1)+'~';}else{result.key='\\x1b[20~';}break;case 121:if(modifiers){result.key='\\x1b[21;'+(modifiers+1)+'~';}else{result.key='\\x1b[21~';}break;case 122:if(modifiers){result.key='\\x1b[23;'+(modifiers+1)+'~';}else{result.key='\\x1b[23~';}break;case 123:if(modifiers){result.key='\\x1b[24;'+(modifiers+1)+'~';}else{result.key='\\x1b[24~';}break;default:// a-z and space\nif(ev.ctrlKey&&!ev.shiftKey&&!ev.altKey&&!ev.metaKey){if(ev.keyCode>=65&&ev.keyCode<=90){result.key=String.fromCharCode(ev.keyCode-64);}else if(ev.keyCode===32){// NUL\nresult.key=String.fromCharCode(0);}else if(ev.keyCode>=51&&ev.keyCode<=55){// escape, file sep, group sep, record sep, unit sep\nresult.key=String.fromCharCode(ev.keyCode-51+27);}else if(ev.keyCode===56){// delete\nresult.key=String.fromCharCode(127);}else if(ev.keyCode===219){// ^[ - escape\nresult.key=String.fromCharCode(27);}else if(ev.keyCode===221){// ^] - group sep\nresult.key=String.fromCharCode(29);}}else if(!this.browser.isMac&&ev.altKey&&!ev.ctrlKey&&!ev.metaKey){// On Mac this is a third level shift. Use <Esc> instead.\nif(ev.keyCode>=65&&ev.keyCode<=90){result.key='\\x1b'+String.fromCharCode(ev.keyCode+32);}else if(ev.keyCode===192){result.key='\\x1b`';}else if(ev.keyCode>=48&&ev.keyCode<=57){result.key='\\x1b'+(ev.keyCode-48);}}break;}return result;};/**\n * Set the G level of the terminal\n * @param g\n */Terminal.prototype.setgLevel=function(g){this.glevel=g;this.charset=this.charsets[g];};/**\n * Set the charset for the given G level of the terminal\n * @param g\n * @param charset\n */Terminal.prototype.setgCharset=function(g,charset){this.charsets[g]=charset;if(this.glevel===g){this.charset=charset;}};/**\n * Handle a keypress event.\n * Key Resources:\n *   - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keypress event to be handled.\n */Terminal.prototype.keyPress=function(ev){var key;this.cancel(ev);if(ev.charCode){key=ev.charCode;}else if(ev.which==null){key=ev.keyCode;}else if(ev.which!==0&&ev.charCode!==0){key=ev.which;}else{return false;}if(!key||(ev.altKey||ev.ctrlKey||ev.metaKey)&&!isThirdLevelShift(this,ev)){return false;}key=String.fromCharCode(key);this.emit('keypress',key,ev);this.emit('key',key,ev);this.showCursor();this.handler(key);return false;};/**\n * Send data for handling to the terminal\n * @param {string} data\n */Terminal.prototype.send=function(data){var self=this;if(!this.queue){setTimeout(function(){self.handler(self.queue);self.queue='';},1);}this.queue+=data;};/**\n * Ring the bell.\n * Note: We could do sweet things with webaudio here\n */Terminal.prototype.bell=function(){if(!this.visualBell)return;var self=this;this.element.style.borderColor='white';setTimeout(function(){self.element.style.borderColor='';},10);if(this.popOnBell)this.focus();};/**\n * Log the current state to the console.\n */Terminal.prototype.log=function(){if(!this.debug)return;if(!this.context.console||!this.context.console.log)return;var args=Array.prototype.slice.call(arguments);this.context.console.log.apply(this.context.console,args);};/**\n * Log the current state as error to the console.\n */Terminal.prototype.error=function(){if(!this.debug)return;if(!this.context.console||!this.context.console.error)return;var args=Array.prototype.slice.call(arguments);this.context.console.error.apply(this.context.console,args);};/**\n * Resizes the terminal.\n *\n * @param {number} x The number of columns to resize to.\n * @param {number} y The number of rows to resize to.\n */Terminal.prototype.resize=function(x,y){var line,el,i,j,ch,addToY;if(x===this.cols&&y===this.rows){return;}if(x<1)x=1;if(y<1)y=1;// resize cols\nj=this.cols;if(j<x){ch=[this.defAttr,' ',1];// does xterm use the default attr?\ni=this.lines.length;while(i--){while(this.lines[i].length<x){this.lines[i].push(ch);}}}else{// (j > x)\ni=this.lines.length;while(i--){while(this.lines[i].length>x){this.lines[i].pop();}}}this.setupStops(j);this.cols=x;// resize rows\nj=this.rows;addToY=0;if(j<y){el=this.element;while(j++<y){// y is rows, not this.y\nif(this.lines.length<y+this.ybase){if(this.ybase>0&&this.lines.length<=this.ybase+this.y+addToY+1){// There is room above the buffer and there are no empty elements below the line,\n// scroll up\nthis.ybase--;addToY++;if(this.ydisp>0){// Viewport is at the top of the buffer, must increase downwards\nthis.ydisp--;}}else{// Add a blank line if there is no buffer left at the top to scroll to, or if there\n// are blank lines after the cursor\nthis.lines.push(this.blankLine());}}if(this.children.length<y){this.insertRow();}}}else{// (j > y)\nwhile(j-->y){if(this.lines.length>y+this.ybase){if(this.lines.length>this.ybase+this.y+1){// The line is a blank line below the cursor, remove it\nthis.lines.pop();}else{// The line is the cursor, scroll down\nthis.ybase++;this.ydisp++;}}if(this.children.length>y){el=this.children.shift();if(!el)continue;el.parentNode.removeChild(el);}}}this.rows=y;// Make sure that the cursor stays on screen\nif(this.y>=y){this.y=y-1;}if(addToY){this.y+=addToY;}if(this.x>=x){this.x=x-1;}this.scrollTop=0;this.scrollBottom=y-1;this.refresh(0,this.rows-1);this.normal=null;this.geometry=[this.cols,this.rows];this.emit('resize',{terminal:this,cols:x,rows:y});};/**\n * Updates the range of rows to refresh\n * @param {number} y The number of rows to refresh next.\n */Terminal.prototype.updateRange=function(y){if(y<this.refreshStart)this.refreshStart=y;if(y>this.refreshEnd)this.refreshEnd=y;// if (y > this.refreshEnd) {\n//   this.refreshEnd = y;\n//   if (y > this.rows - 1) {\n//     this.refreshEnd = this.rows - 1;\n//   }\n// }\n};/**\n * Set the range of refreshing to the maximum value\n */Terminal.prototype.maxRange=function(){this.refreshStart=0;this.refreshEnd=this.rows-1;};/**\n * Setup the tab stops.\n * @param {number} i\n */Terminal.prototype.setupStops=function(i){if(i!=null){if(!this.tabs[i]){i=this.prevStop(i);}}else{this.tabs={};i=0;}for(;i<this.cols;i+=8){this.tabs[i]=true;}};/**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param {number} x The position to move the cursor to the previous tab stop.\n */Terminal.prototype.prevStop=function(x){if(x==null)x=this.x;while(!this.tabs[--x]&&x>0){}return x>=this.cols?this.cols-1:x<0?0:x;};/**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param {number} x The position to move the cursor one tab stop forward.\n */Terminal.prototype.nextStop=function(x){if(x==null)x=this.x;while(!this.tabs[++x]&&x<this.cols){}return x>=this.cols?this.cols-1:x<0?0:x;};/**\n * Erase in the identified line everything from \"x\" to the end of the line (right).\n * @param {number} x The column from which to start erasing to the end of the line.\n * @param {number} y The line in which to operate.\n */Terminal.prototype.eraseRight=function(x,y){var line=this.lines[this.ybase+y],ch=[this.eraseAttr(),' ',1];// xterm\nfor(;x<this.cols;x++){line[x]=ch;}this.updateRange(y);};/**\n * Erase in the identified line everything from \"x\" to the start of the line (left).\n * @param {number} x The column from which to start erasing to the start of the line.\n * @param {number} y The line in which to operate.\n */Terminal.prototype.eraseLeft=function(x,y){var line=this.lines[this.ybase+y],ch=[this.eraseAttr(),' ',1];// xterm\nx++;while(x--){line[x]=ch;}this.updateRange(y);};/**\n * Clears the entire buffer, making the prompt line the new first line.\n */Terminal.prototype.clear=function(){if(this.ybase===0&&this.y===0){// Don't clear if it's already clear\nreturn;}this.lines=[this.lines[this.ybase+this.y]];this.ydisp=0;this.ybase=0;this.y=0;for(var i=1;i<this.rows;i++){this.lines.push(this.blankLine());}this.refresh(0,this.rows-1);this.emit('scroll',this.ydisp);};/**\n * Erase all content in the given line\n * @param {number} y The line to erase all of its contents.\n */Terminal.prototype.eraseLine=function(y){this.eraseRight(0,y);};/**\n * Return the data array of a blank line/\n * @param {number} cur First bunch of data for each \"blank\" character.\n */Terminal.prototype.blankLine=function(cur){var attr=cur?this.eraseAttr():this.defAttr;var ch=[attr,' ',1]// width defaults to 1 halfwidth character\n,line=[],i=0;for(;i<this.cols;i++){line[i]=ch;}return line;};/**\n * If cur return the back color xterm feature attribute. Else return defAttr.\n * @param {object} cur\n */Terminal.prototype.ch=function(cur){return cur?[this.eraseAttr(),' ',1]:[this.defAttr,' ',1];};/**\n * Evaluate if the current erminal is the given argument.\n * @param {object} term The terminal to evaluate\n */Terminal.prototype.is=function(term){var name=this.termName;return(name+'').indexOf(term)===0;};/**\n * Emit the 'data' event and populate the given data.\n * @param {string} data The data to populate in the event.\n */Terminal.prototype.handler=function(data){this.emit('data',data);};/**\n * Emit the 'title' event and populate the given title.\n * @param {string} title The title to populate in the event.\n */Terminal.prototype.handleTitle=function(title){this.emit('title',title);};/**\n * ESC\n *//**\n * ESC D Index (IND is 0x84).\n */Terminal.prototype.index=function(){this.y++;if(this.y>this.scrollBottom){this.y--;this.scroll();}this.state=normal;};/**\n * ESC M Reverse Index (RI is 0x8d).\n */Terminal.prototype.reverseIndex=function(){var j;this.y--;if(this.y<this.scrollTop){this.y++;// possibly move the code below to term.reverseScroll();\n// test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n// blankLine(true) is xterm/linux behavior\nthis.lines.splice(this.y+this.ybase,0,this.blankLine(true));j=this.rows-1-this.scrollBottom;this.lines.splice(this.rows-1+this.ybase-j+1,1);// this.maxRange();\nthis.updateRange(this.scrollTop);this.updateRange(this.scrollBottom);}this.state=normal;};/**\n * ESC c Full Reset (RIS).\n */Terminal.prototype.reset=function(){this.options.rows=this.rows;this.options.cols=this.cols;var customKeydownHandler=this.customKeydownHandler;Terminal.call(this,this.options);this.customKeydownHandler=customKeydownHandler;this.refresh(0,this.rows-1);this.viewport.syncScrollArea();};/**\n * ESC H Tab Set (HTS is 0x88).\n */Terminal.prototype.tabSet=function(){this.tabs[this.x]=true;this.state=normal;};/**\n * CSI\n *//**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n */Terminal.prototype.cursorUp=function(params){var param=params[0];if(param<1)param=1;this.y-=param;if(this.y<0)this.y=0;};/**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n */Terminal.prototype.cursorDown=function(params){var param=params[0];if(param<1)param=1;this.y+=param;if(this.y>=this.rows){this.y=this.rows-1;}};/**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n */Terminal.prototype.cursorForward=function(params){var param=params[0];if(param<1)param=1;this.x+=param;if(this.x>=this.cols){this.x=this.cols-1;}};/**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n */Terminal.prototype.cursorBackward=function(params){var param=params[0];if(param<1)param=1;this.x-=param;if(this.x<0)this.x=0;};/**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n */Terminal.prototype.cursorPos=function(params){var row,col;row=params[0]-1;if(params.length>=2){col=params[1]-1;}else{col=0;}if(row<0){row=0;}else if(row>=this.rows){row=this.rows-1;}if(col<0){col=0;}else if(col>=this.cols){col=this.cols-1;}this.x=col;this.y=row;};/**\n * CSI Ps J  Erase in Display (ED).\n *     Ps = 0  -> Erase Below (default).\n *     Ps = 1  -> Erase Above.\n *     Ps = 2  -> Erase All.\n *     Ps = 3  -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n *   Erase in Display (DECSED).\n *     Ps = 0  -> Selective Erase Below (default).\n *     Ps = 1  -> Selective Erase Above.\n *     Ps = 2  -> Selective Erase All.\n */Terminal.prototype.eraseInDisplay=function(params){var j;switch(params[0]){case 0:this.eraseRight(this.x,this.y);j=this.y+1;for(;j<this.rows;j++){this.eraseLine(j);}break;case 1:this.eraseLeft(this.x,this.y);j=this.y;while(j--){this.eraseLine(j);}break;case 2:j=this.rows;while(j--){this.eraseLine(j);}break;case 3:;// no saved lines\nbreak;}};/**\n * CSI Ps K  Erase in Line (EL).\n *     Ps = 0  -> Erase to Right (default).\n *     Ps = 1  -> Erase to Left.\n *     Ps = 2  -> Erase All.\n * CSI ? Ps K\n *   Erase in Line (DECSEL).\n *     Ps = 0  -> Selective Erase to Right (default).\n *     Ps = 1  -> Selective Erase to Left.\n *     Ps = 2  -> Selective Erase All.\n */Terminal.prototype.eraseInLine=function(params){switch(params[0]){case 0:this.eraseRight(this.x,this.y);break;case 1:this.eraseLeft(this.x,this.y);break;case 2:this.eraseLine(this.y);break;}};/**\n * CSI Pm m  Character Attributes (SGR).\n *     Ps = 0  -> Normal (default).\n *     Ps = 1  -> Bold.\n *     Ps = 4  -> Underlined.\n *     Ps = 5  -> Blink (appears as Bold).\n *     Ps = 7  -> Inverse.\n *     Ps = 8  -> Invisible, i.e., hidden (VT300).\n *     Ps = 2 2  -> Normal (neither bold nor faint).\n *     Ps = 2 4  -> Not underlined.\n *     Ps = 2 5  -> Steady (not blinking).\n *     Ps = 2 7  -> Positive (not inverse).\n *     Ps = 2 8  -> Visible, i.e., not hidden (VT300).\n *     Ps = 3 0  -> Set foreground color to Black.\n *     Ps = 3 1  -> Set foreground color to Red.\n *     Ps = 3 2  -> Set foreground color to Green.\n *     Ps = 3 3  -> Set foreground color to Yellow.\n *     Ps = 3 4  -> Set foreground color to Blue.\n *     Ps = 3 5  -> Set foreground color to Magenta.\n *     Ps = 3 6  -> Set foreground color to Cyan.\n *     Ps = 3 7  -> Set foreground color to White.\n *     Ps = 3 9  -> Set foreground color to default (original).\n *     Ps = 4 0  -> Set background color to Black.\n *     Ps = 4 1  -> Set background color to Red.\n *     Ps = 4 2  -> Set background color to Green.\n *     Ps = 4 3  -> Set background color to Yellow.\n *     Ps = 4 4  -> Set background color to Blue.\n *     Ps = 4 5  -> Set background color to Magenta.\n *     Ps = 4 6  -> Set background color to Cyan.\n *     Ps = 4 7  -> Set background color to White.\n *     Ps = 4 9  -> Set background color to default (original).\n *\n *   If 16-color support is compiled, the following apply.  Assume\n *   that xterm's resources are set so that the ISO color codes are\n *   the first 8 of a set of 16.  Then the aixterm colors are the\n *   bright versions of the ISO colors:\n *     Ps = 9 0  -> Set foreground color to Black.\n *     Ps = 9 1  -> Set foreground color to Red.\n *     Ps = 9 2  -> Set foreground color to Green.\n *     Ps = 9 3  -> Set foreground color to Yellow.\n *     Ps = 9 4  -> Set foreground color to Blue.\n *     Ps = 9 5  -> Set foreground color to Magenta.\n *     Ps = 9 6  -> Set foreground color to Cyan.\n *     Ps = 9 7  -> Set foreground color to White.\n *     Ps = 1 0 0  -> Set background color to Black.\n *     Ps = 1 0 1  -> Set background color to Red.\n *     Ps = 1 0 2  -> Set background color to Green.\n *     Ps = 1 0 3  -> Set background color to Yellow.\n *     Ps = 1 0 4  -> Set background color to Blue.\n *     Ps = 1 0 5  -> Set background color to Magenta.\n *     Ps = 1 0 6  -> Set background color to Cyan.\n *     Ps = 1 0 7  -> Set background color to White.\n *\n *   If xterm is compiled with the 16-color support disabled, it\n *   supports the following, from rxvt:\n *     Ps = 1 0 0  -> Set foreground and background color to\n *     default.\n *\n *   If 88- or 256-color support is compiled, the following apply.\n *     Ps = 3 8  ; 5  ; Ps -> Set foreground color to the second\n *     Ps.\n *     Ps = 4 8  ; 5  ; Ps -> Set background color to the second\n *     Ps.\n */Terminal.prototype.charAttributes=function(params){// Optimize a single SGR0.\nif(params.length===1&&params[0]===0){this.curAttr=this.defAttr;return;}var l=params.length,i=0,flags=this.curAttr>>18,fg=this.curAttr>>9&0x1ff,bg=this.curAttr&0x1ff,p;for(;i<l;i++){p=params[i];if(p>=30&&p<=37){// fg color 8\nfg=p-30;}else if(p>=40&&p<=47){// bg color 8\nbg=p-40;}else if(p>=90&&p<=97){// fg color 16\np+=8;fg=p-90;}else if(p>=100&&p<=107){// bg color 16\np+=8;bg=p-100;}else if(p===0){// default\nflags=this.defAttr>>18;fg=this.defAttr>>9&0x1ff;bg=this.defAttr&0x1ff;// flags = 0;\n// fg = 0x1ff;\n// bg = 0x1ff;\n}else if(p===1){// bold text\nflags|=1;}else if(p===4){// underlined text\nflags|=2;}else if(p===5){// blink\nflags|=4;}else if(p===7){// inverse and positive\n// test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\nflags|=8;}else if(p===8){// invisible\nflags|=16;}else if(p===22){// not bold\nflags&=~1;}else if(p===24){// not underlined\nflags&=~2;}else if(p===25){// not blink\nflags&=~4;}else if(p===27){// not inverse\nflags&=~8;}else if(p===28){// not invisible\nflags&=~16;}else if(p===39){// reset fg\nfg=this.defAttr>>9&0x1ff;}else if(p===49){// reset bg\nbg=this.defAttr&0x1ff;}else if(p===38){// fg color 256\nif(params[i+1]===2){i+=2;fg=matchColor(params[i]&0xff,params[i+1]&0xff,params[i+2]&0xff);if(fg===-1)fg=0x1ff;i+=2;}else if(params[i+1]===5){i+=2;p=params[i]&0xff;fg=p;}}else if(p===48){// bg color 256\nif(params[i+1]===2){i+=2;bg=matchColor(params[i]&0xff,params[i+1]&0xff,params[i+2]&0xff);if(bg===-1)bg=0x1ff;i+=2;}else if(params[i+1]===5){i+=2;p=params[i]&0xff;bg=p;}}else if(p===100){// reset fg/bg\nfg=this.defAttr>>9&0x1ff;bg=this.defAttr&0x1ff;}else{this.error('Unknown SGR attribute: %d.',p);}}this.curAttr=flags<<18|fg<<9|bg;};/**\n * CSI Ps n  Device Status Report (DSR).\n *     Ps = 5  -> Status Report.  Result (``OK'') is\n *   CSI 0 n\n *     Ps = 6  -> Report Cursor Position (CPR) [row;column].\n *   Result is\n *   CSI r ; c R\n * CSI ? Ps n\n *   Device Status Report (DSR, DEC-specific).\n *     Ps = 6  -> Report Cursor Position (CPR) [row;column] as CSI\n *     ? r ; c R (assumes page is zero).\n *     Ps = 1 5  -> Report Printer status as CSI ? 1 0  n  (ready).\n *     or CSI ? 1 1  n  (not ready).\n *     Ps = 2 5  -> Report UDK status as CSI ? 2 0  n  (unlocked)\n *     or CSI ? 2 1  n  (locked).\n *     Ps = 2 6  -> Report Keyboard status as\n *   CSI ? 2 7  ;  1  ;  0  ;  0  n  (North American).\n *   The last two parameters apply to VT400 & up, and denote key-\n *   board ready and LK01 respectively.\n *     Ps = 5 3  -> Report Locator status as\n *   CSI ? 5 3  n  Locator available, if compiled-in, or\n *   CSI ? 5 0  n  No Locator, if not.\n */Terminal.prototype.deviceStatus=function(params){if(!this.prefix){switch(params[0]){case 5:// status report\nthis.send('\\x1b[0n');break;case 6:// cursor position\nthis.send('\\x1b['+(this.y+1)+';'+(this.x+1)+'R');break;}}else if(this.prefix==='?'){// modern xterm doesnt seem to\n// respond to any of these except ?6, 6, and 5\nswitch(params[0]){case 6:// cursor position\nthis.send('\\x1b[?'+(this.y+1)+';'+(this.x+1)+'R');break;case 15:// no printer\n// this.send('\\x1b[?11n');\nbreak;case 25:// dont support user defined keys\n// this.send('\\x1b[?21n');\nbreak;case 26:// north american keyboard\n// this.send('\\x1b[?27;1;0;0n');\nbreak;case 53:// no dec locator/mouse\n// this.send('\\x1b[?50n');\nbreak;}}};/**\n * Additions\n *//**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n */Terminal.prototype.insertChars=function(params){var param,row,j,ch;param=params[0];if(param<1)param=1;row=this.y+this.ybase;j=this.x;ch=[this.eraseAttr(),' ',1];// xterm\nwhile(param--&&j<this.cols){this.lines[row].splice(j++,0,ch);this.lines[row].pop();}};/**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * same as CSI Ps B ?\n */Terminal.prototype.cursorNextLine=function(params){var param=params[0];if(param<1)param=1;this.y+=param;if(this.y>=this.rows){this.y=this.rows-1;}this.x=0;};/**\n * CSI Ps F\n * Cursor Preceding Line Ps Times (default = 1) (CNL).\n * reuse CSI Ps A ?\n */Terminal.prototype.cursorPrecedingLine=function(params){var param=params[0];if(param<1)param=1;this.y-=param;if(this.y<0)this.y=0;this.x=0;};/**\n * CSI Ps G\n * Cursor Character Absolute  [column] (default = [row,1]) (CHA).\n */Terminal.prototype.cursorCharAbsolute=function(params){var param=params[0];if(param<1)param=1;this.x=param-1;};/**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n */Terminal.prototype.insertLines=function(params){var param,row,j;param=params[0];if(param<1)param=1;row=this.y+this.ybase;j=this.rows-1-this.scrollBottom;j=this.rows-1+this.ybase-j+1;while(param--){// test: echo -e '\\e[44m\\e[1L\\e[0m'\n// blankLine(true) - xterm/linux behavior\nthis.lines.splice(row,0,this.blankLine(true));this.lines.splice(j,1);}// this.maxRange();\nthis.updateRange(this.y);this.updateRange(this.scrollBottom);};/**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n */Terminal.prototype.deleteLines=function(params){var param,row,j;param=params[0];if(param<1)param=1;row=this.y+this.ybase;j=this.rows-1-this.scrollBottom;j=this.rows-1+this.ybase-j;while(param--){// test: echo -e '\\e[44m\\e[1M\\e[0m'\n// blankLine(true) - xterm/linux behavior\nthis.lines.splice(j+1,0,this.blankLine(true));this.lines.splice(row,1);}// this.maxRange();\nthis.updateRange(this.y);this.updateRange(this.scrollBottom);};/**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n */Terminal.prototype.deleteChars=function(params){var param,row,ch;param=params[0];if(param<1)param=1;row=this.y+this.ybase;ch=[this.eraseAttr(),' ',1];// xterm\nwhile(param--){this.lines[row].splice(this.x,1);this.lines[row].push(ch);}};/**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n */Terminal.prototype.eraseChars=function(params){var param,row,j,ch;param=params[0];if(param<1)param=1;row=this.y+this.ybase;j=this.x;ch=[this.eraseAttr(),' ',1];// xterm\nwhile(param--&&j<this.cols){this.lines[row][j++]=ch;}};/**\n * CSI Pm `  Character Position Absolute\n *   [column] (default = [row,1]) (HPA).\n */Terminal.prototype.charPosAbsolute=function(params){var param=params[0];if(param<1)param=1;this.x=param-1;if(this.x>=this.cols){this.x=this.cols-1;}};/**\n * 141 61 a * HPR -\n * Horizontal Position Relative\n * reuse CSI Ps C ?\n */Terminal.prototype.HPositionRelative=function(params){var param=params[0];if(param<1)param=1;this.x+=param;if(this.x>=this.cols){this.x=this.cols-1;}};/**\n * CSI Ps c  Send Device Attributes (Primary DA).\n *     Ps = 0  or omitted -> request attributes from terminal.  The\n *     response depends on the decTerminalID resource setting.\n *     -> CSI ? 1 ; 2 c  (``VT100 with Advanced Video Option'')\n *     -> CSI ? 1 ; 0 c  (``VT101 with No Options'')\n *     -> CSI ? 6 c  (``VT102'')\n *     -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c  (``VT220'')\n *   The VT100-style response parameters do not mean anything by\n *   themselves.  VT220 parameters do, telling the host what fea-\n *   tures the terminal supports:\n *     Ps = 1  -> 132-columns.\n *     Ps = 2  -> Printer.\n *     Ps = 6  -> Selective erase.\n *     Ps = 8  -> User-defined keys.\n *     Ps = 9  -> National replacement character sets.\n *     Ps = 1 5  -> Technical characters.\n *     Ps = 2 2  -> ANSI color, e.g., VT525.\n *     Ps = 2 9  -> ANSI text locator (i.e., DEC Locator mode).\n * CSI > Ps c\n *   Send Device Attributes (Secondary DA).\n *     Ps = 0  or omitted -> request the terminal's identification\n *     code.  The response depends on the decTerminalID resource set-\n *     ting.  It should apply only to VT220 and up, but xterm extends\n *     this to VT100.\n *     -> CSI  > Pp ; Pv ; Pc c\n *   where Pp denotes the terminal type\n *     Pp = 0  -> ``VT100''.\n *     Pp = 1  -> ``VT220''.\n *   and Pv is the firmware version (for xterm, this was originally\n *   the XFree86 patch number, starting with 95).  In a DEC termi-\n *   nal, Pc indicates the ROM cartridge registration number and is\n *   always zero.\n * More information:\n *   xterm/charproc.c - line 2012, for more information.\n *   vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n */Terminal.prototype.sendDeviceAttributes=function(params){if(params[0]>0)return;if(!this.prefix){if(this.is('xterm')||this.is('rxvt-unicode')||this.is('screen')){this.send('\\x1b[?1;2c');}else if(this.is('linux')){this.send('\\x1b[?6c');}}else if(this.prefix==='>'){// xterm and urxvt\n// seem to spit this\n// out around ~370 times (?).\nif(this.is('xterm')){this.send('\\x1b[>0;276;0c');}else if(this.is('rxvt-unicode')){this.send('\\x1b[>85;95;0c');}else if(this.is('linux')){// not supported by linux console.\n// linux console echoes parameters.\nthis.send(params[0]+'c');}else if(this.is('screen')){this.send('\\x1b[>83;40003;0c');}}};/**\n * CSI Pm d\n * Line Position Absolute  [row] (default = [1,column]) (VPA).\n */Terminal.prototype.linePosAbsolute=function(params){var param=params[0];if(param<1)param=1;this.y=param-1;if(this.y>=this.rows){this.y=this.rows-1;}};/**\n * 145 65 e * VPR - Vertical Position Relative\n * reuse CSI Ps B ?\n */Terminal.prototype.VPositionRelative=function(params){var param=params[0];if(param<1)param=1;this.y+=param;if(this.y>=this.rows){this.y=this.rows-1;}};/**\n * CSI Ps ; Ps f\n *   Horizontal and Vertical Position [row;column] (default =\n *   [1,1]) (HVP).\n */Terminal.prototype.HVPosition=function(params){if(params[0]<1)params[0]=1;if(params[1]<1)params[1]=1;this.y=params[0]-1;if(this.y>=this.rows){this.y=this.rows-1;}this.x=params[1]-1;if(this.x>=this.cols){this.x=this.cols-1;}};/**\n * CSI Pm h  Set Mode (SM).\n *     Ps = 2  -> Keyboard Action Mode (AM).\n *     Ps = 4  -> Insert Mode (IRM).\n *     Ps = 1 2  -> Send/receive (SRM).\n *     Ps = 2 0  -> Automatic Newline (LNM).\n * CSI ? Pm h\n *   DEC Private Mode Set (DECSET).\n *     Ps = 1  -> Application Cursor Keys (DECCKM).\n *     Ps = 2  -> Designate USASCII for character sets G0-G3\n *     (DECANM), and set VT100 mode.\n *     Ps = 3  -> 132 Column Mode (DECCOLM).\n *     Ps = 4  -> Smooth (Slow) Scroll (DECSCLM).\n *     Ps = 5  -> Reverse Video (DECSCNM).\n *     Ps = 6  -> Origin Mode (DECOM).\n *     Ps = 7  -> Wraparound Mode (DECAWM).\n *     Ps = 8  -> Auto-repeat Keys (DECARM).\n *     Ps = 9  -> Send Mouse X & Y on button press.  See the sec-\n *     tion Mouse Tracking.\n *     Ps = 1 0  -> Show toolbar (rxvt).\n *     Ps = 1 2  -> Start Blinking Cursor (att610).\n *     Ps = 1 8  -> Print form feed (DECPFF).\n *     Ps = 1 9  -> Set print extent to full screen (DECPEX).\n *     Ps = 2 5  -> Show Cursor (DECTCEM).\n *     Ps = 3 0  -> Show scrollbar (rxvt).\n *     Ps = 3 5  -> Enable font-shifting functions (rxvt).\n *     Ps = 3 8  -> Enter Tektronix Mode (DECTEK).\n *     Ps = 4 0  -> Allow 80 -> 132 Mode.\n *     Ps = 4 1  -> more(1) fix (see curses resource).\n *     Ps = 4 2  -> Enable Nation Replacement Character sets (DECN-\n *     RCM).\n *     Ps = 4 4  -> Turn On Margin Bell.\n *     Ps = 4 5  -> Reverse-wraparound Mode.\n *     Ps = 4 6  -> Start Logging.  This is normally disabled by a\n *     compile-time option.\n *     Ps = 4 7  -> Use Alternate Screen Buffer.  (This may be dis-\n *     abled by the titeInhibit resource).\n *     Ps = 6 6  -> Application keypad (DECNKM).\n *     Ps = 6 7  -> Backarrow key sends backspace (DECBKM).\n *     Ps = 1 0 0 0  -> Send Mouse X & Y on button press and\n *     release.  See the section Mouse Tracking.\n *     Ps = 1 0 0 1  -> Use Hilite Mouse Tracking.\n *     Ps = 1 0 0 2  -> Use Cell Motion Mouse Tracking.\n *     Ps = 1 0 0 3  -> Use All Motion Mouse Tracking.\n *     Ps = 1 0 0 4  -> Send FocusIn/FocusOut events.\n *     Ps = 1 0 0 5  -> Enable Extended Mouse Mode.\n *     Ps = 1 0 1 0  -> Scroll to bottom on tty output (rxvt).\n *     Ps = 1 0 1 1  -> Scroll to bottom on key press (rxvt).\n *     Ps = 1 0 3 4  -> Interpret \"meta\" key, sets eighth bit.\n *     (enables the eightBitInput resource).\n *     Ps = 1 0 3 5  -> Enable special modifiers for Alt and Num-\n *     Lock keys.  (This enables the numLock resource).\n *     Ps = 1 0 3 6  -> Send ESC   when Meta modifies a key.  (This\n *     enables the metaSendsEscape resource).\n *     Ps = 1 0 3 7  -> Send DEL from the editing-keypad Delete\n *     key.\n *     Ps = 1 0 3 9  -> Send ESC  when Alt modifies a key.  (This\n *     enables the altSendsEscape resource).\n *     Ps = 1 0 4 0  -> Keep selection even if not highlighted.\n *     (This enables the keepSelection resource).\n *     Ps = 1 0 4 1  -> Use the CLIPBOARD selection.  (This enables\n *     the selectToClipboard resource).\n *     Ps = 1 0 4 2  -> Enable Urgency window manager hint when\n *     Control-G is received.  (This enables the bellIsUrgent\n *     resource).\n *     Ps = 1 0 4 3  -> Enable raising of the window when Control-G\n *     is received.  (enables the popOnBell resource).\n *     Ps = 1 0 4 7  -> Use Alternate Screen Buffer.  (This may be\n *     disabled by the titeInhibit resource).\n *     Ps = 1 0 4 8  -> Save cursor as in DECSC.  (This may be dis-\n *     abled by the titeInhibit resource).\n *     Ps = 1 0 4 9  -> Save cursor as in DECSC and use Alternate\n *     Screen Buffer, clearing it first.  (This may be disabled by\n *     the titeInhibit resource).  This combines the effects of the 1\n *     0 4 7  and 1 0 4 8  modes.  Use this with terminfo-based\n *     applications rather than the 4 7  mode.\n *     Ps = 1 0 5 0  -> Set terminfo/termcap function-key mode.\n *     Ps = 1 0 5 1  -> Set Sun function-key mode.\n *     Ps = 1 0 5 2  -> Set HP function-key mode.\n *     Ps = 1 0 5 3  -> Set SCO function-key mode.\n *     Ps = 1 0 6 0  -> Set legacy keyboard emulation (X11R6).\n *     Ps = 1 0 6 1  -> Set VT220 keyboard emulation.\n *     Ps = 2 0 0 4  -> Set bracketed paste mode.\n * Modes:\n *   http: *vt100.net/docs/vt220-rm/chapter4.html\n */Terminal.prototype.setMode=function(params){if((typeof params==='undefined'?'undefined':_typeof(params))==='object'){var l=params.length,i=0;for(;i<l;i++){this.setMode(params[i]);}return;}if(!this.prefix){switch(params){case 4:this.insertMode=true;break;case 20://this.convertEol = true;\nbreak;}}else if(this.prefix==='?'){switch(params){case 1:this.applicationCursor=true;break;case 2:this.setgCharset(0,Terminal.charsets.US);this.setgCharset(1,Terminal.charsets.US);this.setgCharset(2,Terminal.charsets.US);this.setgCharset(3,Terminal.charsets.US);// set VT100 mode here\nbreak;case 3:// 132 col mode\nthis.savedCols=this.cols;this.resize(132,this.rows);break;case 6:this.originMode=true;break;case 7:this.wraparoundMode=true;break;case 12:// this.cursorBlink = true;\nbreak;case 66:this.log('Serial port requested application keypad.');this.applicationKeypad=true;this.viewport.syncScrollArea();break;case 9:// X10 Mouse\n// no release, no motion, no wheel, no modifiers.\ncase 1000:// vt200 mouse\n// no motion.\n// no modifiers, except control on the wheel.\ncase 1002:// button event mouse\ncase 1003:// any event mouse\n// any event - sends motion events,\n// even if there is no button held down.\nthis.x10Mouse=params===9;this.vt200Mouse=params===1000;this.normalMouse=params>1000;this.mouseEvents=true;this.element.style.cursor='default';this.log('Binding to mouse events.');break;case 1004:// send focusin/focusout events\n// focusin: ^[[I\n// focusout: ^[[O\nthis.sendFocus=true;break;case 1005:// utf8 ext mode mouse\nthis.utfMouse=true;// for wide terminals\n// simply encodes large values as utf8 characters\nbreak;case 1006:// sgr ext mode mouse\nthis.sgrMouse=true;// for wide terminals\n// does not add 32 to fields\n// press: ^[[<b;x;yM\n// release: ^[[<b;x;ym\nbreak;case 1015:// urxvt ext mode mouse\nthis.urxvtMouse=true;// for wide terminals\n// numbers for fields\n// press: ^[[b;x;yM\n// motion: ^[[b;x;yT\nbreak;case 25:// show cursor\nthis.cursorHidden=false;break;case 1049:// alt screen buffer cursor\n//this.saveCursor();\n;// FALL-THROUGH\ncase 47:// alt screen buffer\ncase 1047:// alt screen buffer\nif(!this.normal){var normal={lines:this.lines,ybase:this.ybase,ydisp:this.ydisp,x:this.x,y:this.y,scrollTop:this.scrollTop,scrollBottom:this.scrollBottom,tabs:this.tabs// XXX save charset(s) here?\n// charset: this.charset,\n// glevel: this.glevel,\n// charsets: this.charsets\n};this.reset();this.normal=normal;this.showCursor();}break;}}};/**\n * CSI Pm l  Reset Mode (RM).\n *     Ps = 2  -> Keyboard Action Mode (AM).\n *     Ps = 4  -> Replace Mode (IRM).\n *     Ps = 1 2  -> Send/receive (SRM).\n *     Ps = 2 0  -> Normal Linefeed (LNM).\n * CSI ? Pm l\n *   DEC Private Mode Reset (DECRST).\n *     Ps = 1  -> Normal Cursor Keys (DECCKM).\n *     Ps = 2  -> Designate VT52 mode (DECANM).\n *     Ps = 3  -> 80 Column Mode (DECCOLM).\n *     Ps = 4  -> Jump (Fast) Scroll (DECSCLM).\n *     Ps = 5  -> Normal Video (DECSCNM).\n *     Ps = 6  -> Normal Cursor Mode (DECOM).\n *     Ps = 7  -> No Wraparound Mode (DECAWM).\n *     Ps = 8  -> No Auto-repeat Keys (DECARM).\n *     Ps = 9  -> Don't send Mouse X & Y on button press.\n *     Ps = 1 0  -> Hide toolbar (rxvt).\n *     Ps = 1 2  -> Stop Blinking Cursor (att610).\n *     Ps = 1 8  -> Don't print form feed (DECPFF).\n *     Ps = 1 9  -> Limit print to scrolling region (DECPEX).\n *     Ps = 2 5  -> Hide Cursor (DECTCEM).\n *     Ps = 3 0  -> Don't show scrollbar (rxvt).\n *     Ps = 3 5  -> Disable font-shifting functions (rxvt).\n *     Ps = 4 0  -> Disallow 80 -> 132 Mode.\n *     Ps = 4 1  -> No more(1) fix (see curses resource).\n *     Ps = 4 2  -> Disable Nation Replacement Character sets (DEC-\n *     NRCM).\n *     Ps = 4 4  -> Turn Off Margin Bell.\n *     Ps = 4 5  -> No Reverse-wraparound Mode.\n *     Ps = 4 6  -> Stop Logging.  (This is normally disabled by a\n *     compile-time option).\n *     Ps = 4 7  -> Use Normal Screen Buffer.\n *     Ps = 6 6  -> Numeric keypad (DECNKM).\n *     Ps = 6 7  -> Backarrow key sends delete (DECBKM).\n *     Ps = 1 0 0 0  -> Don't send Mouse X & Y on button press and\n *     release.  See the section Mouse Tracking.\n *     Ps = 1 0 0 1  -> Don't use Hilite Mouse Tracking.\n *     Ps = 1 0 0 2  -> Don't use Cell Motion Mouse Tracking.\n *     Ps = 1 0 0 3  -> Don't use All Motion Mouse Tracking.\n *     Ps = 1 0 0 4  -> Don't send FocusIn/FocusOut events.\n *     Ps = 1 0 0 5  -> Disable Extended Mouse Mode.\n *     Ps = 1 0 1 0  -> Don't scroll to bottom on tty output\n *     (rxvt).\n *     Ps = 1 0 1 1  -> Don't scroll to bottom on key press (rxvt).\n *     Ps = 1 0 3 4  -> Don't interpret \"meta\" key.  (This disables\n *     the eightBitInput resource).\n *     Ps = 1 0 3 5  -> Disable special modifiers for Alt and Num-\n *     Lock keys.  (This disables the numLock resource).\n *     Ps = 1 0 3 6  -> Don't send ESC  when Meta modifies a key.\n *     (This disables the metaSendsEscape resource).\n *     Ps = 1 0 3 7  -> Send VT220 Remove from the editing-keypad\n *     Delete key.\n *     Ps = 1 0 3 9  -> Don't send ESC  when Alt modifies a key.\n *     (This disables the altSendsEscape resource).\n *     Ps = 1 0 4 0  -> Do not keep selection when not highlighted.\n *     (This disables the keepSelection resource).\n *     Ps = 1 0 4 1  -> Use the PRIMARY selection.  (This disables\n *     the selectToClipboard resource).\n *     Ps = 1 0 4 2  -> Disable Urgency window manager hint when\n *     Control-G is received.  (This disables the bellIsUrgent\n *     resource).\n *     Ps = 1 0 4 3  -> Disable raising of the window when Control-\n *     G is received.  (This disables the popOnBell resource).\n *     Ps = 1 0 4 7  -> Use Normal Screen Buffer, clearing screen\n *     first if in the Alternate Screen.  (This may be disabled by\n *     the titeInhibit resource).\n *     Ps = 1 0 4 8  -> Restore cursor as in DECRC.  (This may be\n *     disabled by the titeInhibit resource).\n *     Ps = 1 0 4 9  -> Use Normal Screen Buffer and restore cursor\n *     as in DECRC.  (This may be disabled by the titeInhibit\n *     resource).  This combines the effects of the 1 0 4 7  and 1 0\n *     4 8  modes.  Use this with terminfo-based applications rather\n *     than the 4 7  mode.\n *     Ps = 1 0 5 0  -> Reset terminfo/termcap function-key mode.\n *     Ps = 1 0 5 1  -> Reset Sun function-key mode.\n *     Ps = 1 0 5 2  -> Reset HP function-key mode.\n *     Ps = 1 0 5 3  -> Reset SCO function-key mode.\n *     Ps = 1 0 6 0  -> Reset legacy keyboard emulation (X11R6).\n *     Ps = 1 0 6 1  -> Reset keyboard emulation to Sun/PC style.\n *     Ps = 2 0 0 4  -> Reset bracketed paste mode.\n */Terminal.prototype.resetMode=function(params){if((typeof params==='undefined'?'undefined':_typeof(params))==='object'){var l=params.length,i=0;for(;i<l;i++){this.resetMode(params[i]);}return;}if(!this.prefix){switch(params){case 4:this.insertMode=false;break;case 20://this.convertEol = false;\nbreak;}}else if(this.prefix==='?'){switch(params){case 1:this.applicationCursor=false;break;case 3:if(this.cols===132&&this.savedCols){this.resize(this.savedCols,this.rows);}delete this.savedCols;break;case 6:this.originMode=false;break;case 7:this.wraparoundMode=false;break;case 12:// this.cursorBlink = false;\nbreak;case 66:this.log('Switching back to normal keypad.');this.applicationKeypad=false;this.viewport.syncScrollArea();break;case 9:// X10 Mouse\ncase 1000:// vt200 mouse\ncase 1002:// button event mouse\ncase 1003:// any event mouse\nthis.x10Mouse=false;this.vt200Mouse=false;this.normalMouse=false;this.mouseEvents=false;this.element.style.cursor='';break;case 1004:// send focusin/focusout events\nthis.sendFocus=false;break;case 1005:// utf8 ext mode mouse\nthis.utfMouse=false;break;case 1006:// sgr ext mode mouse\nthis.sgrMouse=false;break;case 1015:// urxvt ext mode mouse\nthis.urxvtMouse=false;break;case 25:// hide cursor\nthis.cursorHidden=true;break;case 1049:// alt screen buffer cursor\n;// FALL-THROUGH\ncase 47:// normal screen buffer\ncase 1047:// normal screen buffer - clearing it first\nif(this.normal){this.lines=this.normal.lines;this.ybase=this.normal.ybase;this.ydisp=this.normal.ydisp;this.x=this.normal.x;this.y=this.normal.y;this.scrollTop=this.normal.scrollTop;this.scrollBottom=this.normal.scrollBottom;this.tabs=this.normal.tabs;this.normal=null;// if (params === 1049) {\n//   this.x = this.savedX;\n//   this.y = this.savedY;\n// }\nthis.refresh(0,this.rows-1);this.showCursor();}break;}}};/**\n * CSI Ps ; Ps r\n *   Set Scrolling Region [top;bottom] (default = full size of win-\n *   dow) (DECSTBM).\n * CSI ? Pm r\n */Terminal.prototype.setScrollRegion=function(params){if(this.prefix)return;this.scrollTop=(params[0]||1)-1;this.scrollBottom=(params[1]||this.rows)-1;this.x=0;this.y=0;};/**\n * CSI s\n *   Save cursor (ANSI.SYS).\n */Terminal.prototype.saveCursor=function(params){this.savedX=this.x;this.savedY=this.y;};/**\n * CSI u\n *   Restore cursor (ANSI.SYS).\n */Terminal.prototype.restoreCursor=function(params){this.x=this.savedX||0;this.y=this.savedY||0;};/**\n * Lesser Used\n *//**\n * CSI Ps I\n *   Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n */Terminal.prototype.cursorForwardTab=function(params){var param=params[0]||1;while(param--){this.x=this.nextStop();}};/**\n * CSI Ps S  Scroll up Ps lines (default = 1) (SU).\n */Terminal.prototype.scrollUp=function(params){var param=params[0]||1;while(param--){this.lines.splice(this.ybase+this.scrollTop,1);this.lines.splice(this.ybase+this.scrollBottom,0,this.blankLine());}// this.maxRange();\nthis.updateRange(this.scrollTop);this.updateRange(this.scrollBottom);};/**\n * CSI Ps T  Scroll down Ps lines (default = 1) (SD).\n */Terminal.prototype.scrollDown=function(params){var param=params[0]||1;while(param--){this.lines.splice(this.ybase+this.scrollBottom,1);this.lines.splice(this.ybase+this.scrollTop,0,this.blankLine());}// this.maxRange();\nthis.updateRange(this.scrollTop);this.updateRange(this.scrollBottom);};/**\n * CSI Ps ; Ps ; Ps ; Ps ; Ps T\n *   Initiate highlight mouse tracking.  Parameters are\n *   [func;startx;starty;firstrow;lastrow].  See the section Mouse\n *   Tracking.\n */Terminal.prototype.initMouseTracking=function(params){// Relevant: DECSET 1001\n};/**\n * CSI > Ps; Ps T\n *   Reset one or more features of the title modes to the default\n *   value.  Normally, \"reset\" disables the feature.  It is possi-\n *   ble to disable the ability to reset features by compiling a\n *   different default for the title modes into xterm.\n *     Ps = 0  -> Do not set window/icon labels using hexadecimal.\n *     Ps = 1  -> Do not query window/icon labels using hexadeci-\n *     mal.\n *     Ps = 2  -> Do not set window/icon labels using UTF-8.\n *     Ps = 3  -> Do not query window/icon labels using UTF-8.\n *   (See discussion of \"Title Modes\").\n */Terminal.prototype.resetTitleModes=function(params){;};/**\n * CSI Ps Z  Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n */Terminal.prototype.cursorBackwardTab=function(params){var param=params[0]||1;while(param--){this.x=this.prevStop();}};/**\n * CSI Ps b  Repeat the preceding graphic character Ps times (REP).\n */Terminal.prototype.repeatPrecedingCharacter=function(params){var param=params[0]||1,line=this.lines[this.ybase+this.y],ch=line[this.x-1]||[this.defAttr,' ',1];while(param--){line[this.x++]=ch;}};/**\n * CSI Ps g  Tab Clear (TBC).\n *     Ps = 0  -> Clear Current Column (default).\n *     Ps = 3  -> Clear All.\n * Potentially:\n *   Ps = 2  -> Clear Stops on Line.\n *   http://vt100.net/annarbor/aaa-ug/section6.html\n */Terminal.prototype.tabClear=function(params){var param=params[0];if(param<=0){delete this.tabs[this.x];}else if(param===3){this.tabs={};}};/**\n * CSI Pm i  Media Copy (MC).\n *     Ps = 0  -> Print screen (default).\n *     Ps = 4  -> Turn off printer controller mode.\n *     Ps = 5  -> Turn on printer controller mode.\n * CSI ? Pm i\n *   Media Copy (MC, DEC-specific).\n *     Ps = 1  -> Print line containing cursor.\n *     Ps = 4  -> Turn off autoprint mode.\n *     Ps = 5  -> Turn on autoprint mode.\n *     Ps = 1  0  -> Print composed display, ignores DECPEX.\n *     Ps = 1  1  -> Print all pages.\n */Terminal.prototype.mediaCopy=function(params){;};/**\n * CSI > Ps; Ps m\n *   Set or reset resource-values used by xterm to decide whether\n *   to construct escape sequences holding information about the\n *   modifiers pressed with a given key.  The first parameter iden-\n *   tifies the resource to set/reset.  The second parameter is the\n *   value to assign to the resource.  If the second parameter is\n *   omitted, the resource is reset to its initial value.\n *     Ps = 1  -> modifyCursorKeys.\n *     Ps = 2  -> modifyFunctionKeys.\n *     Ps = 4  -> modifyOtherKeys.\n *   If no parameters are given, all resources are reset to their\n *   initial values.\n */Terminal.prototype.setResources=function(params){;};/**\n * CSI > Ps n\n *   Disable modifiers which may be enabled via the CSI > Ps; Ps m\n *   sequence.  This corresponds to a resource value of \"-1\", which\n *   cannot be set with the other sequence.  The parameter identi-\n *   fies the resource to be disabled:\n *     Ps = 1  -> modifyCursorKeys.\n *     Ps = 2  -> modifyFunctionKeys.\n *     Ps = 4  -> modifyOtherKeys.\n *   If the parameter is omitted, modifyFunctionKeys is disabled.\n *   When modifyFunctionKeys is disabled, xterm uses the modifier\n *   keys to make an extended sequence of functions rather than\n *   adding a parameter to each function key to denote the modi-\n *   fiers.\n */Terminal.prototype.disableModifiers=function(params){;};/**\n * CSI > Ps p\n *   Set resource value pointerMode.  This is used by xterm to\n *   decide whether to hide the pointer cursor as the user types.\n *   Valid values for the parameter:\n *     Ps = 0  -> never hide the pointer.\n *     Ps = 1  -> hide if the mouse tracking mode is not enabled.\n *     Ps = 2  -> always hide the pointer.  If no parameter is\n *     given, xterm uses the default, which is 1 .\n */Terminal.prototype.setPointerMode=function(params){;};/**\n * CSI ! p   Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n */Terminal.prototype.softReset=function(params){this.cursorHidden=false;this.insertMode=false;this.originMode=false;this.wraparoundMode=false;// autowrap\nthis.applicationKeypad=false;// ?\nthis.viewport.syncScrollArea();this.applicationCursor=false;this.scrollTop=0;this.scrollBottom=this.rows-1;this.curAttr=this.defAttr;this.x=this.y=0;// ?\nthis.charset=null;this.glevel=0;// ??\nthis.charsets=[null];// ??\n};/**\n * CSI Ps$ p\n *   Request ANSI mode (DECRQM).  For VT300 and up, reply is\n *     CSI Ps; Pm$ y\n *   where Ps is the mode number as in RM, and Pm is the mode\n *   value:\n *     0 - not recognized\n *     1 - set\n *     2 - reset\n *     3 - permanently set\n *     4 - permanently reset\n */Terminal.prototype.requestAnsiMode=function(params){;};/**\n * CSI ? Ps$ p\n *   Request DEC private mode (DECRQM).  For VT300 and up, reply is\n *     CSI ? Ps; Pm$ p\n *   where Ps is the mode number as in DECSET, Pm is the mode value\n *   as in the ANSI DECRQM.\n */Terminal.prototype.requestPrivateMode=function(params){;};/**\n * CSI Ps ; Ps \" p\n *   Set conformance level (DECSCL).  Valid values for the first\n *   parameter:\n *     Ps = 6 1  -> VT100.\n *     Ps = 6 2  -> VT200.\n *     Ps = 6 3  -> VT300.\n *   Valid values for the second parameter:\n *     Ps = 0  -> 8-bit controls.\n *     Ps = 1  -> 7-bit controls (always set for VT100).\n *     Ps = 2  -> 8-bit controls.\n */Terminal.prototype.setConformanceLevel=function(params){;};/**\n * CSI Ps q  Load LEDs (DECLL).\n *     Ps = 0  -> Clear all LEDS (default).\n *     Ps = 1  -> Light Num Lock.\n *     Ps = 2  -> Light Caps Lock.\n *     Ps = 3  -> Light Scroll Lock.\n *     Ps = 2  1  -> Extinguish Num Lock.\n *     Ps = 2  2  -> Extinguish Caps Lock.\n *     Ps = 2  3  -> Extinguish Scroll Lock.\n */Terminal.prototype.loadLEDs=function(params){;};/**\n * CSI Ps SP q\n *   Set cursor style (DECSCUSR, VT520).\n *     Ps = 0  -> blinking block.\n *     Ps = 1  -> blinking block (default).\n *     Ps = 2  -> steady block.\n *     Ps = 3  -> blinking underline.\n *     Ps = 4  -> steady underline.\n */Terminal.prototype.setCursorStyle=function(params){;};/**\n * CSI Ps \" q\n *   Select character protection attribute (DECSCA).  Valid values\n *   for the parameter:\n *     Ps = 0  -> DECSED and DECSEL can erase (default).\n *     Ps = 1  -> DECSED and DECSEL cannot erase.\n *     Ps = 2  -> DECSED and DECSEL can erase.\n */Terminal.prototype.setCharProtectionAttr=function(params){;};/**\n * CSI ? Pm r\n *   Restore DEC Private Mode Values.  The value of Ps previously\n *   saved is restored.  Ps values are the same as for DECSET.\n */Terminal.prototype.restorePrivateValues=function(params){;};/**\n * CSI Pt; Pl; Pb; Pr; Ps$ r\n *   Change Attributes in Rectangular Area (DECCARA), VT400 and up.\n *     Pt; Pl; Pb; Pr denotes the rectangle.\n *     Ps denotes the SGR attributes to change: 0, 1, 4, 5, 7.\n * NOTE: xterm doesn't enable this code by default.\n */Terminal.prototype.setAttrInRectangle=function(params){var t=params[0],l=params[1],b=params[2],r=params[3],attr=params[4];var line,i;for(;t<b+1;t++){line=this.lines[this.ybase+t];for(i=l;i<r;i++){line[i]=[attr,line[i][1]];}}// this.maxRange();\nthis.updateRange(params[0]);this.updateRange(params[2]);};/**\n * CSI Pc; Pt; Pl; Pb; Pr$ x\n *   Fill Rectangular Area (DECFRA), VT420 and up.\n *     Pc is the character to use.\n *     Pt; Pl; Pb; Pr denotes the rectangle.\n * NOTE: xterm doesn't enable this code by default.\n */Terminal.prototype.fillRectangle=function(params){var ch=params[0],t=params[1],l=params[2],b=params[3],r=params[4];var line,i;for(;t<b+1;t++){line=this.lines[this.ybase+t];for(i=l;i<r;i++){line[i]=[line[i][0],String.fromCharCode(ch)];}}// this.maxRange();\nthis.updateRange(params[1]);this.updateRange(params[3]);};/**\n * CSI Ps ; Pu ' z\n *   Enable Locator Reporting (DECELR).\n *   Valid values for the first parameter:\n *     Ps = 0  -> Locator disabled (default).\n *     Ps = 1  -> Locator enabled.\n *     Ps = 2  -> Locator enabled for one report, then disabled.\n *   The second parameter specifies the coordinate unit for locator\n *   reports.\n *   Valid values for the second parameter:\n *     Pu = 0  <- or omitted -> default to character cells.\n *     Pu = 1  <- device physical pixels.\n *     Pu = 2  <- character cells.\n */Terminal.prototype.enableLocatorReporting=function(params){var val=params[0]>0;//this.mouseEvents = val;\n//this.decLocator = val;\n};/**\n * CSI Pt; Pl; Pb; Pr$ z\n *   Erase Rectangular Area (DECERA), VT400 and up.\n *     Pt; Pl; Pb; Pr denotes the rectangle.\n * NOTE: xterm doesn't enable this code by default.\n */Terminal.prototype.eraseRectangle=function(params){var t=params[0],l=params[1],b=params[2],r=params[3];var line,i,ch;ch=[this.eraseAttr(),' ',1];// xterm?\nfor(;t<b+1;t++){line=this.lines[this.ybase+t];for(i=l;i<r;i++){line[i]=ch;}}// this.maxRange();\nthis.updateRange(params[0]);this.updateRange(params[2]);};/**\n * CSI P m SP }\n * Insert P s Column(s) (default = 1) (DECIC), VT420 and up.\n * NOTE: xterm doesn't enable this code by default.\n */Terminal.prototype.insertColumns=function(){var param=params[0],l=this.ybase+this.rows,ch=[this.eraseAttr(),' ',1]// xterm?\n,i;while(param--){for(i=this.ybase;i<l;i++){this.lines[i].splice(this.x+1,0,ch);this.lines[i].pop();}}this.maxRange();};/**\n * CSI P m SP ~\n * Delete P s Column(s) (default = 1) (DECDC), VT420 and up\n * NOTE: xterm doesn't enable this code by default.\n */Terminal.prototype.deleteColumns=function(){var param=params[0],l=this.ybase+this.rows,ch=[this.eraseAttr(),' ',1]// xterm?\n,i;while(param--){for(i=this.ybase;i<l;i++){this.lines[i].splice(this.x,1);this.lines[i].push(ch);}}this.maxRange();};/**\n * Character Sets\n */Terminal.charsets={};// DEC Special Character and Line Drawing Set.\n// http://vt100.net/docs/vt102-ug/table5-13.html\n// A lot of curses apps use this if they see TERM=xterm.\n// testing: echo -e '\\e(0a\\e(B'\n// The xterm output sometimes seems to conflict with the\n// reference above. xterm seems in line with the reference\n// when running vttest however.\n// The table below now uses xterm's output from vttest.\nTerminal.charsets.SCLD={// (0\n'`':'\\u25C6',// '◆'\n'a':'\\u2592',// '▒'\n'b':'\\t',// '\\t'\n'c':'\\f',// '\\f'\n'd':'\\r',// '\\r'\n'e':'\\n',// '\\n'\n'f':'\\xB0',// '°'\n'g':'\\xB1',// '±'\n'h':'\\u2424',// '\\u2424' (NL)\n'i':'\\x0B',// '\\v'\n'j':'\\u2518',// '┘'\n'k':'\\u2510',// '┐'\n'l':'\\u250C',// '┌'\n'm':'\\u2514',// '└'\n'n':'\\u253C',// '┼'\n'o':'\\u23BA',// '⎺'\n'p':'\\u23BB',// '⎻'\n'q':'\\u2500',// '─'\n'r':'\\u23BC',// '⎼'\n's':'\\u23BD',// '⎽'\n't':'\\u251C',// '├'\n'u':'\\u2524',// '┤'\n'v':'\\u2534',// '┴'\n'w':'\\u252C',// '┬'\n'x':'\\u2502',// '│'\n'y':'\\u2264',// '≤'\n'z':'\\u2265',// '≥'\n'{':'\\u03C0',// 'π'\n'|':'\\u2260',// '≠'\n'}':'\\xA3',// '£'\n'~':'\\xB7'// '·'\n};Terminal.charsets.UK=null;// (A\nTerminal.charsets.US=null;// (B (USASCII)\nTerminal.charsets.Dutch=null;// (4\nTerminal.charsets.Finnish=null;// (C or (5\nTerminal.charsets.French=null;// (R\nTerminal.charsets.FrenchCanadian=null;// (Q\nTerminal.charsets.German=null;// (K\nTerminal.charsets.Italian=null;// (Y\nTerminal.charsets.NorwegianDanish=null;// (E or (6\nTerminal.charsets.Spanish=null;// (Z\nTerminal.charsets.Swedish=null;// (H or (7\nTerminal.charsets.Swiss=null;// (=\nTerminal.charsets.ISOLatin=null;// /A\n/**\n * Helpers\n */function on(el,type,handler,capture){if(!Array.isArray(el)){el=[el];}el.forEach(function(element){element.addEventListener(type,handler,capture||false);});}function off(el,type,handler,capture){el.removeEventListener(type,handler,capture||false);}function cancel(ev,force){if(!this.cancelEvents&&!force){return;}ev.preventDefault();ev.stopPropagation();return false;}function inherits(child,parent){function f(){this.constructor=child;}f.prototype=parent.prototype;child.prototype=new f();}// if bold is broken, we can't\n// use it in the terminal.\nfunction isBoldBroken(document){var body=document.getElementsByTagName('body')[0];var el=document.createElement('span');el.innerHTML='hello world';body.appendChild(el);var w1=el.scrollWidth;el.style.fontWeight='bold';var w2=el.scrollWidth;body.removeChild(el);return w1!==w2;}function indexOf(obj,el){var i=obj.length;while(i--){if(obj[i]===el)return i;}return-1;}function isThirdLevelShift(term,ev){var thirdLevelKey=term.browser.isMac&&ev.altKey&&!ev.ctrlKey&&!ev.metaKey||term.browser.isMSWindows&&ev.altKey&&ev.ctrlKey&&!ev.metaKey;if(ev.type=='keypress'){return thirdLevelKey;}// Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\nreturn thirdLevelKey&&(!ev.keyCode||ev.keyCode>47);}function matchColor(r1,g1,b1){var hash=r1<<16|g1<<8|b1;if(matchColor._cache[hash]!=null){return matchColor._cache[hash];}var ldiff=Infinity,li=-1,i=0,c,r2,g2,b2,diff;for(;i<Terminal.vcolors.length;i++){c=Terminal.vcolors[i];r2=c[0];g2=c[1];b2=c[2];diff=matchColor.distance(r1,g1,b1,r2,g2,b2);if(diff===0){li=i;break;}if(diff<ldiff){ldiff=diff;li=i;}}return matchColor._cache[hash]=li;}matchColor._cache={};// http://stackoverflow.com/questions/1633828\nmatchColor.distance=function(r1,g1,b1,r2,g2,b2){return Math.pow(30*(r1-r2),2)+Math.pow(59*(g1-g2),2)+Math.pow(11*(b1-b2),2);};function each(obj,iter,con){if(obj.forEach)return obj.forEach(iter,con);for(var i=0;i<obj.length;i++){iter.call(con,obj[i],i,obj);}}function keys(obj){if(Object.keys)return Object.keys(obj);var key,keys=[];for(key in obj){if(Object.prototype.hasOwnProperty.call(obj,key)){keys.push(key);}}return keys;}var wcwidth=function(opts){// extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c\n// combining characters\nvar COMBINING=[[0x0300,0x036F],[0x0483,0x0486],[0x0488,0x0489],[0x0591,0x05BD],[0x05BF,0x05BF],[0x05C1,0x05C2],[0x05C4,0x05C5],[0x05C7,0x05C7],[0x0600,0x0603],[0x0610,0x0615],[0x064B,0x065E],[0x0670,0x0670],[0x06D6,0x06E4],[0x06E7,0x06E8],[0x06EA,0x06ED],[0x070F,0x070F],[0x0711,0x0711],[0x0730,0x074A],[0x07A6,0x07B0],[0x07EB,0x07F3],[0x0901,0x0902],[0x093C,0x093C],[0x0941,0x0948],[0x094D,0x094D],[0x0951,0x0954],[0x0962,0x0963],[0x0981,0x0981],[0x09BC,0x09BC],[0x09C1,0x09C4],[0x09CD,0x09CD],[0x09E2,0x09E3],[0x0A01,0x0A02],[0x0A3C,0x0A3C],[0x0A41,0x0A42],[0x0A47,0x0A48],[0x0A4B,0x0A4D],[0x0A70,0x0A71],[0x0A81,0x0A82],[0x0ABC,0x0ABC],[0x0AC1,0x0AC5],[0x0AC7,0x0AC8],[0x0ACD,0x0ACD],[0x0AE2,0x0AE3],[0x0B01,0x0B01],[0x0B3C,0x0B3C],[0x0B3F,0x0B3F],[0x0B41,0x0B43],[0x0B4D,0x0B4D],[0x0B56,0x0B56],[0x0B82,0x0B82],[0x0BC0,0x0BC0],[0x0BCD,0x0BCD],[0x0C3E,0x0C40],[0x0C46,0x0C48],[0x0C4A,0x0C4D],[0x0C55,0x0C56],[0x0CBC,0x0CBC],[0x0CBF,0x0CBF],[0x0CC6,0x0CC6],[0x0CCC,0x0CCD],[0x0CE2,0x0CE3],[0x0D41,0x0D43],[0x0D4D,0x0D4D],[0x0DCA,0x0DCA],[0x0DD2,0x0DD4],[0x0DD6,0x0DD6],[0x0E31,0x0E31],[0x0E34,0x0E3A],[0x0E47,0x0E4E],[0x0EB1,0x0EB1],[0x0EB4,0x0EB9],[0x0EBB,0x0EBC],[0x0EC8,0x0ECD],[0x0F18,0x0F19],[0x0F35,0x0F35],[0x0F37,0x0F37],[0x0F39,0x0F39],[0x0F71,0x0F7E],[0x0F80,0x0F84],[0x0F86,0x0F87],[0x0F90,0x0F97],[0x0F99,0x0FBC],[0x0FC6,0x0FC6],[0x102D,0x1030],[0x1032,0x1032],[0x1036,0x1037],[0x1039,0x1039],[0x1058,0x1059],[0x1160,0x11FF],[0x135F,0x135F],[0x1712,0x1714],[0x1732,0x1734],[0x1752,0x1753],[0x1772,0x1773],[0x17B4,0x17B5],[0x17B7,0x17BD],[0x17C6,0x17C6],[0x17C9,0x17D3],[0x17DD,0x17DD],[0x180B,0x180D],[0x18A9,0x18A9],[0x1920,0x1922],[0x1927,0x1928],[0x1932,0x1932],[0x1939,0x193B],[0x1A17,0x1A18],[0x1B00,0x1B03],[0x1B34,0x1B34],[0x1B36,0x1B3A],[0x1B3C,0x1B3C],[0x1B42,0x1B42],[0x1B6B,0x1B73],[0x1DC0,0x1DCA],[0x1DFE,0x1DFF],[0x200B,0x200F],[0x202A,0x202E],[0x2060,0x2063],[0x206A,0x206F],[0x20D0,0x20EF],[0x302A,0x302F],[0x3099,0x309A],[0xA806,0xA806],[0xA80B,0xA80B],[0xA825,0xA826],[0xFB1E,0xFB1E],[0xFE00,0xFE0F],[0xFE20,0xFE23],[0xFEFF,0xFEFF],[0xFFF9,0xFFFB],[0x10A01,0x10A03],[0x10A05,0x10A06],[0x10A0C,0x10A0F],[0x10A38,0x10A3A],[0x10A3F,0x10A3F],[0x1D167,0x1D169],[0x1D173,0x1D182],[0x1D185,0x1D18B],[0x1D1AA,0x1D1AD],[0x1D242,0x1D244],[0xE0001,0xE0001],[0xE0020,0xE007F],[0xE0100,0xE01EF]];// binary search\nfunction bisearch(ucs){var min=0;var max=COMBINING.length-1;var mid;if(ucs<COMBINING[0][0]||ucs>COMBINING[max][1])return false;while(max>=min){mid=Math.floor((min+max)/2);if(ucs>COMBINING[mid][1])min=mid+1;else if(ucs<COMBINING[mid][0])max=mid-1;else return true;}return false;}function wcwidth(ucs){// test for 8-bit control characters\nif(ucs===0)return opts.nul;if(ucs<32||ucs>=0x7f&&ucs<0xa0)return opts.control;// binary search in table of non-spacing characters\nif(bisearch(ucs))return 0;// if we arrive here, ucs is not a combining or C0/C1 control character\nreturn 1+(ucs>=0x1100&&(ucs<=0x115f||// Hangul Jamo init. consonants\nucs==0x2329||ucs==0x232a||ucs>=0x2e80&&ucs<=0xa4cf&&ucs!=0x303f||// CJK..Yi\nucs>=0xac00&&ucs<=0xd7a3||// Hangul Syllables\nucs>=0xf900&&ucs<=0xfaff||// CJK Compat Ideographs\nucs>=0xfe10&&ucs<=0xfe19||// Vertical forms\nucs>=0xfe30&&ucs<=0xfe6f||// CJK Compat Forms\nucs>=0xff00&&ucs<=0xff60||// Fullwidth Forms\nucs>=0xffe0&&ucs<=0xffe6||ucs>=0x20000&&ucs<=0x2fffd||ucs>=0x30000&&ucs<=0x3fffd));}return wcwidth;}({nul:0,control:0});// configurable options\n/**\n * Expose\n */Terminal.EventEmitter=_EventEmitter.EventEmitter;Terminal.CompositionHelper=_CompositionHelper.CompositionHelper;Terminal.Viewport=_Viewport.Viewport;Terminal.inherits=inherits;/**\n * Adds an event listener to the terminal.\n *\n * @param {string} event The name of the event. TODO: Document all event types\n * @param {function} callback The function to call when the event is triggered.\n */Terminal.on=on;Terminal.off=off;Terminal.cancel=cancel;module.exports=Terminal;\n\n},{\"./CompositionHelper.js\":1,\"./EventEmitter.js\":2,\"./Viewport.js\":3,\"./handlers/Clipboard.js\":4,\"./utils/Browser\":5}]},{},[7])(7)\n});\n//# sourceMappingURL=xterm.js.map\n"
  },
  {
    "path": "static/assets/pages/chartjs.init.js",
    "content": "/**\nTemplate Name: Ubold Dashboard\nAuthor: CoderThemes\nEmail: coderthemes@gmail.com\nFile: Chartjs\n*/\n\n\n!function($) {\n    \"use strict\";\n\n    var ChartJs = function() {};\n\n    ChartJs.prototype.respChart = function respChart(selector,type,data, options) {\n        // get selector by context\n        var ctx = selector.get(0).getContext(\"2d\");\n        // pointing parent container to make chart js inherit its width\n        var container = $(selector).parent();\n\n        // enable resizing matter\n        $(window).resize( generateChart );\n\n        // this function produce the responsive Chart JS\n        function generateChart(){\n            // make chart width fit with its container\n            var ww = selector.attr('width', $(container).width() );\n            switch(type){\n                case 'Line':\n                    new Chart(ctx).Line(data, options);\n                    break;\n                case 'Doughnut':\n                    new Chart(ctx).Doughnut(data, options);\n                    break;\n                case 'Pie':\n                    new Chart(ctx).Pie(data, options);\n                    break;\n                case 'Bar':\n                    new Chart(ctx).Bar(data, options);\n                    break;\n                case 'Radar':\n                    new Chart(ctx).Radar(data, options);\n                    break;\n                case 'PolarArea':\n                    new Chart(ctx).PolarArea(data, options);\n                    break;\n            }\n            // Initiate new chart or Redraw\n\n        };\n        // run function - render chart at first load\n        generateChart();\n    },\n    //init\n    ChartJs.prototype.init = function() {\n        //creating lineChart\n        var LineChart = {\n            labels : [\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\"],\n            datasets : [\n                {\n                    fillColor : \"rgba(93, 156, 236, 0.5)\",\n                    strokeColor : \"rgba(93, 156, 236, 1)\",\n                    pointColor : \"rgba(93, 156, 236, 1)\",\n                    pointStrokeColor : \"#fff\",\n                    data : [33,52,63,92,50,53,46]\n                },\n                {\n                    fillColor : \"rgba(95, 190, 170, 0.5)\",\n                    strokeColor : \"rgba(95, 190, 170, 1)\",\n                    pointColor : \"rgba(95, 190, 170, 1)\",\n                    pointStrokeColor : \"#fff\",\n                    data : [22,20,30,60,29,25,12]\n                }\n                \n            ]\n        };\n        \n        this.respChart($(\"#lineChart\"),'Line',LineChart);\n\n        //donut chart\n        var DonutChart = [\n            {\n                value: 300,\n                color: \"#5fbeaa\",\n                highlight: \"#5fbeaa\",\n                label: \"Chrome\"\n            }, {\n                value: 50,\n                color: \"#36404a\",\n                highlight: \"#36404a\",\n                label: \"IE\"\n            }, {\n                value: 40,\n                color: \"#ebeff2\",\n                highlight: \"#ebeff2\",\n                label: \"Other\"\n            }, {\n                value: 120,\n                color: \"#5d9cec\",\n                highlight: \"#5d9cec\",\n                label: \"Firefox\"\n            }\n\n        ]\n        this.respChart($(\"#doughnut\"),'Doughnut',DonutChart);\n\n\n        //Pie chart\n        var PieChart = [\n            {\n                value: 40,\n                color:\"#ebeff2\",\n                label: \"IE\"\n            },\n            {\n                value : 80,\n                color : \"#5fbeaa\",\n                label: \"Chrome\"\n            },\n            {\n                value : 70,\n                color : \"#5d9cec\",\n                label: \"Safari\"\n            }\n        ]\n        this.respChart($(\"#pie\"),'Pie',PieChart);\n\n\n        //barchart\n        var BarChart = {\n            labels : [\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\"],\n            datasets : [\n                {\n                    fillColor: 'rgba(93, 156, 236, 0.7)',\n                    strokeColor: 'rgba(93, 156, 236, 1)',\n                    highlightFill: 'rgba(93, 156, 236, 1)',\n                    highlightStroke: 'rgba(93, 156, 236, 0.9)',\n                    data : [65,59,90,81,56,55,40]\n                },\n                {\n                    fillColor: 'rgba(235, 239, 242, 0.7)',\n                    strokeColor: 'rgba(235, 239, 242, 1)',\n                    highlightFill: 'rgba(235, 239, 242, 1)',\n                    highlightStroke: 'rgba(235, 239, 242, 0.9)',\n                    data : [28,48,40,19,96,27,100]\n                }\n            ]\n        }\n        this.respChart($(\"#bar\"),'Bar',BarChart);\n        \n        \n        //barchart-Single\n        var BarChartSingle = {\n            labels : [\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"],\n            datasets : [\n                {\n                    fillColor: '#ebeff2',\n                    strokeColor: '#ebeff2',\n                    highlightFill: '#5fbeaa',\n                    highlightStroke: '#ebeff2',\n                    data : [65,59,90,81,56,55,40,34,50,35,90,75]\n                }\n            ]\n        }\n        this.respChart($(\"#bar-single\"),'Bar',BarChartSingle);\n\n        //radar chart\n        var RadarChart = {\n            labels : [\"Eating\",\"Drinking\",\"Sleeping\",\"Designing\",\"Coding\",\"Partying\",\"Running\"],\n            datasets : [\n                {\n                    fillColor : \"rgba(93, 156, 236, 0.5)\",\n                    strokeColor : \"rgba(93, 156, 236, 0.5)\",\n                    pointColor : \"rgba(93, 156, 236, 1)\",\n                    pointStrokeColor : \"#fff\",\n                    data : [65,59,90,81,56,55,40]\n                },\n                {\n                    fillColor : \"rgba(54, 64, 74, 0.5)\",\n                    strokeColor : \"rgba(54, 64, 74, 0.8)\",\n                    pointColor : \"rgba(54, 64, 74, 1)\",\n                    pointStrokeColor : \"#fff\",\n                    data : [28,48,40,19,96,27,100]\n                }\n            ]\n        }\n        this.respChart($(\"#radar\"),'Radar',RadarChart);\n\n        //Polar area chart\n        var PolarChart = [\n            \n            {\n                value : 90,\n                color: \"#5fbeaa\",\n                label: \"Chrom\"\n            },\n            {\n                value : 24,\n                color: \"#1a2942\",\n                label: \"Firefox\"\n            },\n            {\n                value : 58,\n                color: \"#5d9cec\",\n                label: \"Other\"\n            },\n            \n            {\n                value : 42,\n                color: \"#ebeff2\",\n                label: \"IE9+\"\n            }\n        ]\n        this.respChart($(\"#polarArea\"),'PolarArea',PolarChart);\n    },\n    $.ChartJs = new ChartJs, $.ChartJs.Constructor = ChartJs\n\n}(window.jQuery),\n\n//initializing \nfunction($) {\n    \"use strict\";\n    $.ChartJs.init()\n}(window.jQuery);\n\n"
  },
  {
    "path": "static/assets/pages/datatables.editable.init.js",
    "content": "/**\n* Theme: Ubold Admin Template\n* Author: Coderthemes\n* Component: Editable\n* \n*/\n\n(function( $ ) {\n\n\t'use strict';\n\n\tvar EditableTable = {\n\n\t\toptions: {\n\t\t\taddButton: '#addToTable',\n\t\t\ttable: '#datatable-editable',\n\t\t\tdialog: {\n\t\t\t\twrapper: '#dialog',\n\t\t\t\tcancelButton: '#dialogCancel',\n\t\t\t\tconfirmButton: '#dialogConfirm',\n\t\t\t}\n\t\t},\n\n\t\tinitialize: function() {\n\t\t\tthis\n\t\t\t\t.setVars()\n\t\t\t\t.build()\n\t\t\t\t.events();\n\t\t},\n\n\t\tsetVars: function() {\n\t\t\tthis.$table\t\t\t\t= $( this.options.table );\n\t\t\tthis.$addButton\t\t\t= $( this.options.addButton );\n\n\t\t\t// dialog\n\t\t\tthis.dialog\t\t\t\t= {};\n\t\t\tthis.dialog.$wrapper\t= $( this.options.dialog.wrapper );\n\t\t\tthis.dialog.$cancel\t\t= $( this.options.dialog.cancelButton );\n\t\t\tthis.dialog.$confirm\t= $( this.options.dialog.confirmButton );\n\n\t\t\treturn this;\n\t\t},\n\n\t\tbuild: function() {\n\t\t\tthis.datatable = this.$table.DataTable({\n\t\t\t\taoColumns: [\n\t\t\t\t\tnull,\n\t\t\t\t\tnull,\n\t\t\t\t\tnull,\n\t\t\t\t\t{ \"bSortable\": false }\n\t\t\t\t]\n\t\t\t});\n\n\t\t\twindow.dt = this.datatable;\n\n\t\t\treturn this;\n\t\t},\n\n\t\tevents: function() {\n\t\t\tvar _self = this;\n\n\t\t\tthis.$table\n\t\t\t\t.on('click', 'a.save-row', function( e ) {\n\t\t\t\t\te.preventDefault();\n\n\t\t\t\t\t_self.rowSave( $(this).closest( 'tr' ) );\n\t\t\t\t})\n\t\t\t\t.on('click', 'a.cancel-row', function( e ) {\n\t\t\t\t\te.preventDefault();\n\n\t\t\t\t\t_self.rowCancel( $(this).closest( 'tr' ) );\n\t\t\t\t})\n\t\t\t\t.on('click', 'a.edit-row', function( e ) {\n\t\t\t\t\te.preventDefault();\n\n\t\t\t\t\t_self.rowEdit( $(this).closest( 'tr' ) );\n\t\t\t\t})\n\t\t\t\t.on( 'click', 'a.remove-row', function( e ) {\n\t\t\t\t\te.preventDefault();\n\n\t\t\t\t\tvar $row = $(this).closest( 'tr' );\n\n\t\t\t\t\t$.magnificPopup.open({\n\t\t\t\t\t\titems: {\n\t\t\t\t\t\t\tsrc: _self.options.dialog.wrapper,\n\t\t\t\t\t\t\ttype: 'inline'\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpreloader: false,\n\t\t\t\t\t\tmodal: true,\n\t\t\t\t\t\tcallbacks: {\n\t\t\t\t\t\t\tchange: function() {\n\t\t\t\t\t\t\t\t_self.dialog.$confirm.on( 'click', function( e ) {\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\n\t\t\t\t\t\t\t\t\t_self.rowRemove( $row );\n\t\t\t\t\t\t\t\t\t$.magnificPopup.close();\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tclose: function() {\n\t\t\t\t\t\t\t\t_self.dialog.$confirm.off( 'click' );\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\n\t\t\tthis.$addButton.on( 'click', function(e) {\n\t\t\t\te.preventDefault();\n\n\t\t\t\t_self.rowAdd();\n\t\t\t});\n\n\t\t\tthis.dialog.$cancel.on( 'click', function( e ) {\n\t\t\t\te.preventDefault();\n\t\t\t\t$.magnificPopup.close();\n\t\t\t});\n\n\t\t\treturn this;\n\t\t},\n\n\t\t// ==========================================================================================\n\t\t// ROW FUNCTIONS\n\t\t// ==========================================================================================\n\t\trowAdd: function() {\n\t\t\tthis.$addButton.attr({ 'disabled': 'disabled' });\n\n\t\t\tvar actions,\n\t\t\t\tdata,\n\t\t\t\t$row;\n\n\t\t\tactions = [\n\t\t\t\t'<a href=\"#\" class=\"hidden on-editing save-row\"><i class=\"fa fa-save\"></i></a>',\n\t\t\t\t'<a href=\"#\" class=\"hidden on-editing cancel-row\"><i class=\"fa fa-times\"></i></a>',\n\t\t\t\t'<a href=\"#\" class=\"on-default edit-row\"><i class=\"fa fa-pencil\"></i></a>',\n\t\t\t\t'<a href=\"#\" class=\"on-default remove-row\"><i class=\"fa fa-trash-o\"></i></a>'\n\t\t\t].join(' ');\n\n\t\t\tdata = this.datatable.row.add([ '', '', '', actions ]);\n\t\t\t$row = this.datatable.row( data[0] ).nodes().to$();\n\n\t\t\t$row\n\t\t\t\t.addClass( 'adding' )\n\t\t\t\t.find( 'td:last' )\n\t\t\t\t.addClass( 'actions' );\n\n\t\t\tthis.rowEdit( $row );\n\n\t\t\tthis.datatable.order([0,'asc']).draw(); // always show fields\n\t\t},\n\n\t\trowCancel: function( $row ) {\n\t\t\tvar _self = this,\n\t\t\t\t$actions,\n\t\t\t\ti,\n\t\t\t\tdata;\n\n\t\t\tif ( $row.hasClass('adding') ) {\n\t\t\t\tthis.rowRemove( $row );\n\t\t\t} else {\n\n\t\t\t\tdata = this.datatable.row( $row.get(0) ).data();\n\t\t\t\tthis.datatable.row( $row.get(0) ).data( data );\n\n\t\t\t\t$actions = $row.find('td.actions');\n\t\t\t\tif ( $actions.get(0) ) {\n\t\t\t\t\tthis.rowSetActionsDefault( $row );\n\t\t\t\t}\n\n\t\t\t\tthis.datatable.draw();\n\t\t\t}\n\t\t},\n\n\t\trowEdit: function( $row ) {\n\t\t\tvar _self = this,\n\t\t\t\tdata;\n\n\t\t\tdata = this.datatable.row( $row.get(0) ).data();\n\n\t\t\t$row.children( 'td' ).each(function( i ) {\n\t\t\t\tvar $this = $( this );\n\n\t\t\t\tif ( $this.hasClass('actions') ) {\n\t\t\t\t\t_self.rowSetActionsEditing( $row );\n\t\t\t\t} else {\n\t\t\t\t\t$this.html( '<input type=\"text\" class=\"form-control input-block\" value=\"' + data[i] + '\"/>' );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\trowSave: function( $row ) {\n\t\t\tvar _self     = this,\n\t\t\t\t$actions,\n\t\t\t\tvalues    = [];\n\n\t\t\tif ( $row.hasClass( 'adding' ) ) {\n\t\t\t\tthis.$addButton.removeAttr( 'disabled' );\n\t\t\t\t$row.removeClass( 'adding' );\n\t\t\t}\n\n\t\t\tvalues = $row.find('td').map(function() {\n\t\t\t\tvar $this = $(this);\n\n\t\t\t\tif ( $this.hasClass('actions') ) {\n\t\t\t\t\t_self.rowSetActionsDefault( $row );\n\t\t\t\t\treturn _self.datatable.cell( this ).data();\n\t\t\t\t} else {\n\t\t\t\t\treturn $.trim( $this.find('input').val() );\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.datatable.row( $row.get(0) ).data( values );\n\n\t\t\t$actions = $row.find('td.actions');\n\t\t\tif ( $actions.get(0) ) {\n\t\t\t\tthis.rowSetActionsDefault( $row );\n\t\t\t}\n\n\t\t\tthis.datatable.draw();\n\t\t},\n\n\t\trowRemove: function( $row ) {\n\t\t\tif ( $row.hasClass('adding') ) {\n\t\t\t\tthis.$addButton.removeAttr( 'disabled' );\n\t\t\t}\n\n\t\t\tthis.datatable.row( $row.get(0) ).remove().draw();\n\t\t},\n\n\t\trowSetActionsEditing: function( $row ) {\n\t\t\t$row.find( '.on-editing' ).removeClass( 'hidden' );\n\t\t\t$row.find( '.on-default' ).addClass( 'hidden' );\n\t\t},\n\n\t\trowSetActionsDefault: function( $row ) {\n\t\t\t$row.find( '.on-editing' ).addClass( 'hidden' );\n\t\t\t$row.find( '.on-default' ).removeClass( 'hidden' );\n\t\t}\n\n\t};\n\n\t$(function() {\n\t\tEditableTable.initialize();\n\t});\n\n}).apply( this, [ jQuery ]);"
  },
  {
    "path": "static/assets/pages/easy-pie-chart.init.js",
    "content": "/**\n* Theme: Ubold Admin Template\n* Author: Coderthemes\n* Easy pie chart\n*/\n\n!function($) {\n    \"use strict\";\n\n    var EasyPieChart = function() {};\n\n    EasyPieChart.prototype.init = function() {\n    \t//initializing various types of easy pie charts\n    \t$('.easy-pie-chart-1').easyPieChart({\n\t\t\teasing: 'easeOutBounce',\n\t\t\tbarColor : '#5d9cec',\n\t\t\tlineWidth: 10,\n\t\t\tanimate: 1000,\n            scaleColor: false,\n            lineCap: 'square',\n            trackColor: '#e5e5e5',\n\t\t\tonStep: function(from, to, percent) {\n\t\t\t\t$(this.el).find('.percent').text(Math.round(percent));\n\t\t\t}\n\t\t});\n\t\t$('.easy-pie-chart-2').easyPieChart({\n\t\t\teasing: 'easeOutBounce',\n\t\t\tbarColor : '#fb6d9d',\n\t\t\tlineWidth: 10,\n\t\t\ttrackColor : false,\n\t\t\tlineCap : 'butt',\n\t\t\tonStep: function(from, to, percent) {\n\t\t\t\t$(this.el).find('.percent').text(Math.round(percent));\n\t\t\t}\n\t\t});\n\t\t$('.easy-pie-chart-3').easyPieChart({\n\t\t\teasing: 'easeOutBounce',\n\t\t\tbarColor : '#34d3eb',\n\t\t\tlineWidth: 10,\n\t\t\tlineCap : 'square',\n\t\t\tscaleColor: \"transparent\",\n\t\t\tonStep: function(from, to, percent) {\n\t\t\t\t$(this.el).find('.percent').text(Math.round(percent));\n\t\t\t}\n\t\t});\n\t\t$('.easy-pie-chart-4').easyPieChart({\n\t\t\teasing: 'easeOutBounce',\n\t\t\tbarColor : '#5fbeaa',\n\t\t\tlineWidth: 10,\n\t\t\tonStep: function(from, to, percent) {\n\t\t\t\t$(this.el).find('.percent').text(Math.round(percent));\n\t\t\t}\n\t\t});\n    },\n    //init\n    $.EasyPieChart = new EasyPieChart, $.EasyPieChart.Constructor = EasyPieChart\n}(window.jQuery),\n\n//initializing\nfunction($) {\n    \"use strict\";\n    $.EasyPieChart.init()\n}(window.jQuery);"
  },
  {
    "path": "static/assets/pages/jquery.bs-table.js",
    "content": "\n/**\n* Theme: Ubold Admin Template\n* Author: Coderthemes\n* bootstrap tables\n*/\n\n\n\n$(document).ready(function() {\n\n\n\t// BOOTSTRAP TABLE - CUSTOM TOOLBAR\n\t// =================================================================\n\t// Require Bootstrap Table\n\t// http://bootstrap-table.wenzhixin.net.cn/\n\t// =================================================================\n\tvar $table = $('#demo-custom-toolbar'),\t$remove = $('#demo-delete-row');\n\n\t$table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table', function () {\n\t\t$remove.prop('disabled', !$table.bootstrapTable('getSelections').length);\n\t});\n\n\t$remove.click(function () {\n\t\tvar ids = $.map($table.bootstrapTable('getSelections'), function (row) {\n\t\t\treturn row.id\n\t\t});\n\t\t$table.bootstrapTable('remove', {\n\t\t\tfield: 'id',\n\t\t\tvalues: ids\n\t\t});\n\t\t$remove.prop('disabled', true);\n\t});\n\n\n});\n\n// FORMAT COLUMN\n// Use \"data-formatter\" on HTML to format the display of bootstrap table column.\n// =================================================================\n\n\n// Sample format for Invoice Column.\n// =================================================================\nfunction invoiceFormatter(value, row) {\n\treturn '<a href=\"#\" class=\"btn-link\" > Order #' + value + '</a>';\n}\n\n// Sample Format for User Name Column.\n// =================================================================\nfunction nameFormatter(value, row) {\n\treturn '<a href=\"#\" class=\"btn-link\" > ' + value + '</a>';\n}\n\n// Sample Format for Order Date Column.\n// =================================================================\nfunction dateFormatter(value, row) {\n\tvar icon = row.id % 2 === 0 ? 'fa-star' : 'fa-user';\n\treturn '<span class=\"text-muted\"> ' + value + '</span>';\n}\n\n\n// Sample Format for Order Status Column.\n// =================================================================\nfunction statusFormatter(value, row) {\n\tvar labelColor;\n\tif (value == \"Paid\") {\n\t\tlabelColor = \"success\";\n\t}else if(value == \"Unpaid\"){\n\t\tlabelColor = \"warning\";\n\t}else if(value == \"Shipped\"){\n\t\tlabelColor = \"info\";\n\t}else if(value == \"Refunded\"){\n\t\tlabelColor = \"danger\";\n\t}\n\tvar icon = row.id % 2 === 0 ? 'fa-star' : 'fa-user';\n\treturn '<div class=\"label label-table label-'+ labelColor+'\"> ' + value + '</div>';\n}\n\n\n// Sort Price Column\n// =================================================================\nfunction priceSorter(a, b) {\n\ta = +a.substring(1); // remove $\n\tb = +b.substring(1);\n\tif (a > b) return 1;\n\tif (a < b) return -1;\n\treturn 0;\n}\n\n"
  },
  {
    "path": "static/assets/pages/jquery.dashboard.js",
    "content": "\n/**\n* Theme: Ubold Admin Template\n* Author: Coderthemes\n* Morris Chart\n*/\n\n!function($) {\n    \"use strict\";\n\n    var Dashboard1 = function() {\n    \tthis.$realData = []\n    };\n    \n    //creates Stacked chart\n    Dashboard1.prototype.createStackedChart  = function(element, data, xkey, ykeys, labels, lineColors) {\n        Morris.Bar({\n            element: element,\n            data: data,\n            xkey: xkey,\n            ykeys: ykeys,\n            stacked: true,\n            labels: labels,\n            hideHover: 'auto',\n            resize: true, //defaulted to true\n            gridLineColor: '#eeeeee',\n            barColors: lineColors\n        });\n    },\n\n    //creates area chart with dotted\n    Dashboard1.prototype.createAreaChartDotted = function(element, pointSize, lineWidth, data, xkey, ykeys, labels, Pfillcolor, Pstockcolor, lineColors) {\n        Morris.Area({\n            element: element,\n            pointSize: 0,\n            lineWidth: 0,\n            data: data,\n            xkey: xkey,\n            ykeys: ykeys,\n            labels: labels,\n            hideHover: 'auto',\n            pointFillColors: Pfillcolor,\n            pointStrokeColors: Pstockcolor,\n            resize: true,\n            gridLineColor: '#eef0f2',\n            lineColors: lineColors\n        });\n\n   },\n    \n    \n    Dashboard1.prototype.init = function() {\n\n        //creating Stacked chart\n        var $stckedData  = [\n            { y: '2005', a: 45, b: 180, c: 100 },\n            { y: '2006', a: 75,  b: 65, c: 80 },\n            { y: '2007', a: 100, b: 90, c: 56 },\n            { y: '2008', a: 75,  b: 65, c: 89 },\n            { y: '2009', a: 100, b: 90, c: 120 },\n            { y: '2010', a: 75,  b: 65, c: 110 },\n            { y: '2011', a: 50,  b: 40, c: 85 },\n            { y: '2012', a: 75,  b: 65, c: 52 },\n            { y: '2013', a: 50,  b: 40, c: 77 },\n            { y: '2014', a: 75,  b: 65, c: 90 },\n            { y: '2015', a: 100, b: 90, c: 130 }\n        ];\n        this.createStackedChart('morris-bar-stacked', $stckedData, 'y', ['a', 'b', 'c'], ['Desktops', 'Tablets', 'Mobiles'], ['#5fbeaa', '#5d9cec', '#ebeff2']);\n\n        //creating area chart\n        var $areaDotData = [\n                { y: '2009', a: 10, b: 20, c:30 },\n                { y: '2010', a: 75,  b: 65, c:30 },\n                { y: '2011', a: 50,  b: 40, c:30 },\n                { y: '2012', a: 75,  b: 65, c:30 },\n                { y: '2013', a: 50,  b: 40, c:30 },\n                { y: '2014', a: 75,  b: 65, c:30 },\n                { y: '2015', a: 90, b: 60, c:30 }\n            ];\n        this.createAreaChartDotted('morris-area-with-dotted', 0, 0, $areaDotData, 'y', ['a', 'b', 'c'], ['Desktops ', 'Tablets ', 'Mobiles '],['#ffffff'],['#999999'], ['#5fbeaa', '#5d9cec','#ebeff2']);\n\n    },\n    //init\n    $.Dashboard1 = new Dashboard1, $.Dashboard1.Constructor = Dashboard1\n}(window.jQuery),\n\n//initializing \nfunction($) {\n    \"use strict\";\n    $.Dashboard1.init();\n}(window.jQuery);"
  },
  {
    "path": "static/assets/pages/jquery.flot.init.js",
    "content": "/**\n * Theme: Ubold Admin Template\n * Author: Coderthemes\n * Module/App: Flot-Chart\n */\n\n! function($) {\n\t\"use strict\";\n\n\tvar FlotChart = function() {\n\t\tthis.$body = $(\"body\")\n\t\tthis.$realData = []\n\t};\n\n\t//creates plot graph\n\tFlotChart.prototype.createPlotGraph = function(selector, data1, data2, labels, colors, borderColor, bgColor) {\n\t\t//shows tooltip\n\t\tfunction showTooltip(x, y, contents) {\n\t\t\t$('<div id=\"tooltip\" class=\"tooltipflot\">' + contents + '</div>').css({\n\t\t\t\tposition : 'absolute',\n\t\t\t\ttop : y + 5,\n\t\t\t\tleft : x + 5\n\t\t\t}).appendTo(\"body\").fadeIn(200);\n\t\t}\n\n\n\t\t$.plot($(selector), [{\n\t\t\tdata : data1,\n\t\t\tlabel : labels[0],\n\t\t\tcolor : colors[0]\n\t\t}, {\n\t\t\tdata : data2,\n\t\t\tlabel : labels[1],\n\t\t\tcolor : colors[1]\n\t\t}], {\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\tlineWidth : 1,\n\t\t\t\t\tfillColor : {\n\t\t\t\t\t\tcolors : [{\n\t\t\t\t\t\t\topacity : 0.5\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\topacity : 0.5\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tpoints : {\n\t\t\t\t\tshow : true\n\t\t\t\t},\n\t\t\t\tshadowSize : 0\n\t\t\t},\n\n\t\t\tgrid : {\n\t\t\t\thoverable : true,\n\t\t\t\tclickable : true,\n\t\t\t\tborderColor : borderColor,\n\t\t\t\ttickColor : \"#f9f9f9\",\n\t\t\t\tborderWidth : 1,\n\t\t\t\tlabelMargin : 10,\n\t\t\t\tbackgroundColor : bgColor\n\t\t\t},\n\t\t\tlegend : {\n\t\t\t\tposition : \"ne\",\n\t\t\t\tmargin : [0, -24],\n\t\t\t\tnoColumns : 0,\n\t\t\t\tlabelBoxBorderColor : null,\n\t\t\t\tlabelFormatter : function(label, series) {\n\t\t\t\t\t// just add some space to labes\n\t\t\t\t\treturn '' + label + '&nbsp;&nbsp;';\n\t\t\t\t},\n\t\t\t\twidth : 30,\n\t\t\t\theight : 2\n\t\t\t},\n\t\t\tyaxis : {\n\t\t\t\ttickColor : '#f5f5f5',\n\t\t\t\tfont : {\n\t\t\t\t\tcolor : '#bdbdbd'\n\t\t\t\t}\n\t\t\t},\n\t\t\txaxis : {\n\t\t\t\ttickColor : '#f5f5f5',\n\t\t\t\tfont : {\n\t\t\t\t\tcolor : '#bdbdbd'\n\t\t\t\t}\n\t\t\t},\n\t\t\ttooltip : true,\n\t\t\ttooltipOpts : {\n\t\t\t\tcontent : '%s: Value of %x is %y',\n\t\t\t\tshifts : {\n\t\t\t\t\tx : -60,\n\t\t\t\t\ty : 25\n\t\t\t\t},\n\t\t\t\tdefaultTheme : false\n\t\t\t}\n\t\t});\n\t},\n\t//end plot graph\n\n\t//creates Pie Chart\n\tFlotChart.prototype.createPieGraph = function(selector, labels, datas, colors) {\n\t\tvar data = [{\n\t\t\tlabel : labels[0],\n\t\t\tdata : datas[0]\n\t\t}, {\n\t\t\tlabel : labels[1],\n\t\t\tdata : datas[1]\n\t\t}, {\n\t\t\tlabel : labels[2],\n\t\t\tdata : datas[2]\n\t\t}];\n\t\tvar options = {\n\t\t\tseries : {\n\t\t\t\tpie : {\n\t\t\t\t\tshow : true\n\t\t\t\t}\n\t\t\t},\n\t\t\tlegend : {\n\t\t\t\tshow : false\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 : colors,\n\t\t\ttooltip : true,\n\t\t\ttooltipOpts : {\n\t\t\t\tcontent : \"%s, %p.0%\"\n\t\t\t}\n\t\t};\n\n\t\t$.plot($(selector), data, options);\n\t},\n\n\t//returns some random data\n\tFlotChart.prototype.randomData = function() {\n\t\tvar totalPoints = 300;\n\t\tif (this.$realData.length > 0)\n\t\t\tthis.$realData = this.$realData.slice(1);\n\n\t\t// Do a random walk\n\t\twhile (this.$realData.length < totalPoints) {\n\n\t\t\tvar prev = this.$realData.length > 0 ? this.$realData[this.$realData.length - 1] : 50,\n\t\t\t    y = prev + Math.random() * 10 - 5;\n\n\t\t\tif (y < 0) {\n\t\t\t\ty = 0;\n\t\t\t} else if (y > 100) {\n\t\t\t\ty = 100;\n\t\t\t}\n\n\t\t\tthis.$realData.push(y);\n\t\t}\n\n\t\t// Zip the generated y values with the x values\n\t\tvar res = [];\n\t\tfor (var i = 0; i < this.$realData.length; ++i) {\n\t\t\tres.push([i, this.$realData[i]])\n\t\t}\n\n\t\treturn res;\n\t}, FlotChart.prototype.createRealTimeGraph = function(selector, data, colors) {\n\t\tvar plot = $.plot(selector, [data], {\n\t\t\tcolors : colors,\n\t\t\tseries : {\n\t\t\t\tgrow : {\n\t\t\t\t\tactive : false\n\t\t\t\t}, //disable auto grow\n\t\t\t\tshadowSize : 0, // drawing is faster without shadows\n\t\t\t\tlines : {\n\t\t\t\t\tshow : true,\n\t\t\t\t\tfill : true,\n\t\t\t\t\tlineWidth : 2,\n\t\t\t\t\tsteps : false\n\t\t\t\t}\n\t\t\t},\n\t\t\tgrid : {\n\t\t\t\tshow : true,\n\t\t\t\taboveData : false,\n\t\t\t\tcolor : '#dcdcdc',\n\t\t\t\tlabelMargin : 15,\n\t\t\t\taxisMargin : 0,\n\t\t\t\tborderWidth : 0,\n\t\t\t\tborderColor : null,\n\t\t\t\tminBorderMargin : 5,\n\t\t\t\tclickable : true,\n\t\t\t\thoverable : true,\n\t\t\t\tautoHighlight : false,\n\t\t\t\tmouseActiveRadius : 20\n\t\t\t},\n\t\t\ttooltip : true, //activate tooltip\n\t\t\ttooltipOpts : {\n\t\t\t\tcontent : \"Value is : %y.0\" + \"%\",\n\t\t\t\tshifts : {\n\t\t\t\t\tx : -30,\n\t\t\t\t\ty : -50\n\t\t\t\t}\n\t\t\t},\n\t\t\tyaxis : {\n\t\t\t\tmin : 0,\n\t\t\t\tmax : 100,\n\t\t\t\tcolor : 'rgba(0,0,0,0.1)'\n\t\t\t},\n\t\t\txaxis : {\n\t\t\t\tshow : false\n\t\t\t}\n\t\t});\n\n\t\treturn plot;\n\t},\n\t//creates Pie Chart\n\tFlotChart.prototype.createDonutGraph = function(selector, labels, datas, colors) {\n\t\tvar data = [{\n\t\t\tlabel : labels[0],\n\t\t\tdata : datas[0]\n\t\t}, {\n\t\t\tlabel : labels[1],\n\t\t\tdata : datas[1]\n\t\t}, {\n\t\t\tlabel : labels[2],\n\t\t\tdata : datas[2]\n\t\t}, {\n\t\t\tlabel : labels[3],\n\t\t\tdata : datas[3]\n\t\t}];\n\t\tvar options = {\n\t\t\tseries : {\n\t\t\t\tpie : {\n\t\t\t\t\tshow : true,\n\t\t\t\t\tinnerRadius : 0.5\n\t\t\t\t}\n\t\t\t},\n\t\t\tlegend : {\n\t\t\t\tshow : true,\n\t\t\t\tlabelFormatter : function(label, series) {\n\t\t\t\t\treturn '<div style=\"font-size:14px;\">&nbsp;' + label + '</div>'\n\t\t\t\t},\n\t\t\t\tlabelBoxBorderColor : null,\n\t\t\t\tmargin : 50,\n\t\t\t\twidth : 20,\n\t\t\t\tpadding : 1\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 : colors,\n\t\t\ttooltip : true,\n\t\t\ttooltipOpts : {\n\t\t\t\tcontent : \"%s, %p.0%\"\n\t\t\t}\n\t\t};\n\n\t\t$.plot($(selector), data, options);\n\t},\n\t//creates Combine Chart\n\tFlotChart.prototype.createCombineGraph = function(selector, ticks, labels, datas) {\n\n\t\tvar data = [{\n\t\t\tlabel : labels[0],\n\t\t\tdata : datas[0],\n\t\t\tlines : {\n\t\t\t\tshow : true,\n\t\t\t\tfill : true\n\t\t\t},\n\t\t\tpoints : {\n\t\t\t\tshow : true\n\t\t\t}\n\t\t}, {\n\t\t\tlabel : labels[1],\n\t\t\tdata : datas[1],\n\t\t\tlines : {\n\t\t\t\tshow : true\n\t\t\t},\n\t\t\tpoints : {\n\t\t\t\tshow : true\n\t\t\t}\n\t\t}, {\n\t\t\tlabel : labels[2],\n\t\t\tdata : datas[2],\n\t\t\tbars : {\n\t\t\t\tshow : true\n\t\t\t}\n\t\t}];\n\t\tvar options = {\n\t\t\tseries : {\n\t\t\t\tshadowSize : 0\n\t\t\t},\n\t\t\tgrid : {\n\t\t\t\thoverable : true,\n\t\t\t\tclickable : true,\n\t\t\t\ttickColor : \"#f9f9f9\",\n\t\t\t\tborderWidth : 1,\n\t\t\t\tborderColor : \"#eeeeee\"\n\t\t\t},\n\t\t\tcolors : [\"#6e8cd7\", \"#34d3eb\", \"#5fbeaa\"],\n\t\t\ttooltip : true,\n\t\t\ttooltipOpts : {\n\t\t\t\tdefaultTheme : false\n\t\t\t},\n\t\t\tlegend : {\n\t\t\t\tposition : \"ne\",\n\t\t\t\tmargin : [0, -24],\n\t\t\t\tnoColumns : 0,\n\t\t\t\tlabelBoxBorderColor : null,\n\t\t\t\tlabelFormatter : function(label, series) {\n\t\t\t\t\t// just add some space to labes\n\t\t\t\t\treturn '' + label + '&nbsp;&nbsp;';\n\t\t\t\t},\n\t\t\t\twidth : 30,\n\t\t\t\theight : 2\n\t\t\t},\n\t\t\tyaxis : {\n\t\t\t\ttickColor : '#f5f5f5',\n\t\t\t\tfont : {\n\t\t\t\t\tcolor : '#bdbdbd'\n\t\t\t\t}\n\t\t\t},\n\t\t\txaxis : {\n\t\t\t\tticks: ticks,\n\t\t\t\ttickColor : '#f5f5f5',\n\t\t\t\tfont : {\n\t\t\t\t\tcolor : '#bdbdbd'\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t$.plot($(selector), data, options);\n\t},\n\n\t//initializing various charts and components\n\tFlotChart.prototype.init = function() {\n\t\t//plot graph data\n\t\tvar uploads = [[0, 9], [1, 8], [2, 5], [3, 8], [4, 5], [5, 14], [6, 10]];\n\t\tvar downloads = [[0, 5], [1, 12], [2, 4], [3, 3], [4, 12], [5, 11], [6, 14]];\n\t\tvar plabels = [\"Visits\", \"Pages/Visit\"];\n\t\tvar pcolors = ['#5fbeaa', '#34d3eb'];\n\t\tvar borderColor = '#f5f5f5';\n\t\tvar bgColor = '#fff';\n\t\tthis.createPlotGraph(\"#website-stats\", uploads, downloads, plabels, pcolors, borderColor, bgColor);\n\n\t\t//Pie graph data\n\t\tvar pielabels = [\"Series 1\", \"Series 2\", \"Series 3\"];\n\t\tvar datas = [20, 30, 15];\n\t\tvar colors = [\"#5fbeaa\", \"#6c85bd\", \"#34d3eb\"];\n\t\tthis.createPieGraph(\"#pie-chart #pie-chart-container\", pielabels, datas, colors);\n\n\t\t//real time data representation\n\t\tvar plot = this.createRealTimeGraph('#flotRealTime', this.randomData(), ['#5fbeaa']);\n\t\tplot.draw();\n\t\tvar $this = this;\n\t\tfunction updatePlot() {\n\t\t\tplot.setData([$this.randomData()]);\n\t\t\t// Since the axes don't change, we don't need to call plot.setupGrid()\n\t\t\tplot.draw();\n\t\t\tsetTimeout(updatePlot, $('html').hasClass('mobile-device') ? 1000 : 1000);\n\t\t}\n\n\t\tupdatePlot();\n\n\t\t//Donut pie graph data\n\t\tvar donutlabels = [\"Series 1\", \"Series 2\", \"Series 3\", \"Series 4\"];\n\t\tvar donutdatas = [35, 20, 10, 20];\n\t\tvar donutcolors = [\"#5fbeaa\", \"#ebeff2\", \"#34d3eb\", \"#6e8cd7\"];\n\t\tthis.createDonutGraph(\"#donut-chart #donut-chart-container\", donutlabels, donutdatas, donutcolors);\n\n\t\t//Combine graph data\n\t\tvar data24Hours = [[0, 201], [1, 520], [2, 337], [3, 261], [4, 157], [5, 95], [6, 200], [7, 250], [8, 320], [9, 500], [10, 152], [11, 214], [12, 364], [13, 449], [14, 558], [15, 282], [16, 379], [17, 429], [18, 518], [19, 470], [20, 330], [21, 245], [22, 358], [23, 74]];\n\t\tvar data48Hours = [[0, 311], [1, 630], [2, 447], [3, 371], [4, 267], [5, 205], [6, 310], [7, 360], [8, 430], [9, 610], [10, 262], [11, 324], [12, 474], [13, 559], [14, 668], [15, 392], [16, 489], [17, 539], [18, 628], [19, 580], [20, 440], [21, 355], [22, 468], [23, 184]];\n\t\tvar dataDifference = [[23, 727], [22, 128], [21, 110], [20, 92], [19, 172], [18, 63], [17, 150], [16, 592], [15, 12], [14, 246], [13, 52], [12, 149], [11, 123], [10, 2], [9, 325], [8, 10], [7, 15], [6, 89], [5, 65], [4, 77], [3, 600], [2, 200], [1, 385], [0, 200]];\n\t\tvar ticks = [[0, \"22h\"], [1, \"\"], [2, \"00h\"], [3, \"\"], [4, \"02h\"], [5, \"\"], [6, \"04h\"], [7, \"\"], [8, \"06h\"], [9, \"\"], [10, \"08h\"], [11, \"\"], [12, \"10h\"], [13, \"\"], [14, \"12h\"], [15, \"\"], [16, \"14h\"], [17, \"\"], [18, \"16h\"], [19, \"\"], [20, \"18h\"], [21, \"\"], [22, \"20h\"], [23, \"\"]];\n\t\tvar combinelabels = [\"Last 24 Hours\", \"Last 48 Hours\", \"Difference\"];\n\t\tvar combinedatas = [data24Hours, data48Hours, dataDifference];\n\n\t\tthis.createCombineGraph(\"#combine-chart #combine-chart-container\", ticks, combinelabels, combinedatas);\n\t},\n\n\t//init flotchart\n\t$.FlotChart = new FlotChart, $.FlotChart.Constructor =\n\tFlotChart\n\n}(window.jQuery),\n\n//initializing flotchart\nfunction($) {\n\t\"use strict\";\n\t$.FlotChart.init()\n}(window.jQuery);\n\n$(document).ready(function() {\n\n\t\n\n\t//------------- Ordered bars chart -------------//\n\t$(function() {\n\t\t//some data\n\t\tvar d1 = [];\n\t\tfor (var i = 0; i <= 10; i += 1)\n\t\t\td1.push([i, parseInt(Math.random() * 30)]);\n\n\t\tvar d2 = [];\n\t\tfor (var i = 0; i <= 10; i += 1)\n\t\t\td2.push([i, parseInt(Math.random() * 30)]);\n\n\t\tvar d3 = [];\n\t\tfor (var i = 0; i <= 10; i += 1)\n\t\t\td3.push([i, parseInt(Math.random() * 30)]);\n\n\t\tvar ds = new Array();\n\n\t\tds.push({\n\t\t\tlabel : \"Data One\",\n\t\t\tdata : d1,\n\t\t\tbars : {\n\t\t\t\torder : 1\n\t\t\t}\n\t\t});\n\t\tds.push({\n\t\t\tlabel : \"Data Two\",\n\t\t\tdata : d2,\n\t\t\tbars : {\n\t\t\t\torder : 2\n\t\t\t}\n\t\t});\n\t\tds.push({\n\t\t\tlabel : \"Data Three\",\n\t\t\tdata : d3,\n\t\t\tbars : {\n\t\t\t\torder : 3\n\t\t\t}\n\t\t});\n\n\t\tvar stack = 0,\n\t\t    bars = false,\n\t\t    lines = false,\n\t\t    steps = false;\n\n\t\tvar options = {\n\t\t\tbars : {\n\t\t\t\tshow : true,\n\t\t\t\tbarWidth : 0.2,\n\t\t\t\tfill : 1\n\t\t\t},\n\t\t\tgrid : {\n\t\t\t\tshow : true,\n\t\t\t\taboveData : false,\n\t\t\t\tlabelMargin : 5,\n\t\t\t\taxisMargin : 0,\n\t\t\t\tborderWidth : 1,\n\t\t\t\tminBorderMargin : 5,\n\t\t\t\tclickable : true,\n\t\t\t\thoverable : true,\n\t\t\t\tautoHighlight : false,\n\t\t\t\tmouseActiveRadius : 20,\n\t\t\t\tborderColor : '#f5f5f5'\n\t\t\t},\n\t\t\tseries : {\n\t\t\t\tstack : stack\n\t\t\t},\n\t\t\tlegend : {\n\t\t\t\tposition : \"ne\",\n\t\t\t\tmargin : [0, -24],\n\t\t\t\tnoColumns : 0,\n\t\t\t\tlabelBoxBorderColor : null,\n\t\t\t\tlabelFormatter : function(label, series) {\n\t\t\t\t\t// just add some space to labes\n\t\t\t\t\treturn '' + label + '&nbsp;&nbsp;';\n\t\t\t\t},\n\t\t\t\twidth : 30,\n\t\t\t\theight : 2\n\t\t\t},\n\t\t\tyaxis : {\n\t\t\t\ttickColor : '#f5f5f5',\n\t\t\t\tfont : {\n\t\t\t\t\tcolor : '#bdbdbd'\n\t\t\t\t}\n\t\t\t},\n\t\t\txaxis : {\n\t\t\t\ttickColor : '#f5f5f5',\n\t\t\t\tfont : {\n\t\t\t\t\tcolor : '#bdbdbd'\n\t\t\t\t}\n\t\t\t},\n\t\t\tcolors : [\"#6e8cd7\", \"#34d3eb\", \"#5fbeaa\"],\n\t\t\ttooltip : true, //activate tooltip\n\t\t\ttooltipOpts : {\n\t\t\t\tcontent : \"%s : %y.0\",\n\t\t\t\tshifts : {\n\t\t\t\t\tx : -30,\n\t\t\t\t\ty : -50\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t$.plot($(\"#ordered-bars-chart\"), ds, options);\n\t});\n});\n\n"
  },
  {
    "path": "static/assets/pages/jquery.footable.js",
    "content": "/**\n* Theme: Ubold Dashboard\n* Author: Coderthemes\n* Foo table\n*/\n\n$(window).on('load', function() {\n\n\t// Row Toggler\n\t// -----------------------------------------------------------------\n\t$('#demo-foo-row-toggler').footable();\n\n\t// Accordion\n\t// -----------------------------------------------------------------\n\t$('#demo-foo-accordion').footable().on('footable_row_expanded', function(e) {\n\t\t$('#demo-foo-accordion tbody tr.footable-detail-show').not(e.row).each(function() {\n\t\t\t$('#demo-foo-accordion').data('footable').toggleDetail(this);\n\t\t});\n\t});\n\n\t// Pagination\n\t// -----------------------------------------------------------------\n\t$('#demo-foo-pagination').footable();\n\t$('#demo-show-entries').change(function (e) {\n\t\te.preventDefault();\n\t\tvar pageSize = $(this).val();\n\t\t$('#demo-foo-pagination').data('page-size', pageSize);\n\t\t$('#demo-foo-pagination').trigger('footable_initialized');\n\t});\n\n\t// Filtering\n\t// -----------------------------------------------------------------\n\tvar filtering = $('#demo-foo-filtering');\n\tfiltering.footable().on('footable_filtering', function (e) {\n\t\tvar selected = $('#demo-foo-filter-status').find(':selected').val();\n\t\te.filter += (e.filter && e.filter.length > 0) ? ' ' + selected : selected;\n\t\te.clear = !e.filter;\n\t});\n\n\t// Filter status\n\t$('#demo-foo-filter-status').change(function (e) {\n\t\te.preventDefault();\n\t\tfiltering.trigger('footable_filter', {filter: $(this).val()});\n\t});\n\n\t// Search input\n\t$('#demo-foo-search').on('input', function (e) {\n\t\te.preventDefault();\n\t\tfiltering.trigger('footable_filter', {filter: $(this).val()});\n\t});\n\n\n\t// Add & Remove Row\n\t// -----------------------------------------------------------------\n\tvar addrow = $('#demo-foo-addrow');\n\taddrow.footable().on('click', '.demo-delete-row', function() {\n\n\t\t//get the footable object\n\t\tvar footable = addrow.data('footable');\n\n\t\t//get the row we are wanting to delete\n\t\tvar row = $(this).parents('tr:first');\n\n\t\t//delete the row\n\t\tfootable.removeRow(row);\n\t});\n\n\t// Search input\n\t$('#demo-input-search2').on('input', function (e) {\n\t\te.preventDefault();\n\t\taddrow.trigger('footable_filter', {filter: $(this).val()});\n\t});\n\n\t// Add Row Button\n\t$('#demo-btn-addrow').click(function() {\n\n\t\t//get the footable object\n\t\tvar footable = addrow.data('footable');\n\n\t\t//build up the row we are wanting to add\n\t\tvar newRow = '<tr><td style=\"text-align: center;\"><button class=\"demo-delete-row btn btn-danger btn-xs btn-icon fa fa-times\"></button></td><td>Adam</td><td>Doe</td><td>Traffic Court Referee</td><td>22 Jun 1972</td><td><span class=\"label label-table label-success\">Active</span></td></tr>';\n\n\t\t//add it\n\t\tfootable.appendRow(newRow);\n\t});\n});\n"
  },
  {
    "path": "static/assets/pages/jquery.sweet-alert.init.js",
    "content": "\n/**\n* Theme: Ubold Admin Template\n* Author: Coderthemes\n* SweetAlert\n*/\n\n!function($) {\n    \"use strict\";\n\n    var SweetAlert = function() {};\n\n    //examples \n    SweetAlert.prototype.init = function() {\n        \n    //Basic\n    $('#sa-basic').click(function(){\n        swal(\"Here's a message!\");\n    });\n\n    //A title with a text under\n    $('#sa-title').click(function(){\n        swal(\"Here's a message!\", \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed lorem erat, tincidunt vitae ipsum et, pellentesque maximus enim. Mauris eleifend ex semper, lobortis purus sed, pharetra felis\")\n    });\n\n    //Success Message\n    $('#sa-success').click(function(){\n        swal(\"Good job!\", \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed lorem erat, tincidunt vitae ipsum et, pellentesque maximus enim. Mauris eleifend ex semper, lobortis purus sed, pharetra felis\", \"success\")\n    });\n\n    //Warning Message\n    $('#sa-warning').click(function(){\n        swal({   \n            title: \"Are you sure?\",   \n            text: \"You will not be able to recover this imaginary file!\",   \n            type: \"warning\",   \n            showCancelButton: true,   \n            confirmButtonColor: \"#DD6B55\",   \n            confirmButtonText: \"Yes, delete it!\",   \n            closeOnConfirm: false \n        }, function(){   \n            swal(\"Deleted!\", \"Your imaginary file has been deleted.\", \"success\"); \n        });\n    });\n\n    //Parameter\n    $('#sa-params').click(function(){\n        swal({   \n            title: \"Are you sure?\",   \n            text: \"You will not be able to recover this imaginary file!\",   \n            type: \"warning\",   \n            showCancelButton: true,   \n            confirmButtonColor: \"#DD6B55\",   \n            confirmButtonText: \"Yes, delete it!\",   \n            cancelButtonText: \"No, cancel plx!\",   \n            closeOnConfirm: false,   \n            closeOnCancel: false \n        }, function(isConfirm){   \n            if (isConfirm) {     \n                swal(\"Deleted!\", \"Your imaginary file has been deleted.\", \"success\");   \n            } else {     \n                swal(\"Cancelled\", \"Your imaginary file is safe :)\", \"error\");   \n            } \n        });\n    });\n\n    //Custom Image\n    $('#sa-image').click(function(){\n        swal({   \n            title: \"Sweet!\",   \n            text: \"Here's a custom image.\",   \n            imageUrl: \"/static/assets/plugins/sweetalert/thumbs-up.jpg\"\n        });\n    });\n\n    //Auto Close Timer\n    $('#sa-close').click(function(){\n         swal({   \n            title: \"Info\",\n            text: \"User registration success!!\",\n            timer: 2000,   \n            showConfirmButton: false \n        });\n    });\n\n\n    },\n    //init\n    $.SweetAlert = new SweetAlert, $.SweetAlert.Constructor = SweetAlert\n}(window.jQuery),\n\n//initializing \nfunction($) {\n    \"use strict\";\n    $.SweetAlert.init()\n}(window.jQuery);"
  },
  {
    "path": "static/assets/plugins/Chart.js/Chart.js",
    "content": "/*!\n * Chart.js\n * http://chartjs.org/\n * Version: 1.0.2\n *\n * Copyright 2015 Nick Downie\n * Released under the MIT license\n * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md\n */\n\n\n(function(){\n\n\t\"use strict\";\n\n\t//Declare root variable - window in the browser, global on the server\n\tvar root = this,\n\t\tprevious = root.Chart;\n\n\t//Occupy the global variable of Chart, and create a simple base class\n\tvar Chart = function(context){\n\t\tvar chart = this;\n\t\tthis.canvas = context.canvas;\n\n\t\tthis.ctx = context;\n\n\t\t//Variables global to the chart\n\t\tvar computeDimension = function(element,dimension)\n\t\t{\n\t\t\tif (element['offset'+dimension])\n\t\t\t{\n\t\t\t\treturn element['offset'+dimension];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn document.defaultView.getComputedStyle(element).getPropertyValue(dimension);\n\t\t\t}\n\t\t}\n\n\t\tvar width = this.width = computeDimension(context.canvas,'Width');\n\t\tvar height = this.height = computeDimension(context.canvas,'Height');\n\n\t\t// Firefox requires this to work correctly\n\t\tcontext.canvas.width  = width;\n\t\tcontext.canvas.height = height;\n\n\t\tvar width = this.width = context.canvas.width;\n\t\tvar height = this.height = context.canvas.height;\n\t\tthis.aspectRatio = this.width / this.height;\n\t\t//High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.\n\t\thelpers.retinaScale(this);\n\n\t\treturn this;\n\t};\n\t//Globally expose the defaults to allow for user updating/changing\n\tChart.defaults = {\n\t\tglobal: {\n\t\t\t// Boolean - Whether to animate the chart\n\t\t\tanimation: true,\n\n\t\t\t// Number - Number of animation steps\n\t\t\tanimationSteps: 60,\n\n\t\t\t// String - Animation easing effect\n\t\t\tanimationEasing: \"easeOutQuart\",\n\n\t\t\t// Boolean - If we should show the scale at all\n\t\t\tshowScale: true,\n\n\t\t\t// Boolean - If we want to override with a hard coded scale\n\t\t\tscaleOverride: false,\n\n\t\t\t// ** Required if scaleOverride is true **\n\t\t\t// Number - The number of steps in a hard coded scale\n\t\t\tscaleSteps: null,\n\t\t\t// Number - The value jump in the hard coded scale\n\t\t\tscaleStepWidth: null,\n\t\t\t// Number - The scale starting value\n\t\t\tscaleStartValue: null,\n\n\t\t\t// String - Colour of the scale line\n\t\t\tscaleLineColor: \"rgba(0,0,0,.1)\",\n\n\t\t\t// Number - Pixel width of the scale line\n\t\t\tscaleLineWidth: 1,\n\n\t\t\t// Boolean - Whether to show labels on the scale\n\t\t\tscaleShowLabels: true,\n\n\t\t\t// Interpolated JS string - can access value\n\t\t\tscaleLabel: \"<%=value%>\",\n\n\t\t\t// Boolean - Whether the scale should stick to integers, and not show any floats even if drawing space is there\n\t\t\tscaleIntegersOnly: true,\n\n\t\t\t// Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value\n\t\t\tscaleBeginAtZero: false,\n\n\t\t\t// String - Scale label font declaration for the scale label\n\t\t\tscaleFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\n\t\t\t// Number - Scale label font size in pixels\n\t\t\tscaleFontSize: 12,\n\n\t\t\t// String - Scale label font weight style\n\t\t\tscaleFontStyle: \"normal\",\n\n\t\t\t// String - Scale label font colour\n\t\t\tscaleFontColor: \"#666\",\n\n\t\t\t// Boolean - whether or not the chart should be responsive and resize when the browser does.\n\t\t\tresponsive: false,\n\n\t\t\t// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container\n\t\t\tmaintainAspectRatio: true,\n\n\t\t\t// Boolean - Determines whether to draw tooltips on the canvas or not - attaches events to touchmove & mousemove\n\t\t\tshowTooltips: true,\n\n\t\t\t// Boolean - Determines whether to draw built-in tooltip or call custom tooltip function\n\t\t\tcustomTooltips: false,\n\n\t\t\t// Array - Array of string names to attach tooltip events\n\t\t\ttooltipEvents: [\"mousemove\", \"touchstart\", \"touchmove\", \"mouseout\"],\n\n\t\t\t// String - Tooltip background colour\n\t\t\ttooltipFillColor: \"rgba(0,0,0,0.8)\",\n\n\t\t\t// String - Tooltip label font declaration for the scale label\n\t\t\ttooltipFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\n\t\t\t// Number - Tooltip label font size in pixels\n\t\t\ttooltipFontSize: 14,\n\n\t\t\t// String - Tooltip font weight style\n\t\t\ttooltipFontStyle: \"normal\",\n\n\t\t\t// String - Tooltip label font colour\n\t\t\ttooltipFontColor: \"#fff\",\n\n\t\t\t// String - Tooltip title font declaration for the scale label\n\t\t\ttooltipTitleFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\n\t\t\t// Number - Tooltip title font size in pixels\n\t\t\ttooltipTitleFontSize: 14,\n\n\t\t\t// String - Tooltip title font weight style\n\t\t\ttooltipTitleFontStyle: \"bold\",\n\n\t\t\t// String - Tooltip title font colour\n\t\t\ttooltipTitleFontColor: \"#fff\",\n\n\t\t\t// Number - pixel width of padding around tooltip text\n\t\t\ttooltipYPadding: 6,\n\n\t\t\t// Number - pixel width of padding around tooltip text\n\t\t\ttooltipXPadding: 6,\n\n\t\t\t// Number - Size of the caret on the tooltip\n\t\t\ttooltipCaretSize: 8,\n\n\t\t\t// Number - Pixel radius of the tooltip border\n\t\t\ttooltipCornerRadius: 6,\n\n\t\t\t// Number - Pixel offset from point x to tooltip edge\n\t\t\ttooltipXOffset: 10,\n\n\t\t\t// String - Template string for single tooltips\n\t\t\ttooltipTemplate: \"<%if (label){%><%=label%>: <%}%><%= value %>\",\n\n\t\t\t// String - Template string for single tooltips\n\t\t\tmultiTooltipTemplate: \"<%= value %>\",\n\n\t\t\t// String - Colour behind the legend colour block\n\t\t\tmultiTooltipKeyBackground: '#fff',\n\n\t\t\t// Function - Will fire on animation progression.\n\t\t\tonAnimationProgress: function(){},\n\n\t\t\t// Function - Will fire on animation completion.\n\t\t\tonAnimationComplete: function(){}\n\n\t\t}\n\t};\n\n\t//Create a dictionary of chart types, to allow for extension of existing types\n\tChart.types = {};\n\n\t//Global Chart helpers object for utility methods and classes\n\tvar helpers = Chart.helpers = {};\n\n\t\t//-- Basic js utility methods\n\tvar each = helpers.each = function(loopable,callback,self){\n\t\t\tvar additionalArgs = Array.prototype.slice.call(arguments, 3);\n\t\t\t// Check to see if null or undefined firstly.\n\t\t\tif (loopable){\n\t\t\t\tif (loopable.length === +loopable.length){\n\t\t\t\t\tvar i;\n\t\t\t\t\tfor (i=0; i<loopable.length; i++){\n\t\t\t\t\t\tcallback.apply(self,[loopable[i], i].concat(additionalArgs));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\tfor (var item in loopable){\n\t\t\t\t\t\tcallback.apply(self,[loopable[item],item].concat(additionalArgs));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tclone = helpers.clone = function(obj){\n\t\t\tvar objClone = {};\n\t\t\teach(obj,function(value,key){\n\t\t\t\tif (obj.hasOwnProperty(key)) objClone[key] = value;\n\t\t\t});\n\t\t\treturn objClone;\n\t\t},\n\t\textend = helpers.extend = function(base){\n\t\t\teach(Array.prototype.slice.call(arguments,1), function(extensionObject) {\n\t\t\t\teach(extensionObject,function(value,key){\n\t\t\t\t\tif (extensionObject.hasOwnProperty(key)) base[key] = value;\n\t\t\t\t});\n\t\t\t});\n\t\t\treturn base;\n\t\t},\n\t\tmerge = helpers.merge = function(base,master){\n\t\t\t//Merge properties in left object over to a shallow clone of object right.\n\t\t\tvar args = Array.prototype.slice.call(arguments,0);\n\t\t\targs.unshift({});\n\t\t\treturn extend.apply(null, args);\n\t\t},\n\t\tindexOf = helpers.indexOf = function(arrayToSearch, item){\n\t\t\tif (Array.prototype.indexOf) {\n\t\t\t\treturn arrayToSearch.indexOf(item);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tfor (var i = 0; i < arrayToSearch.length; i++) {\n\t\t\t\t\tif (arrayToSearch[i] === item) return i;\n\t\t\t\t}\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t},\n\t\twhere = helpers.where = function(collection, filterCallback){\n\t\t\tvar filtered = [];\n\n\t\t\thelpers.each(collection, function(item){\n\t\t\t\tif (filterCallback(item)){\n\t\t\t\t\tfiltered.push(item);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn filtered;\n\t\t},\n\t\tfindNextWhere = helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex){\n\t\t\t// Default to start of the array\n\t\t\tif (!startIndex){\n\t\t\t\tstartIndex = -1;\n\t\t\t}\n\t\t\tfor (var i = startIndex + 1; i < arrayToSearch.length; i++) {\n\t\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\t\tif (filterCallback(currentItem)){\n\t\t\t\t\treturn currentItem;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tfindPreviousWhere = helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex){\n\t\t\t// Default to end of the array\n\t\t\tif (!startIndex){\n\t\t\t\tstartIndex = arrayToSearch.length;\n\t\t\t}\n\t\t\tfor (var i = startIndex - 1; i >= 0; i--) {\n\t\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\t\tif (filterCallback(currentItem)){\n\t\t\t\t\treturn currentItem;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tinherits = helpers.inherits = function(extensions){\n\t\t\t//Basic javascript inheritance based on the model created in Backbone.js\n\t\t\tvar parent = this;\n\t\t\tvar ChartElement = (extensions && extensions.hasOwnProperty(\"constructor\")) ? extensions.constructor : function(){ return parent.apply(this, arguments); };\n\n\t\t\tvar Surrogate = function(){ this.constructor = ChartElement;};\n\t\t\tSurrogate.prototype = parent.prototype;\n\t\t\tChartElement.prototype = new Surrogate();\n\n\t\t\tChartElement.extend = inherits;\n\n\t\t\tif (extensions) extend(ChartElement.prototype, extensions);\n\n\t\t\tChartElement.__super__ = parent.prototype;\n\n\t\t\treturn ChartElement;\n\t\t},\n\t\tnoop = helpers.noop = function(){},\n\t\tuid = helpers.uid = (function(){\n\t\t\tvar id=0;\n\t\t\treturn function(){\n\t\t\t\treturn \"chart-\" + id++;\n\t\t\t};\n\t\t})(),\n\t\twarn = helpers.warn = function(str){\n\t\t\t//Method for warning of errors\n\t\t\tif (window.console && typeof window.console.warn == \"function\") console.warn(str);\n\t\t},\n\t\tamd = helpers.amd = (typeof define == 'function' && define.amd),\n\t\t//-- Math methods\n\t\tisNumber = helpers.isNumber = function(n){\n\t\t\treturn !isNaN(parseFloat(n)) && isFinite(n);\n\t\t},\n\t\tmax = helpers.max = function(array){\n\t\t\treturn Math.max.apply( Math, array );\n\t\t},\n\t\tmin = helpers.min = function(array){\n\t\t\treturn Math.min.apply( Math, array );\n\t\t},\n\t\tcap = helpers.cap = function(valueToCap,maxValue,minValue){\n\t\t\tif(isNumber(maxValue)) {\n\t\t\t\tif( valueToCap > maxValue ) {\n\t\t\t\t\treturn maxValue;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(isNumber(minValue)){\n\t\t\t\tif ( valueToCap < minValue ){\n\t\t\t\t\treturn minValue;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn valueToCap;\n\t\t},\n\t\tgetDecimalPlaces = helpers.getDecimalPlaces = function(num){\n\t\t\tif (num%1!==0 && isNumber(num)){\n\t\t\t\treturn num.toString().split(\".\")[1].length;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t},\n\t\ttoRadians = helpers.radians = function(degrees){\n\t\t\treturn degrees * (Math.PI/180);\n\t\t},\n\t\t// Gets the angle from vertical upright to the point about a centre.\n\t\tgetAngleFromPoint = helpers.getAngleFromPoint = function(centrePoint, anglePoint){\n\t\t\tvar distanceFromXCenter = anglePoint.x - centrePoint.x,\n\t\t\t\tdistanceFromYCenter = anglePoint.y - centrePoint.y,\n\t\t\t\tradialDistanceFromCenter = Math.sqrt( distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);\n\n\n\t\t\tvar angle = Math.PI * 2 + Math.atan2(distanceFromYCenter, distanceFromXCenter);\n\n\t\t\t//If the segment is in the top left quadrant, we need to add another rotation to the angle\n\t\t\tif (distanceFromXCenter < 0 && distanceFromYCenter < 0){\n\t\t\t\tangle += Math.PI*2;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tangle: angle,\n\t\t\t\tdistance: radialDistanceFromCenter\n\t\t\t};\n\t\t},\n\t\taliasPixel = helpers.aliasPixel = function(pixelWidth){\n\t\t\treturn (pixelWidth % 2 === 0) ? 0 : 0.5;\n\t\t},\n\t\tsplineCurve = helpers.splineCurve = function(FirstPoint,MiddlePoint,AfterPoint,t){\n\t\t\t//Props to Rob Spencer at scaled innovation for his post on splining between points\n\t\t\t//http://scaledinnovation.com/analytics/splines/aboutSplines.html\n\t\t\tvar d01=Math.sqrt(Math.pow(MiddlePoint.x-FirstPoint.x,2)+Math.pow(MiddlePoint.y-FirstPoint.y,2)),\n\t\t\t\td12=Math.sqrt(Math.pow(AfterPoint.x-MiddlePoint.x,2)+Math.pow(AfterPoint.y-MiddlePoint.y,2)),\n\t\t\t\tfa=t*d01/(d01+d12),// scaling factor for triangle Ta\n\t\t\t\tfb=t*d12/(d01+d12);\n\t\t\treturn {\n\t\t\t\tinner : {\n\t\t\t\t\tx : MiddlePoint.x-fa*(AfterPoint.x-FirstPoint.x),\n\t\t\t\t\ty : MiddlePoint.y-fa*(AfterPoint.y-FirstPoint.y)\n\t\t\t\t},\n\t\t\t\touter : {\n\t\t\t\t\tx: MiddlePoint.x+fb*(AfterPoint.x-FirstPoint.x),\n\t\t\t\t\ty : MiddlePoint.y+fb*(AfterPoint.y-FirstPoint.y)\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\tcalculateOrderOfMagnitude = helpers.calculateOrderOfMagnitude = function(val){\n\t\t\treturn Math.floor(Math.log(val) / Math.LN10);\n\t\t},\n\t\tcalculateScaleRange = helpers.calculateScaleRange = function(valuesArray, drawingSize, textSize, startFromZero, integersOnly){\n\n\t\t\t//Set a minimum step of two - a point at the top of the graph, and a point at the base\n\t\t\tvar minSteps = 2,\n\t\t\t\tmaxSteps = Math.floor(drawingSize/(textSize * 1.5)),\n\t\t\t\tskipFitting = (minSteps >= maxSteps);\n\n\t\t\tvar maxValue = max(valuesArray),\n\t\t\t\tminValue = min(valuesArray);\n\n\t\t\t// We need some degree of seperation here to calculate the scales if all the values are the same\n\t\t\t// Adding/minusing 0.5 will give us a range of 1.\n\t\t\tif (maxValue === minValue){\n\t\t\t\tmaxValue += 0.5;\n\t\t\t\t// So we don't end up with a graph with a negative start value if we've said always start from zero\n\t\t\t\tif (minValue >= 0.5 && !startFromZero){\n\t\t\t\t\tminValue -= 0.5;\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\t// Make up a whole number above the values\n\t\t\t\t\tmaxValue += 0.5;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar\tvalueRange = Math.abs(maxValue - minValue),\n\t\t\t\trangeOrderOfMagnitude = calculateOrderOfMagnitude(valueRange),\n\t\t\t\tgraphMax = Math.ceil(maxValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),\n\t\t\t\tgraphMin = (startFromZero) ? 0 : Math.floor(minValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),\n\t\t\t\tgraphRange = graphMax - graphMin,\n\t\t\t\tstepValue = Math.pow(10, rangeOrderOfMagnitude),\n\t\t\t\tnumberOfSteps = Math.round(graphRange / stepValue);\n\n\t\t\t//If we have more space on the graph we'll use it to give more definition to the data\n\t\t\twhile((numberOfSteps > maxSteps || (numberOfSteps * 2) < maxSteps) && !skipFitting) {\n\t\t\t\tif(numberOfSteps > maxSteps){\n\t\t\t\t\tstepValue *=2;\n\t\t\t\t\tnumberOfSteps = Math.round(graphRange/stepValue);\n\t\t\t\t\t// Don't ever deal with a decimal number of steps - cancel fitting and just use the minimum number of steps.\n\t\t\t\t\tif (numberOfSteps % 1 !== 0){\n\t\t\t\t\t\tskipFitting = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//We can fit in double the amount of scale points on the scale\n\t\t\t\telse{\n\t\t\t\t\t//If user has declared ints only, and the step value isn't a decimal\n\t\t\t\t\tif (integersOnly && rangeOrderOfMagnitude >= 0){\n\t\t\t\t\t\t//If the user has said integers only, we need to check that making the scale more granular wouldn't make it a float\n\t\t\t\t\t\tif(stepValue/2 % 1 === 0){\n\t\t\t\t\t\t\tstepValue /=2;\n\t\t\t\t\t\t\tnumberOfSteps = Math.round(graphRange/stepValue);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//If it would make it a float break out of the loop\n\t\t\t\t\t\telse{\n\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\t//If the scale doesn't have to be an int, make the scale more granular anyway.\n\t\t\t\t\telse{\n\t\t\t\t\t\tstepValue /=2;\n\t\t\t\t\t\tnumberOfSteps = Math.round(graphRange/stepValue);\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (skipFitting){\n\t\t\t\tnumberOfSteps = minSteps;\n\t\t\t\tstepValue = graphRange / numberOfSteps;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsteps : numberOfSteps,\n\t\t\t\tstepValue : stepValue,\n\t\t\t\tmin : graphMin,\n\t\t\t\tmax\t: graphMin + (numberOfSteps * stepValue)\n\t\t\t};\n\n\t\t},\n\t\t/* jshint ignore:start */\n\t\t// Blows up jshint errors based on the new Function constructor\n\t\t//Templating methods\n\t\t//Javascript micro templating by John Resig - source at http://ejohn.org/blog/javascript-micro-templating/\n\t\ttemplate = helpers.template = function(templateString, valuesObject){\n\n\t\t\t// If templateString is function rather than string-template - call the function for valuesObject\n\n\t\t\tif(templateString instanceof Function){\n\t\t\t \treturn templateString(valuesObject);\n\t\t \t}\n\n\t\t\tvar cache = {};\n\t\t\tfunction tmpl(str, data){\n\t\t\t\t// Figure out if we're getting a template, or if we need to\n\t\t\t\t// load the template - and be sure to cache the result.\n\t\t\t\tvar fn = !/\\W/.test(str) ?\n\t\t\t\tcache[str] = cache[str] :\n\n\t\t\t\t// Generate a reusable function that will serve as a template\n\t\t\t\t// generator (and which will be cached).\n\t\t\t\tnew Function(\"obj\",\n\t\t\t\t\t\"var p=[],print=function(){p.push.apply(p,arguments);};\" +\n\n\t\t\t\t\t// Introduce the data as local variables using with(){}\n\t\t\t\t\t\"with(obj){p.push('\" +\n\n\t\t\t\t\t// Convert the template into pure JavaScript\n\t\t\t\t\tstr\n\t\t\t\t\t\t.replace(/[\\r\\t\\n]/g, \" \")\n\t\t\t\t\t\t.split(\"<%\").join(\"\\t\")\n\t\t\t\t\t\t.replace(/((^|%>)[^\\t]*)'/g, \"$1\\r\")\n\t\t\t\t\t\t.replace(/\\t=(.*?)%>/g, \"',$1,'\")\n\t\t\t\t\t\t.split(\"\\t\").join(\"');\")\n\t\t\t\t\t\t.split(\"%>\").join(\"p.push('\")\n\t\t\t\t\t\t.split(\"\\r\").join(\"\\\\'\") +\n\t\t\t\t\t\"');}return p.join('');\"\n\t\t\t\t);\n\n\t\t\t\t// Provide some basic currying to the user\n\t\t\t\treturn data ? fn( data ) : fn;\n\t\t\t}\n\t\t\treturn tmpl(templateString,valuesObject);\n\t\t},\n\t\t/* jshint ignore:end */\n\t\tgenerateLabels = helpers.generateLabels = function(templateString,numberOfSteps,graphMin,stepValue){\n\t\t\tvar labelsArray = new Array(numberOfSteps);\n\t\t\tif (labelTemplateString){\n\t\t\t\teach(labelsArray,function(val,index){\n\t\t\t\t\tlabelsArray[index] = template(templateString,{value: (graphMin + (stepValue*(index+1)))});\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn labelsArray;\n\t\t},\n\t\t//--Animation methods\n\t\t//Easing functions adapted from Robert Penner's easing equations\n\t\t//http://www.robertpenner.com/easing/\n\t\teasingEffects = helpers.easingEffects = {\n\t\t\tlinear: function (t) {\n\t\t\t\treturn t;\n\t\t\t},\n\t\t\teaseInQuad: function (t) {\n\t\t\t\treturn t * t;\n\t\t\t},\n\t\t\teaseOutQuad: function (t) {\n\t\t\t\treturn -1 * t * (t - 2);\n\t\t\t},\n\t\t\teaseInOutQuad: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * t * t;\n\t\t\t\treturn -1 / 2 * ((--t) * (t - 2) - 1);\n\t\t\t},\n\t\t\teaseInCubic: function (t) {\n\t\t\t\treturn t * t * t;\n\t\t\t},\n\t\t\teaseOutCubic: function (t) {\n\t\t\t\treturn 1 * ((t = t / 1 - 1) * t * t + 1);\n\t\t\t},\n\t\t\teaseInOutCubic: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t;\n\t\t\t\treturn 1 / 2 * ((t -= 2) * t * t + 2);\n\t\t\t},\n\t\t\teaseInQuart: function (t) {\n\t\t\t\treturn t * t * t * t;\n\t\t\t},\n\t\t\teaseOutQuart: function (t) {\n\t\t\t\treturn -1 * ((t = t / 1 - 1) * t * t * t - 1);\n\t\t\t},\n\t\t\teaseInOutQuart: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t;\n\t\t\t\treturn -1 / 2 * ((t -= 2) * t * t * t - 2);\n\t\t\t},\n\t\t\teaseInQuint: function (t) {\n\t\t\t\treturn 1 * (t /= 1) * t * t * t * t;\n\t\t\t},\n\t\t\teaseOutQuint: function (t) {\n\t\t\t\treturn 1 * ((t = t / 1 - 1) * t * t * t * t + 1);\n\t\t\t},\n\t\t\teaseInOutQuint: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t * t;\n\t\t\t\treturn 1 / 2 * ((t -= 2) * t * t * t * t + 2);\n\t\t\t},\n\t\t\teaseInSine: function (t) {\n\t\t\t\treturn -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;\n\t\t\t},\n\t\t\teaseOutSine: function (t) {\n\t\t\t\treturn 1 * Math.sin(t / 1 * (Math.PI / 2));\n\t\t\t},\n\t\t\teaseInOutSine: function (t) {\n\t\t\t\treturn -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);\n\t\t\t},\n\t\t\teaseInExpo: function (t) {\n\t\t\t\treturn (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));\n\t\t\t},\n\t\t\teaseOutExpo: function (t) {\n\t\t\t\treturn (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);\n\t\t\t},\n\t\t\teaseInOutExpo: function (t) {\n\t\t\t\tif (t === 0) return 0;\n\t\t\t\tif (t === 1) return 1;\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * Math.pow(2, 10 * (t - 1));\n\t\t\t\treturn 1 / 2 * (-Math.pow(2, -10 * --t) + 2);\n\t\t\t},\n\t\t\teaseInCirc: function (t) {\n\t\t\t\tif (t >= 1) return t;\n\t\t\t\treturn -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);\n\t\t\t},\n\t\t\teaseOutCirc: function (t) {\n\t\t\t\treturn 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);\n\t\t\t},\n\t\t\teaseInOutCirc: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return -1 / 2 * (Math.sqrt(1 - t * t) - 1);\n\t\t\t\treturn 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);\n\t\t\t},\n\t\t\teaseInElastic: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tvar p = 0;\n\t\t\t\tvar a = 1;\n\t\t\t\tif (t === 0) return 0;\n\t\t\t\tif ((t /= 1) == 1) return 1;\n\t\t\t\tif (!p) p = 1 * 0.3;\n\t\t\t\tif (a < Math.abs(1)) {\n\t\t\t\t\ta = 1;\n\t\t\t\t\ts = p / 4;\n\t\t\t\t} else s = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t\treturn -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\n\t\t\t},\n\t\t\teaseOutElastic: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tvar p = 0;\n\t\t\t\tvar a = 1;\n\t\t\t\tif (t === 0) return 0;\n\t\t\t\tif ((t /= 1) == 1) return 1;\n\t\t\t\tif (!p) p = 1 * 0.3;\n\t\t\t\tif (a < Math.abs(1)) {\n\t\t\t\t\ta = 1;\n\t\t\t\t\ts = p / 4;\n\t\t\t\t} else s = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t\treturn a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;\n\t\t\t},\n\t\t\teaseInOutElastic: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tvar p = 0;\n\t\t\t\tvar a = 1;\n\t\t\t\tif (t === 0) return 0;\n\t\t\t\tif ((t /= 1 / 2) == 2) return 1;\n\t\t\t\tif (!p) p = 1 * (0.3 * 1.5);\n\t\t\t\tif (a < Math.abs(1)) {\n\t\t\t\t\ta = 1;\n\t\t\t\t\ts = p / 4;\n\t\t\t\t} else s = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t\tif (t < 1) return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\n\t\t\t\treturn a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;\n\t\t\t},\n\t\t\teaseInBack: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\treturn 1 * (t /= 1) * t * ((s + 1) * t - s);\n\t\t\t},\n\t\t\teaseOutBack: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\treturn 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);\n\t\t\t},\n\t\t\teaseInOutBack: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));\n\t\t\t\treturn 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);\n\t\t\t},\n\t\t\teaseInBounce: function (t) {\n\t\t\t\treturn 1 - easingEffects.easeOutBounce(1 - t);\n\t\t\t},\n\t\t\teaseOutBounce: function (t) {\n\t\t\t\tif ((t /= 1) < (1 / 2.75)) {\n\t\t\t\t\treturn 1 * (7.5625 * t * t);\n\t\t\t\t} else if (t < (2 / 2.75)) {\n\t\t\t\t\treturn 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);\n\t\t\t\t} else if (t < (2.5 / 2.75)) {\n\t\t\t\t\treturn 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);\n\t\t\t\t} else {\n\t\t\t\t\treturn 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);\n\t\t\t\t}\n\t\t\t},\n\t\t\teaseInOutBounce: function (t) {\n\t\t\t\tif (t < 1 / 2) return easingEffects.easeInBounce(t * 2) * 0.5;\n\t\t\t\treturn easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;\n\t\t\t}\n\t\t},\n\t\t//Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/\n\t\trequestAnimFrame = helpers.requestAnimFrame = (function(){\n\t\t\treturn window.requestAnimationFrame ||\n\t\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\t\twindow.oRequestAnimationFrame ||\n\t\t\t\twindow.msRequestAnimationFrame ||\n\t\t\t\tfunction(callback) {\n\t\t\t\t\treturn window.setTimeout(callback, 1000 / 60);\n\t\t\t\t};\n\t\t})(),\n\t\tcancelAnimFrame = helpers.cancelAnimFrame = (function(){\n\t\t\treturn window.cancelAnimationFrame ||\n\t\t\t\twindow.webkitCancelAnimationFrame ||\n\t\t\t\twindow.mozCancelAnimationFrame ||\n\t\t\t\twindow.oCancelAnimationFrame ||\n\t\t\t\twindow.msCancelAnimationFrame ||\n\t\t\t\tfunction(callback) {\n\t\t\t\t\treturn window.clearTimeout(callback, 1000 / 60);\n\t\t\t\t};\n\t\t})(),\n\t\tanimationLoop = helpers.animationLoop = function(callback,totalSteps,easingString,onProgress,onComplete,chartInstance){\n\n\t\t\tvar currentStep = 0,\n\t\t\t\teasingFunction = easingEffects[easingString] || easingEffects.linear;\n\n\t\t\tvar animationFrame = function(){\n\t\t\t\tcurrentStep++;\n\t\t\t\tvar stepDecimal = currentStep/totalSteps;\n\t\t\t\tvar easeDecimal = easingFunction(stepDecimal);\n\n\t\t\t\tcallback.call(chartInstance,easeDecimal,stepDecimal, currentStep);\n\t\t\t\tonProgress.call(chartInstance,easeDecimal,stepDecimal);\n\t\t\t\tif (currentStep < totalSteps){\n\t\t\t\t\tchartInstance.animationFrame = requestAnimFrame(animationFrame);\n\t\t\t\t} else{\n\t\t\t\t\tonComplete.apply(chartInstance);\n\t\t\t\t}\n\t\t\t};\n\t\t\trequestAnimFrame(animationFrame);\n\t\t},\n\t\t//-- DOM methods\n\t\tgetRelativePosition = helpers.getRelativePosition = function(evt){\n\t\t\tvar mouseX, mouseY;\n\t\t\tvar e = evt.originalEvent || evt,\n\t\t\t\tcanvas = evt.currentTarget || evt.srcElement,\n\t\t\t\tboundingRect = canvas.getBoundingClientRect();\n\n\t\t\tif (e.touches){\n\t\t\t\tmouseX = e.touches[0].clientX - boundingRect.left;\n\t\t\t\tmouseY = e.touches[0].clientY - boundingRect.top;\n\n\t\t\t}\n\t\t\telse{\n\t\t\t\tmouseX = e.clientX - boundingRect.left;\n\t\t\t\tmouseY = e.clientY - boundingRect.top;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tx : mouseX,\n\t\t\t\ty : mouseY\n\t\t\t};\n\n\t\t},\n\t\taddEvent = helpers.addEvent = function(node,eventType,method){\n\t\t\tif (node.addEventListener){\n\t\t\t\tnode.addEventListener(eventType,method);\n\t\t\t} else if (node.attachEvent){\n\t\t\t\tnode.attachEvent(\"on\"+eventType, method);\n\t\t\t} else {\n\t\t\t\tnode[\"on\"+eventType] = method;\n\t\t\t}\n\t\t},\n\t\tremoveEvent = helpers.removeEvent = function(node, eventType, handler){\n\t\t\tif (node.removeEventListener){\n\t\t\t\tnode.removeEventListener(eventType, handler, false);\n\t\t\t} else if (node.detachEvent){\n\t\t\t\tnode.detachEvent(\"on\"+eventType,handler);\n\t\t\t} else{\n\t\t\t\tnode[\"on\" + eventType] = noop;\n\t\t\t}\n\t\t},\n\t\tbindEvents = helpers.bindEvents = function(chartInstance, arrayOfEvents, handler){\n\t\t\t// Create the events object if it's not already present\n\t\t\tif (!chartInstance.events) chartInstance.events = {};\n\n\t\t\teach(arrayOfEvents,function(eventName){\n\t\t\t\tchartInstance.events[eventName] = function(){\n\t\t\t\t\thandler.apply(chartInstance, arguments);\n\t\t\t\t};\n\t\t\t\taddEvent(chartInstance.chart.canvas,eventName,chartInstance.events[eventName]);\n\t\t\t});\n\t\t},\n\t\tunbindEvents = helpers.unbindEvents = function (chartInstance, arrayOfEvents) {\n\t\t\teach(arrayOfEvents, function(handler,eventName){\n\t\t\t\tremoveEvent(chartInstance.chart.canvas, eventName, handler);\n\t\t\t});\n\t\t},\n\t\tgetMaximumWidth = helpers.getMaximumWidth = function(domNode){\n\t\t\tvar container = domNode.parentNode;\n\t\t\t// TODO = check cross browser stuff with this.\n\t\t\treturn container.clientWidth;\n\t\t},\n\t\tgetMaximumHeight = helpers.getMaximumHeight = function(domNode){\n\t\t\tvar container = domNode.parentNode;\n\t\t\t// TODO = check cross browser stuff with this.\n\t\t\treturn container.clientHeight;\n\t\t},\n\t\tgetMaximumSize = helpers.getMaximumSize = helpers.getMaximumWidth, // legacy support\n\t\tretinaScale = helpers.retinaScale = function(chart){\n\t\t\tvar ctx = chart.ctx,\n\t\t\t\twidth = chart.canvas.width,\n\t\t\t\theight = chart.canvas.height;\n\n\t\t\tif (window.devicePixelRatio) {\n\t\t\t\tctx.canvas.style.width = width + \"px\";\n\t\t\t\tctx.canvas.style.height = height + \"px\";\n\t\t\t\tctx.canvas.height = height * window.devicePixelRatio;\n\t\t\t\tctx.canvas.width = width * window.devicePixelRatio;\n\t\t\t\tctx.scale(window.devicePixelRatio, window.devicePixelRatio);\n\t\t\t}\n\t\t},\n\t\t//-- Canvas methods\n\t\tclear = helpers.clear = function(chart){\n\t\t\tchart.ctx.clearRect(0,0,chart.width,chart.height);\n\t\t},\n\t\tfontString = helpers.fontString = function(pixelSize,fontStyle,fontFamily){\n\t\t\treturn fontStyle + \" \" + pixelSize+\"px \" + fontFamily;\n\t\t},\n\t\tlongestText = helpers.longestText = function(ctx,font,arrayOfStrings){\n\t\t\tctx.font = font;\n\t\t\tvar longest = 0;\n\t\t\teach(arrayOfStrings,function(string){\n\t\t\t\tvar textWidth = ctx.measureText(string).width;\n\t\t\t\tlongest = (textWidth > longest) ? textWidth : longest;\n\t\t\t});\n\t\t\treturn longest;\n\t\t},\n\t\tdrawRoundedRectangle = helpers.drawRoundedRectangle = function(ctx,x,y,width,height,radius){\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x + radius, y);\n\t\t\tctx.lineTo(x + width - radius, y);\n\t\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n\t\t\tctx.lineTo(x + width, y + height - radius);\n\t\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n\t\t\tctx.lineTo(x + radius, y + height);\n\t\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n\t\t\tctx.lineTo(x, y + radius);\n\t\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t\t\tctx.closePath();\n\t\t};\n\n\n\t//Store a reference to each instance - allowing us to globally resize chart instances on window resize.\n\t//Destroy method on the chart will remove the instance of the chart from this reference.\n\tChart.instances = {};\n\n\tChart.Type = function(data,options,chart){\n\t\tthis.options = options;\n\t\tthis.chart = chart;\n\t\tthis.id = uid();\n\t\t//Add the chart instance to the global namespace\n\t\tChart.instances[this.id] = this;\n\n\t\t// Initialize is always called when a chart type is created\n\t\t// By default it is a no op, but it should be extended\n\t\tif (options.responsive){\n\t\t\tthis.resize();\n\t\t}\n\t\tthis.initialize.call(this,data);\n\t};\n\n\t//Core methods that'll be a part of every chart type\n\textend(Chart.Type.prototype,{\n\t\tinitialize : function(){return this;},\n\t\tclear : function(){\n\t\t\tclear(this.chart);\n\t\t\treturn this;\n\t\t},\n\t\tstop : function(){\n\t\t\t// Stops any current animation loop occuring\n\t\t\tcancelAnimFrame(this.animationFrame);\n\t\t\treturn this;\n\t\t},\n\t\tresize : function(callback){\n\t\t\tthis.stop();\n\t\t\tvar canvas = this.chart.canvas,\n\t\t\t\tnewWidth = getMaximumWidth(this.chart.canvas),\n\t\t\t\tnewHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : getMaximumHeight(this.chart.canvas);\n\n\t\t\tcanvas.width = this.chart.width = newWidth;\n\t\t\tcanvas.height = this.chart.height = newHeight;\n\n\t\t\tretinaScale(this.chart);\n\n\t\t\tif (typeof callback === \"function\"){\n\t\t\t\tcallback.apply(this, Array.prototype.slice.call(arguments, 1));\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\treflow : noop,\n\t\trender : function(reflow){\n\t\t\tif (reflow){\n\t\t\t\tthis.reflow();\n\t\t\t}\n\t\t\tif (this.options.animation && !reflow){\n\t\t\t\thelpers.animationLoop(\n\t\t\t\t\tthis.draw,\n\t\t\t\t\tthis.options.animationSteps,\n\t\t\t\t\tthis.options.animationEasing,\n\t\t\t\t\tthis.options.onAnimationProgress,\n\t\t\t\t\tthis.options.onAnimationComplete,\n\t\t\t\t\tthis\n\t\t\t\t);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tthis.draw();\n\t\t\t\tthis.options.onAnimationComplete.call(this);\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\tgenerateLegend : function(){\n\t\t\treturn template(this.options.legendTemplate,this);\n\t\t},\n\t\tdestroy : function(){\n\t\t\tthis.clear();\n\t\t\tunbindEvents(this, this.events);\n\t\t\tvar canvas = this.chart.canvas;\n\n\t\t\t// Reset canvas height/width attributes starts a fresh with the canvas context\n\t\t\tcanvas.width = this.chart.width;\n\t\t\tcanvas.height = this.chart.height;\n\n\t\t\t// < IE9 doesn't support removeProperty\n\t\t\tif (canvas.style.removeProperty) {\n\t\t\t\tcanvas.style.removeProperty('width');\n\t\t\t\tcanvas.style.removeProperty('height');\n\t\t\t} else {\n\t\t\t\tcanvas.style.removeAttribute('width');\n\t\t\t\tcanvas.style.removeAttribute('height');\n\t\t\t}\n\n\t\t\tdelete Chart.instances[this.id];\n\t\t},\n\t\tshowTooltip : function(ChartElements, forceRedraw){\n\t\t\t// Only redraw the chart if we've actually changed what we're hovering on.\n\t\t\tif (typeof this.activeElements === 'undefined') this.activeElements = [];\n\n\t\t\tvar isChanged = (function(Elements){\n\t\t\t\tvar changed = false;\n\n\t\t\t\tif (Elements.length !== this.activeElements.length){\n\t\t\t\t\tchanged = true;\n\t\t\t\t\treturn changed;\n\t\t\t\t}\n\n\t\t\t\teach(Elements, function(element, index){\n\t\t\t\t\tif (element !== this.activeElements[index]){\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\t\t\t\treturn changed;\n\t\t\t}).call(this, ChartElements);\n\n\t\t\tif (!isChanged && !forceRedraw){\n\t\t\t\treturn;\n\t\t\t}\n\t\t\telse{\n\t\t\t\tthis.activeElements = ChartElements;\n\t\t\t}\n\t\t\tthis.draw();\n\t\t\tif(this.options.customTooltips){\n\t\t\t\tthis.options.customTooltips(false);\n\t\t\t}\n\t\t\tif (ChartElements.length > 0){\n\t\t\t\t// If we have multiple datasets, show a MultiTooltip for all of the data points at that index\n\t\t\t\tif (this.datasets && this.datasets.length > 1) {\n\t\t\t\t\tvar dataArray,\n\t\t\t\t\t\tdataIndex;\n\n\t\t\t\t\tfor (var i = this.datasets.length - 1; i >= 0; i--) {\n\t\t\t\t\t\tdataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments;\n\t\t\t\t\t\tdataIndex = indexOf(dataArray, ChartElements[0]);\n\t\t\t\t\t\tif (dataIndex !== -1){\n\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\tvar tooltipLabels = [],\n\t\t\t\t\t\ttooltipColors = [],\n\t\t\t\t\t\tmedianPosition = (function(index) {\n\n\t\t\t\t\t\t\t// Get all the points at that particular index\n\t\t\t\t\t\t\tvar Elements = [],\n\t\t\t\t\t\t\t\tdataCollection,\n\t\t\t\t\t\t\t\txPositions = [],\n\t\t\t\t\t\t\t\tyPositions = [],\n\t\t\t\t\t\t\t\txMax,\n\t\t\t\t\t\t\t\tyMax,\n\t\t\t\t\t\t\t\txMin,\n\t\t\t\t\t\t\t\tyMin;\n\t\t\t\t\t\t\thelpers.each(this.datasets, function(dataset){\n\t\t\t\t\t\t\t\tdataCollection = dataset.points || dataset.bars || dataset.segments;\n\t\t\t\t\t\t\t\tif (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){\n\t\t\t\t\t\t\t\t\tElements.push(dataCollection[dataIndex]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\thelpers.each(Elements, function(element) {\n\t\t\t\t\t\t\t\txPositions.push(element.x);\n\t\t\t\t\t\t\t\tyPositions.push(element.y);\n\n\n\t\t\t\t\t\t\t\t//Include any colour information about the element\n\t\t\t\t\t\t\t\ttooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));\n\t\t\t\t\t\t\t\ttooltipColors.push({\n\t\t\t\t\t\t\t\t\tfill: element._saved.fillColor || element.fillColor,\n\t\t\t\t\t\t\t\t\tstroke: element._saved.strokeColor || element.strokeColor\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t}, this);\n\n\t\t\t\t\t\t\tyMin = min(yPositions);\n\t\t\t\t\t\t\tyMax = max(yPositions);\n\n\t\t\t\t\t\t\txMin = min(xPositions);\n\t\t\t\t\t\t\txMax = max(xPositions);\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tx: (xMin > this.chart.width/2) ? xMin : xMax,\n\t\t\t\t\t\t\t\ty: (yMin + yMax)/2\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}).call(this, dataIndex);\n\n\t\t\t\t\tnew Chart.MultiTooltip({\n\t\t\t\t\t\tx: medianPosition.x,\n\t\t\t\t\t\ty: medianPosition.y,\n\t\t\t\t\t\txPadding: this.options.tooltipXPadding,\n\t\t\t\t\t\tyPadding: this.options.tooltipYPadding,\n\t\t\t\t\t\txOffset: this.options.tooltipXOffset,\n\t\t\t\t\t\tfillColor: this.options.tooltipFillColor,\n\t\t\t\t\t\ttextColor: this.options.tooltipFontColor,\n\t\t\t\t\t\tfontFamily: this.options.tooltipFontFamily,\n\t\t\t\t\t\tfontStyle: this.options.tooltipFontStyle,\n\t\t\t\t\t\tfontSize: this.options.tooltipFontSize,\n\t\t\t\t\t\ttitleTextColor: this.options.tooltipTitleFontColor,\n\t\t\t\t\t\ttitleFontFamily: this.options.tooltipTitleFontFamily,\n\t\t\t\t\t\ttitleFontStyle: this.options.tooltipTitleFontStyle,\n\t\t\t\t\t\ttitleFontSize: this.options.tooltipTitleFontSize,\n\t\t\t\t\t\tcornerRadius: this.options.tooltipCornerRadius,\n\t\t\t\t\t\tlabels: tooltipLabels,\n\t\t\t\t\t\tlegendColors: tooltipColors,\n\t\t\t\t\t\tlegendColorBackground : this.options.multiTooltipKeyBackground,\n\t\t\t\t\t\ttitle: ChartElements[0].label,\n\t\t\t\t\t\tchart: this.chart,\n\t\t\t\t\t\tctx: this.chart.ctx,\n\t\t\t\t\t\tcustom: this.options.customTooltips\n\t\t\t\t\t}).draw();\n\n\t\t\t\t} else {\n\t\t\t\t\teach(ChartElements, function(Element) {\n\t\t\t\t\t\tvar tooltipPosition = Element.tooltipPosition();\n\t\t\t\t\t\tnew Chart.Tooltip({\n\t\t\t\t\t\t\tx: Math.round(tooltipPosition.x),\n\t\t\t\t\t\t\ty: Math.round(tooltipPosition.y),\n\t\t\t\t\t\t\txPadding: this.options.tooltipXPadding,\n\t\t\t\t\t\t\tyPadding: this.options.tooltipYPadding,\n\t\t\t\t\t\t\tfillColor: this.options.tooltipFillColor,\n\t\t\t\t\t\t\ttextColor: this.options.tooltipFontColor,\n\t\t\t\t\t\t\tfontFamily: this.options.tooltipFontFamily,\n\t\t\t\t\t\t\tfontStyle: this.options.tooltipFontStyle,\n\t\t\t\t\t\t\tfontSize: this.options.tooltipFontSize,\n\t\t\t\t\t\t\tcaretHeight: this.options.tooltipCaretSize,\n\t\t\t\t\t\t\tcornerRadius: this.options.tooltipCornerRadius,\n\t\t\t\t\t\t\ttext: template(this.options.tooltipTemplate, Element),\n\t\t\t\t\t\t\tchart: this.chart,\n\t\t\t\t\t\t\tcustom: this.options.customTooltips\n\t\t\t\t\t\t}).draw();\n\t\t\t\t\t}, this);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\ttoBase64Image : function(){\n\t\t\treturn this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);\n\t\t}\n\t});\n\n\tChart.Type.extend = function(extensions){\n\n\t\tvar parent = this;\n\n\t\tvar ChartType = function(){\n\t\t\treturn parent.apply(this,arguments);\n\t\t};\n\n\t\t//Copy the prototype object of the this class\n\t\tChartType.prototype = clone(parent.prototype);\n\t\t//Now overwrite some of the properties in the base class with the new extensions\n\t\textend(ChartType.prototype, extensions);\n\n\t\tChartType.extend = Chart.Type.extend;\n\n\t\tif (extensions.name || parent.prototype.name){\n\n\t\t\tvar chartName = extensions.name || parent.prototype.name;\n\t\t\t//Assign any potential default values of the new chart type\n\n\t\t\t//If none are defined, we'll use a clone of the chart type this is being extended from.\n\t\t\t//I.e. if we extend a line chart, we'll use the defaults from the line chart if our new chart\n\t\t\t//doesn't define some defaults of their own.\n\n\t\t\tvar baseDefaults = (Chart.defaults[parent.prototype.name]) ? clone(Chart.defaults[parent.prototype.name]) : {};\n\n\t\t\tChart.defaults[chartName] = extend(baseDefaults,extensions.defaults);\n\n\t\t\tChart.types[chartName] = ChartType;\n\n\t\t\t//Register this new chart type in the Chart prototype\n\t\t\tChart.prototype[chartName] = function(data,options){\n\t\t\t\tvar config = merge(Chart.defaults.global, Chart.defaults[chartName], options || {});\n\t\t\t\treturn new ChartType(data,config,this);\n\t\t\t};\n\t\t} else{\n\t\t\twarn(\"Name not provided for this chart, so it hasn't been registered\");\n\t\t}\n\t\treturn parent;\n\t};\n\n\tChart.Element = function(configuration){\n\t\textend(this,configuration);\n\t\tthis.initialize.apply(this,arguments);\n\t\tthis.save();\n\t};\n\textend(Chart.Element.prototype,{\n\t\tinitialize : function(){},\n\t\trestore : function(props){\n\t\t\tif (!props){\n\t\t\t\textend(this,this._saved);\n\t\t\t} else {\n\t\t\t\teach(props,function(key){\n\t\t\t\t\tthis[key] = this._saved[key];\n\t\t\t\t},this);\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\tsave : function(){\n\t\t\tthis._saved = clone(this);\n\t\t\tdelete this._saved._saved;\n\t\t\treturn this;\n\t\t},\n\t\tupdate : function(newProps){\n\t\t\teach(newProps,function(value,key){\n\t\t\t\tthis._saved[key] = this[key];\n\t\t\t\tthis[key] = value;\n\t\t\t},this);\n\t\t\treturn this;\n\t\t},\n\t\ttransition : function(props,ease){\n\t\t\teach(props,function(value,key){\n\t\t\t\tthis[key] = ((value - this._saved[key]) * ease) + this._saved[key];\n\t\t\t},this);\n\t\t\treturn this;\n\t\t},\n\t\ttooltipPosition : function(){\n\t\t\treturn {\n\t\t\t\tx : this.x,\n\t\t\t\ty : this.y\n\t\t\t};\n\t\t},\n\t\thasValue: function(){\n\t\t\treturn isNumber(this.value);\n\t\t}\n\t});\n\n\tChart.Element.extend = inherits;\n\n\n\tChart.Point = Chart.Element.extend({\n\t\tdisplay: true,\n\t\tinRange: function(chartX,chartY){\n\t\t\tvar hitDetectionRange = this.hitDetectionRadius + this.radius;\n\t\t\treturn ((Math.pow(chartX-this.x, 2)+Math.pow(chartY-this.y, 2)) < Math.pow(hitDetectionRange,2));\n\t\t},\n\t\tdraw : function(){\n\t\t\tif (this.display){\n\t\t\t\tvar ctx = this.ctx;\n\t\t\t\tctx.beginPath();\n\n\t\t\t\tctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);\n\t\t\t\tctx.closePath();\n\n\t\t\t\tctx.strokeStyle = this.strokeColor;\n\t\t\t\tctx.lineWidth = this.strokeWidth;\n\n\t\t\t\tctx.fillStyle = this.fillColor;\n\n\t\t\t\tctx.fill();\n\t\t\t\tctx.stroke();\n\t\t\t}\n\n\n\t\t\t//Quick debug for bezier curve splining\n\t\t\t//Highlights control points and the line between them.\n\t\t\t//Handy for dev - stripped in the min version.\n\n\t\t\t// ctx.save();\n\t\t\t// ctx.fillStyle = \"black\";\n\t\t\t// ctx.strokeStyle = \"black\"\n\t\t\t// ctx.beginPath();\n\t\t\t// ctx.arc(this.controlPoints.inner.x,this.controlPoints.inner.y, 2, 0, Math.PI*2);\n\t\t\t// ctx.fill();\n\n\t\t\t// ctx.beginPath();\n\t\t\t// ctx.arc(this.controlPoints.outer.x,this.controlPoints.outer.y, 2, 0, Math.PI*2);\n\t\t\t// ctx.fill();\n\n\t\t\t// ctx.moveTo(this.controlPoints.inner.x,this.controlPoints.inner.y);\n\t\t\t// ctx.lineTo(this.x, this.y);\n\t\t\t// ctx.lineTo(this.controlPoints.outer.x,this.controlPoints.outer.y);\n\t\t\t// ctx.stroke();\n\n\t\t\t// ctx.restore();\n\n\n\n\t\t}\n\t});\n\n\tChart.Arc = Chart.Element.extend({\n\t\tinRange : function(chartX,chartY){\n\n\t\t\tvar pointRelativePosition = helpers.getAngleFromPoint(this, {\n\t\t\t\tx: chartX,\n\t\t\t\ty: chartY\n\t\t\t});\n\n\t\t\t//Check if within the range of the open/close angle\n\t\t\tvar betweenAngles = (pointRelativePosition.angle >= this.startAngle && pointRelativePosition.angle <= this.endAngle),\n\t\t\t\twithinRadius = (pointRelativePosition.distance >= this.innerRadius && pointRelativePosition.distance <= this.outerRadius);\n\n\t\t\treturn (betweenAngles && withinRadius);\n\t\t\t//Ensure within the outside of the arc centre, but inside arc outer\n\t\t},\n\t\ttooltipPosition : function(){\n\t\t\tvar centreAngle = this.startAngle + ((this.endAngle - this.startAngle) / 2),\n\t\t\t\trangeFromCentre = (this.outerRadius - this.innerRadius) / 2 + this.innerRadius;\n\t\t\treturn {\n\t\t\t\tx : this.x + (Math.cos(centreAngle) * rangeFromCentre),\n\t\t\t\ty : this.y + (Math.sin(centreAngle) * rangeFromCentre)\n\t\t\t};\n\t\t},\n\t\tdraw : function(animationPercent){\n\n\t\t\tvar easingDecimal = animationPercent || 1;\n\n\t\t\tvar ctx = this.ctx;\n\n\t\t\tctx.beginPath();\n\n\t\t\tctx.arc(this.x, this.y, this.outerRadius, this.startAngle, this.endAngle);\n\n\t\t\tctx.arc(this.x, this.y, this.innerRadius, this.endAngle, this.startAngle, true);\n\n\t\t\tctx.closePath();\n\t\t\tctx.strokeStyle = this.strokeColor;\n\t\t\tctx.lineWidth = this.strokeWidth;\n\n\t\t\tctx.fillStyle = this.fillColor;\n\n\t\t\tctx.fill();\n\t\t\tctx.lineJoin = 'bevel';\n\n\t\t\tif (this.showStroke){\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t}\n\t});\n\n\tChart.Rectangle = Chart.Element.extend({\n\t\tdraw : function(){\n\t\t\tvar ctx = this.ctx,\n\t\t\t\thalfWidth = this.width/2,\n\t\t\t\tleftX = this.x - halfWidth,\n\t\t\t\trightX = this.x + halfWidth,\n\t\t\t\ttop = this.base - (this.base - this.y),\n\t\t\t\thalfStroke = this.strokeWidth / 2;\n\n\t\t\t// Canvas doesn't allow us to stroke inside the width so we can\n\t\t\t// adjust the sizes to fit if we're setting a stroke on the line\n\t\t\tif (this.showStroke){\n\t\t\t\tleftX += halfStroke;\n\t\t\t\trightX -= halfStroke;\n\t\t\t\ttop += halfStroke;\n\t\t\t}\n\n\t\t\tctx.beginPath();\n\n\t\t\tctx.fillStyle = this.fillColor;\n\t\t\tctx.strokeStyle = this.strokeColor;\n\t\t\tctx.lineWidth = this.strokeWidth;\n\n\t\t\t// It'd be nice to keep this class totally generic to any rectangle\n\t\t\t// and simply specify which border to miss out.\n\t\t\tctx.moveTo(leftX, this.base);\n\t\t\tctx.lineTo(leftX, top);\n\t\t\tctx.lineTo(rightX, top);\n\t\t\tctx.lineTo(rightX, this.base);\n\t\t\tctx.fill();\n\t\t\tif (this.showStroke){\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t},\n\t\theight : function(){\n\t\t\treturn this.base - this.y;\n\t\t},\n\t\tinRange : function(chartX,chartY){\n\t\t\treturn (chartX >= this.x - this.width/2 && chartX <= this.x + this.width/2) && (chartY >= this.y && chartY <= this.base);\n\t\t}\n\t});\n\n\tChart.Tooltip = Chart.Element.extend({\n\t\tdraw : function(){\n\n\t\t\tvar ctx = this.chart.ctx;\n\n\t\t\tctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);\n\n\t\t\tthis.xAlign = \"center\";\n\t\t\tthis.yAlign = \"above\";\n\n\t\t\t//Distance between the actual element.y position and the start of the tooltip caret\n\t\t\tvar caretPadding = this.caretPadding = 2;\n\n\t\t\tvar tooltipWidth = ctx.measureText(this.text).width + 2*this.xPadding,\n\t\t\t\ttooltipRectHeight = this.fontSize + 2*this.yPadding,\n\t\t\t\ttooltipHeight = tooltipRectHeight + this.caretHeight + caretPadding;\n\n\t\t\tif (this.x + tooltipWidth/2 >this.chart.width){\n\t\t\t\tthis.xAlign = \"left\";\n\t\t\t} else if (this.x - tooltipWidth/2 < 0){\n\t\t\t\tthis.xAlign = \"right\";\n\t\t\t}\n\n\t\t\tif (this.y - tooltipHeight < 0){\n\t\t\t\tthis.yAlign = \"below\";\n\t\t\t}\n\n\n\t\t\tvar tooltipX = this.x - tooltipWidth/2,\n\t\t\t\ttooltipY = this.y - tooltipHeight;\n\n\t\t\tctx.fillStyle = this.fillColor;\n\n\t\t\t// Custom Tooltips\n\t\t\tif(this.custom){\n\t\t\t\tthis.custom(this);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tswitch(this.yAlign)\n\t\t\t\t{\n\t\t\t\tcase \"above\":\n\t\t\t\t\t//Draw a caret above the x/y\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(this.x,this.y - caretPadding);\n\t\t\t\t\tctx.lineTo(this.x + this.caretHeight, this.y - (caretPadding + this.caretHeight));\n\t\t\t\t\tctx.lineTo(this.x - this.caretHeight, this.y - (caretPadding + this.caretHeight));\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tctx.fill();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"below\":\n\t\t\t\t\ttooltipY = this.y + caretPadding + this.caretHeight;\n\t\t\t\t\t//Draw a caret below the x/y\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(this.x, this.y + caretPadding);\n\t\t\t\t\tctx.lineTo(this.x + this.caretHeight, this.y + caretPadding + this.caretHeight);\n\t\t\t\t\tctx.lineTo(this.x - this.caretHeight, this.y + caretPadding + this.caretHeight);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tctx.fill();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tswitch(this.xAlign)\n\t\t\t\t{\n\t\t\t\tcase \"left\":\n\t\t\t\t\ttooltipX = this.x - tooltipWidth + (this.cornerRadius + this.caretHeight);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"right\":\n\t\t\t\t\ttooltipX = this.x - (this.cornerRadius + this.caretHeight);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdrawRoundedRectangle(ctx,tooltipX,tooltipY,tooltipWidth,tooltipRectHeight,this.cornerRadius);\n\n\t\t\t\tctx.fill();\n\n\t\t\t\tctx.fillStyle = this.textColor;\n\t\t\t\tctx.textAlign = \"center\";\n\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\tctx.fillText(this.text, tooltipX + tooltipWidth/2, tooltipY + tooltipRectHeight/2);\n\t\t\t}\n\t\t}\n\t});\n\n\tChart.MultiTooltip = Chart.Element.extend({\n\t\tinitialize : function(){\n\t\t\tthis.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);\n\n\t\t\tthis.titleFont = fontString(this.titleFontSize,this.titleFontStyle,this.titleFontFamily);\n\n\t\t\tthis.height = (this.labels.length * this.fontSize) + ((this.labels.length-1) * (this.fontSize/2)) + (this.yPadding*2) + this.titleFontSize *1.5;\n\n\t\t\tthis.ctx.font = this.titleFont;\n\n\t\t\tvar titleWidth = this.ctx.measureText(this.title).width,\n\t\t\t\t//Label has a legend square as well so account for this.\n\t\t\t\tlabelWidth = longestText(this.ctx,this.font,this.labels) + this.fontSize + 3,\n\t\t\t\tlongestTextWidth = max([labelWidth,titleWidth]);\n\n\t\t\tthis.width = longestTextWidth + (this.xPadding*2);\n\n\n\t\t\tvar halfHeight = this.height/2;\n\n\t\t\t//Check to ensure the height will fit on the canvas\n\t\t\tif (this.y - halfHeight < 0 ){\n\t\t\t\tthis.y = halfHeight;\n\t\t\t} else if (this.y + halfHeight > this.chart.height){\n\t\t\t\tthis.y = this.chart.height - halfHeight;\n\t\t\t}\n\n\t\t\t//Decide whether to align left or right based on position on canvas\n\t\t\tif (this.x > this.chart.width/2){\n\t\t\t\tthis.x -= this.xOffset + this.width;\n\t\t\t} else {\n\t\t\t\tthis.x += this.xOffset;\n\t\t\t}\n\n\n\t\t},\n\t\tgetLineHeight : function(index){\n\t\t\tvar baseLineHeight = this.y - (this.height/2) + this.yPadding,\n\t\t\t\tafterTitleIndex = index-1;\n\n\t\t\t//If the index is zero, we're getting the title\n\t\t\tif (index === 0){\n\t\t\t\treturn baseLineHeight + this.titleFontSize/2;\n\t\t\t} else{\n\t\t\t\treturn baseLineHeight + ((this.fontSize*1.5*afterTitleIndex) + this.fontSize/2) + this.titleFontSize * 1.5;\n\t\t\t}\n\n\t\t},\n\t\tdraw : function(){\n\t\t\t// Custom Tooltips\n\t\t\tif(this.custom){\n\t\t\t\tthis.custom(this);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tdrawRoundedRectangle(this.ctx,this.x,this.y - this.height/2,this.width,this.height,this.cornerRadius);\n\t\t\t\tvar ctx = this.ctx;\n\t\t\t\tctx.fillStyle = this.fillColor;\n\t\t\t\tctx.fill();\n\t\t\t\tctx.closePath();\n\n\t\t\t\tctx.textAlign = \"left\";\n\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\tctx.fillStyle = this.titleTextColor;\n\t\t\t\tctx.font = this.titleFont;\n\n\t\t\t\tctx.fillText(this.title,this.x + this.xPadding, this.getLineHeight(0));\n\n\t\t\t\tctx.font = this.font;\n\t\t\t\thelpers.each(this.labels,function(label,index){\n\t\t\t\t\tctx.fillStyle = this.textColor;\n\t\t\t\t\tctx.fillText(label,this.x + this.xPadding + this.fontSize + 3, this.getLineHeight(index + 1));\n\n\t\t\t\t\t//A bit gnarly, but clearing this rectangle breaks when using explorercanvas (clears whole canvas)\n\t\t\t\t\t//ctx.clearRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);\n\t\t\t\t\t//Instead we'll make a white filled block to put the legendColour palette over.\n\n\t\t\t\t\tctx.fillStyle = this.legendColorBackground;\n\t\t\t\t\tctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);\n\n\t\t\t\t\tctx.fillStyle = this.legendColors[index].fill;\n\t\t\t\t\tctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);\n\n\n\t\t\t\t},this);\n\t\t\t}\n\t\t}\n\t});\n\n\tChart.Scale = Chart.Element.extend({\n\t\tinitialize : function(){\n\t\t\tthis.fit();\n\t\t},\n\t\tbuildYLabels : function(){\n\t\t\tthis.yLabels = [];\n\n\t\t\tvar stepDecimalPlaces = getDecimalPlaces(this.stepValue);\n\n\t\t\tfor (var i=0; i<=this.steps; i++){\n\t\t\t\tthis.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));\n\t\t\t}\n\t\t\tthis.yLabelWidth = (this.display && this.showLabels) ? longestText(this.ctx,this.font,this.yLabels) : 0;\n\t\t},\n\t\taddXLabel : function(label){\n\t\t\tthis.xLabels.push(label);\n\t\t\tthis.valuesCount++;\n\t\t\tthis.fit();\n\t\t},\n\t\tremoveXLabel : function(){\n\t\t\tthis.xLabels.shift();\n\t\t\tthis.valuesCount--;\n\t\t\tthis.fit();\n\t\t},\n\t\t// Fitting loop to rotate x Labels and figure out what fits there, and also calculate how many Y steps to use\n\t\tfit: function(){\n\t\t\t// First we need the width of the yLabels, assuming the xLabels aren't rotated\n\n\t\t\t// To do that we need the base line at the top and base of the chart, assuming there is no x label rotation\n\t\t\tthis.startPoint = (this.display) ? this.fontSize : 0;\n\t\t\tthis.endPoint = (this.display) ? this.height - (this.fontSize * 1.5) - 5 : this.height; // -5 to pad labels\n\n\t\t\t// Apply padding settings to the start and end point.\n\t\t\tthis.startPoint += this.padding;\n\t\t\tthis.endPoint -= this.padding;\n\n\t\t\t// Cache the starting height, so can determine if we need to recalculate the scale yAxis\n\t\t\tvar cachedHeight = this.endPoint - this.startPoint,\n\t\t\t\tcachedYLabelWidth;\n\n\t\t\t// Build the current yLabels so we have an idea of what size they'll be to start\n\t\t\t/*\n\t\t\t *\tThis sets what is returned from calculateScaleRange as static properties of this class:\n\t\t\t *\n\t\t\t\tthis.steps;\n\t\t\t\tthis.stepValue;\n\t\t\t\tthis.min;\n\t\t\t\tthis.max;\n\t\t\t *\n\t\t\t */\n\t\t\tthis.calculateYRange(cachedHeight);\n\n\t\t\t// With these properties set we can now build the array of yLabels\n\t\t\t// and also the width of the largest yLabel\n\t\t\tthis.buildYLabels();\n\n\t\t\tthis.calculateXLabelRotation();\n\n\t\t\twhile((cachedHeight > this.endPoint - this.startPoint)){\n\t\t\t\tcachedHeight = this.endPoint - this.startPoint;\n\t\t\t\tcachedYLabelWidth = this.yLabelWidth;\n\n\t\t\t\tthis.calculateYRange(cachedHeight);\n\t\t\t\tthis.buildYLabels();\n\n\t\t\t\t// Only go through the xLabel loop again if the yLabel width has changed\n\t\t\t\tif (cachedYLabelWidth < this.yLabelWidth){\n\t\t\t\t\tthis.calculateXLabelRotation();\n\t\t\t\t}\n\t\t\t}\n\n\t\t},\n\t\tcalculateXLabelRotation : function(){\n\t\t\t//Get the width of each grid by calculating the difference\n\t\t\t//between x offsets between 0 and 1.\n\n\t\t\tthis.ctx.font = this.font;\n\n\t\t\tvar firstWidth = this.ctx.measureText(this.xLabels[0]).width,\n\t\t\t\tlastWidth = this.ctx.measureText(this.xLabels[this.xLabels.length - 1]).width,\n\t\t\t\tfirstRotated,\n\t\t\t\tlastRotated;\n\n\n\t\t\tthis.xScalePaddingRight = lastWidth/2 + 3;\n\t\t\tthis.xScalePaddingLeft = (firstWidth/2 > this.yLabelWidth + 10) ? firstWidth/2 : this.yLabelWidth + 10;\n\n\t\t\tthis.xLabelRotation = 0;\n\t\t\tif (this.display){\n\t\t\t\tvar originalLabelWidth = longestText(this.ctx,this.font,this.xLabels),\n\t\t\t\t\tcosRotation,\n\t\t\t\t\tfirstRotatedWidth;\n\t\t\t\tthis.xLabelWidth = originalLabelWidth;\n\t\t\t\t//Allow 3 pixels x2 padding either side for label readability\n\t\t\t\tvar xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6;\n\n\t\t\t\t//Max label rotate should be 90 - also act as a loop counter\n\t\t\t\twhile ((this.xLabelWidth > xGridWidth && this.xLabelRotation === 0) || (this.xLabelWidth > xGridWidth && this.xLabelRotation <= 90 && this.xLabelRotation > 0)){\n\t\t\t\t\tcosRotation = Math.cos(toRadians(this.xLabelRotation));\n\n\t\t\t\t\tfirstRotated = cosRotation * firstWidth;\n\t\t\t\t\tlastRotated = cosRotation * lastWidth;\n\n\t\t\t\t\t// We're right aligning the text now.\n\t\t\t\t\tif (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8){\n\t\t\t\t\t\tthis.xScalePaddingLeft = firstRotated + this.fontSize / 2;\n\t\t\t\t\t}\n\t\t\t\t\tthis.xScalePaddingRight = this.fontSize/2;\n\n\n\t\t\t\t\tthis.xLabelRotation++;\n\t\t\t\t\tthis.xLabelWidth = cosRotation * originalLabelWidth;\n\n\t\t\t\t}\n\t\t\t\tif (this.xLabelRotation > 0){\n\t\t\t\t\tthis.endPoint -= Math.sin(toRadians(this.xLabelRotation))*originalLabelWidth + 3;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse{\n\t\t\t\tthis.xLabelWidth = 0;\n\t\t\t\tthis.xScalePaddingRight = this.padding;\n\t\t\t\tthis.xScalePaddingLeft = this.padding;\n\t\t\t}\n\n\t\t},\n\t\t// Needs to be overidden in each Chart type\n\t\t// Otherwise we need to pass all the data into the scale class\n\t\tcalculateYRange: noop,\n\t\tdrawingArea: function(){\n\t\t\treturn this.startPoint - this.endPoint;\n\t\t},\n\t\tcalculateY : function(value){\n\t\t\tvar scalingFactor = this.drawingArea() / (this.min - this.max);\n\t\t\treturn this.endPoint - (scalingFactor * (value - this.min));\n\t\t},\n\t\tcalculateX : function(index){\n\t\t\tvar isRotated = (this.xLabelRotation > 0),\n\t\t\t\t// innerWidth = (this.offsetGridLines) ? this.width - offsetLeft - this.padding : this.width - (offsetLeft + halfLabelWidth * 2) - this.padding,\n\t\t\t\tinnerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight),\n\t\t\t\tvalueWidth = innerWidth/Math.max((this.valuesCount - ((this.offsetGridLines) ? 0 : 1)), 1),\n\t\t\t\tvalueOffset = (valueWidth * index) + this.xScalePaddingLeft;\n\n\t\t\tif (this.offsetGridLines){\n\t\t\t\tvalueOffset += (valueWidth/2);\n\t\t\t}\n\n\t\t\treturn Math.round(valueOffset);\n\t\t},\n\t\tupdate : function(newProps){\n\t\t\thelpers.extend(this, newProps);\n\t\t\tthis.fit();\n\t\t},\n\t\tdraw : function(){\n\t\t\tvar ctx = this.ctx,\n\t\t\t\tyLabelGap = (this.endPoint - this.startPoint) / this.steps,\n\t\t\t\txStart = Math.round(this.xScalePaddingLeft);\n\t\t\tif (this.display){\n\t\t\t\tctx.fillStyle = this.textColor;\n\t\t\t\tctx.font = this.font;\n\t\t\t\teach(this.yLabels,function(labelString,index){\n\t\t\t\t\tvar yLabelCenter = this.endPoint - (yLabelGap * index),\n\t\t\t\t\t\tlinePositionY = Math.round(yLabelCenter),\n\t\t\t\t\t\tdrawHorizontalLine = this.showHorizontalLines;\n\n\t\t\t\t\tctx.textAlign = \"right\";\n\t\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\t\tif (this.showLabels){\n\t\t\t\t\t\tctx.fillText(labelString,xStart - 10,yLabelCenter);\n\t\t\t\t\t}\n\n\t\t\t\t\t// This is X axis, so draw it\n\t\t\t\t\tif (index === 0 && !drawHorizontalLine){\n\t\t\t\t\t\tdrawHorizontalLine = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawHorizontalLine){\n\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (index > 0){\n\t\t\t\t\t\t// This is a grid line in the centre, so drop that\n\t\t\t\t\t\tctx.lineWidth = this.gridLineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.gridLineColor;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// This is the first line on the scale\n\t\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\t}\n\n\t\t\t\t\tlinePositionY += helpers.aliasPixel(ctx.lineWidth);\n\n\t\t\t\t\tif(drawHorizontalLine){\n\t\t\t\t\t\tctx.moveTo(xStart, linePositionY);\n\t\t\t\t\t\tctx.lineTo(this.width, linePositionY);\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(xStart - 5, linePositionY);\n\t\t\t\t\tctx.lineTo(xStart, linePositionY);\n\t\t\t\t\tctx.stroke();\n\t\t\t\t\tctx.closePath();\n\n\t\t\t\t},this);\n\n\t\t\t\teach(this.xLabels,function(label,index){\n\t\t\t\t\tvar xPos = this.calculateX(index) + aliasPixel(this.lineWidth),\n\t\t\t\t\t\t// Check to see if line/bar here and decide where to place the line\n\t\t\t\t\t\tlinePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth),\n\t\t\t\t\t\tisRotated = (this.xLabelRotation > 0),\n\t\t\t\t\t\tdrawVerticalLine = this.showVerticalLines;\n\n\t\t\t\t\t// This is Y axis, so draw it\n\t\t\t\t\tif (index === 0 && !drawVerticalLine){\n\t\t\t\t\t\tdrawVerticalLine = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawVerticalLine){\n\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (index > 0){\n\t\t\t\t\t\t// This is a grid line in the centre, so drop that\n\t\t\t\t\t\tctx.lineWidth = this.gridLineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.gridLineColor;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// This is the first line on the scale\n\t\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawVerticalLine){\n\t\t\t\t\t\tctx.moveTo(linePos,this.endPoint);\n\t\t\t\t\t\tctx.lineTo(linePos,this.startPoint - 3);\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t}\n\n\n\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\n\n\t\t\t\t\t// Small lines at the bottom of the base grid line\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(linePos,this.endPoint);\n\t\t\t\t\tctx.lineTo(linePos,this.endPoint + 5);\n\t\t\t\t\tctx.stroke();\n\t\t\t\t\tctx.closePath();\n\n\t\t\t\t\tctx.save();\n\t\t\t\t\tctx.translate(xPos,(isRotated) ? this.endPoint + 12 : this.endPoint + 8);\n\t\t\t\t\tctx.rotate(toRadians(this.xLabelRotation)*-1);\n\t\t\t\t\tctx.font = this.font;\n\t\t\t\t\tctx.textAlign = (isRotated) ? \"right\" : \"center\";\n\t\t\t\t\tctx.textBaseline = (isRotated) ? \"middle\" : \"top\";\n\t\t\t\t\tctx.fillText(label, 0, 0);\n\t\t\t\t\tctx.restore();\n\t\t\t\t},this);\n\n\t\t\t}\n\t\t}\n\n\t});\n\n\tChart.RadialScale = Chart.Element.extend({\n\t\tinitialize: function(){\n\t\t\tthis.size = min([this.height, this.width]);\n\t\t\tthis.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);\n\t\t},\n\t\tcalculateCenterOffset: function(value){\n\t\t\t// Take into account half font size + the yPadding of the top value\n\t\t\tvar scalingFactor = this.drawingArea / (this.max - this.min);\n\n\t\t\treturn (value - this.min) * scalingFactor;\n\t\t},\n\t\tupdate : function(){\n\t\t\tif (!this.lineArc){\n\t\t\t\tthis.setScaleSize();\n\t\t\t} else {\n\t\t\t\tthis.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);\n\t\t\t}\n\t\t\tthis.buildYLabels();\n\t\t},\n\t\tbuildYLabels: function(){\n\t\t\tthis.yLabels = [];\n\n\t\t\tvar stepDecimalPlaces = getDecimalPlaces(this.stepValue);\n\n\t\t\tfor (var i=0; i<=this.steps; i++){\n\t\t\t\tthis.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));\n\t\t\t}\n\t\t},\n\t\tgetCircumference : function(){\n\t\t\treturn ((Math.PI*2) / this.valuesCount);\n\t\t},\n\t\tsetScaleSize: function(){\n\t\t\t/*\n\t\t\t * Right, this is really confusing and there is a lot of maths going on here\n\t\t\t * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9\n\t\t\t *\n\t\t\t * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif\n\t\t\t *\n\t\t\t * Solution:\n\t\t\t *\n\t\t\t * We assume the radius of the polygon is half the size of the canvas at first\n\t\t\t * at each index we check if the text overlaps.\n\t\t\t *\n\t\t\t * Where it does, we store that angle and that index.\n\t\t\t *\n\t\t\t * After finding the largest index and angle we calculate how much we need to remove\n\t\t\t * from the shape radius to move the point inwards by that x.\n\t\t\t *\n\t\t\t * We average the left and right distances to get the maximum shape radius that can fit in the box\n\t\t\t * along with labels.\n\t\t\t *\n\t\t\t * Once we have that, we can find the centre point for the chart, by taking the x text protrusion\n\t\t\t * on each side, removing that from the size, halving it and adding the left x protrusion width.\n\t\t\t *\n\t\t\t * This will mean we have a shape fitted to the canvas, as large as it can be with the labels\n\t\t\t * and position it in the most space efficient manner\n\t\t\t *\n\t\t\t * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif\n\t\t\t */\n\n\n\t\t\t// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.\n\t\t\t// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points\n\t\t\tvar largestPossibleRadius = min([(this.height/2 - this.pointLabelFontSize - 5), this.width/2]),\n\t\t\t\tpointPosition,\n\t\t\t\ti,\n\t\t\t\ttextWidth,\n\t\t\t\thalfTextWidth,\n\t\t\t\tfurthestRight = this.width,\n\t\t\t\tfurthestRightIndex,\n\t\t\t\tfurthestRightAngle,\n\t\t\t\tfurthestLeft = 0,\n\t\t\t\tfurthestLeftIndex,\n\t\t\t\tfurthestLeftAngle,\n\t\t\t\txProtrusionLeft,\n\t\t\t\txProtrusionRight,\n\t\t\t\tradiusReductionRight,\n\t\t\t\tradiusReductionLeft,\n\t\t\t\tmaxWidthRadius;\n\t\t\tthis.ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);\n\t\t\tfor (i=0;i<this.valuesCount;i++){\n\t\t\t\t// 5px to space the text slightly out - similar to what we do in the draw function.\n\t\t\t\tpointPosition = this.getPointPosition(i, largestPossibleRadius);\n\t\t\t\ttextWidth = this.ctx.measureText(template(this.templateString, { value: this.labels[i] })).width + 5;\n\t\t\t\tif (i === 0 || i === this.valuesCount/2){\n\t\t\t\t\t// If we're at index zero, or exactly the middle, we're at exactly the top/bottom\n\t\t\t\t\t// of the radar chart, so text will be aligned centrally, so we'll half it and compare\n\t\t\t\t\t// w/left and right text sizes\n\t\t\t\t\thalfTextWidth = textWidth/2;\n\t\t\t\t\tif (pointPosition.x + halfTextWidth > furthestRight) {\n\t\t\t\t\t\tfurthestRight = pointPosition.x + halfTextWidth;\n\t\t\t\t\t\tfurthestRightIndex = i;\n\t\t\t\t\t}\n\t\t\t\t\tif (pointPosition.x - halfTextWidth < furthestLeft) {\n\t\t\t\t\t\tfurthestLeft = pointPosition.x - halfTextWidth;\n\t\t\t\t\t\tfurthestLeftIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (i < this.valuesCount/2) {\n\t\t\t\t\t// Less than half the values means we'll left align the text\n\t\t\t\t\tif (pointPosition.x + textWidth > furthestRight) {\n\t\t\t\t\t\tfurthestRight = pointPosition.x + textWidth;\n\t\t\t\t\t\tfurthestRightIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (i > this.valuesCount/2){\n\t\t\t\t\t// More than half the values means we'll right align the text\n\t\t\t\t\tif (pointPosition.x - textWidth < furthestLeft) {\n\t\t\t\t\t\tfurthestLeft = pointPosition.x - textWidth;\n\t\t\t\t\t\tfurthestLeftIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\txProtrusionLeft = furthestLeft;\n\n\t\t\txProtrusionRight = Math.ceil(furthestRight - this.width);\n\n\t\t\tfurthestRightAngle = this.getIndexAngle(furthestRightIndex);\n\n\t\t\tfurthestLeftAngle = this.getIndexAngle(furthestLeftIndex);\n\n\t\t\tradiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI/2);\n\n\t\t\tradiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI/2);\n\n\t\t\t// Ensure we actually need to reduce the size of the chart\n\t\t\tradiusReductionRight = (isNumber(radiusReductionRight)) ? radiusReductionRight : 0;\n\t\t\tradiusReductionLeft = (isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;\n\n\t\t\tthis.drawingArea = largestPossibleRadius - (radiusReductionLeft + radiusReductionRight)/2;\n\n\t\t\t//this.drawingArea = min([maxWidthRadius, (this.height - (2 * (this.pointLabelFontSize + 5)))/2])\n\t\t\tthis.setCenterPoint(radiusReductionLeft, radiusReductionRight);\n\n\t\t},\n\t\tsetCenterPoint: function(leftMovement, rightMovement){\n\n\t\t\tvar maxRight = this.width - rightMovement - this.drawingArea,\n\t\t\t\tmaxLeft = leftMovement + this.drawingArea;\n\n\t\t\tthis.xCenter = (maxLeft + maxRight)/2;\n\t\t\t// Always vertically in the centre as the text height doesn't change\n\t\t\tthis.yCenter = (this.height/2);\n\t\t},\n\n\t\tgetIndexAngle : function(index){\n\t\t\tvar angleMultiplier = (Math.PI * 2) / this.valuesCount;\n\t\t\t// Start from the top instead of right, so remove a quarter of the circle\n\n\t\t\treturn index * angleMultiplier - (Math.PI/2);\n\t\t},\n\t\tgetPointPosition : function(index, distanceFromCenter){\n\t\t\tvar thisAngle = this.getIndexAngle(index);\n\t\t\treturn {\n\t\t\t\tx : (Math.cos(thisAngle) * distanceFromCenter) + this.xCenter,\n\t\t\t\ty : (Math.sin(thisAngle) * distanceFromCenter) + this.yCenter\n\t\t\t};\n\t\t},\n\t\tdraw: function(){\n\t\t\tif (this.display){\n\t\t\t\tvar ctx = this.ctx;\n\t\t\t\teach(this.yLabels, function(label, index){\n\t\t\t\t\t// Don't draw a centre value\n\t\t\t\t\tif (index > 0){\n\t\t\t\t\t\tvar yCenterOffset = index * (this.drawingArea/this.steps),\n\t\t\t\t\t\t\tyHeight = this.yCenter - yCenterOffset,\n\t\t\t\t\t\t\tpointPosition;\n\n\t\t\t\t\t\t// Draw circular lines around the scale\n\t\t\t\t\t\tif (this.lineWidth > 0){\n\t\t\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\n\t\t\t\t\t\t\tif(this.lineArc){\n\t\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\t\tctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI*2);\n\t\t\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\t\t} else{\n\t\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\t\tfor (var i=0;i<this.valuesCount;i++)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tpointPosition = this.getPointPosition(i, this.calculateCenterOffset(this.min + (index * this.stepValue)));\n\t\t\t\t\t\t\t\t\tif (i === 0){\n\t\t\t\t\t\t\t\t\t\tctx.moveTo(pointPosition.x, pointPosition.y);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tctx.lineTo(pointPosition.x, pointPosition.y);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(this.showLabels){\n\t\t\t\t\t\t\tctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);\n\t\t\t\t\t\t\tif (this.showLabelBackdrop){\n\t\t\t\t\t\t\t\tvar labelWidth = ctx.measureText(label).width;\n\t\t\t\t\t\t\t\tctx.fillStyle = this.backdropColor;\n\t\t\t\t\t\t\t\tctx.fillRect(\n\t\t\t\t\t\t\t\t\tthis.xCenter - labelWidth/2 - this.backdropPaddingX,\n\t\t\t\t\t\t\t\t\tyHeight - this.fontSize/2 - this.backdropPaddingY,\n\t\t\t\t\t\t\t\t\tlabelWidth + this.backdropPaddingX*2,\n\t\t\t\t\t\t\t\t\tthis.fontSize + this.backdropPaddingY*2\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\t\t\t\tctx.fillStyle = this.fontColor;\n\t\t\t\t\t\t\tctx.fillText(label, this.xCenter, yHeight);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\n\t\t\t\tif (!this.lineArc){\n\t\t\t\t\tctx.lineWidth = this.angleLineWidth;\n\t\t\t\t\tctx.strokeStyle = this.angleLineColor;\n\t\t\t\t\tfor (var i = this.valuesCount - 1; i >= 0; i--) {\n\t\t\t\t\t\tif (this.angleLineWidth > 0){\n\t\t\t\t\t\t\tvar outerPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max));\n\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\tctx.moveTo(this.xCenter, this.yCenter);\n\t\t\t\t\t\t\tctx.lineTo(outerPosition.x, outerPosition.y);\n\t\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Extra 3px out for some label spacing\n\t\t\t\t\t\tvar pointLabelPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max) + 5);\n\t\t\t\t\t\tctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);\n\t\t\t\t\t\tctx.fillStyle = this.pointLabelFontColor;\n\n\t\t\t\t\t\tvar labelsCount = this.labels.length,\n\t\t\t\t\t\t\thalfLabelsCount = this.labels.length/2,\n\t\t\t\t\t\t\tquarterLabelsCount = halfLabelsCount/2,\n\t\t\t\t\t\t\tupperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),\n\t\t\t\t\t\t\texactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);\n\t\t\t\t\t\tif (i === 0){\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t} else if(i === halfLabelsCount){\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t} else if (i < halfLabelsCount){\n\t\t\t\t\t\t\tctx.textAlign = 'left';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tctx.textAlign = 'right';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Set the correct text baseline based on outer positioning\n\t\t\t\t\t\tif (exactQuarter){\n\t\t\t\t\t\t\tctx.textBaseline = 'middle';\n\t\t\t\t\t\t} else if (upperHalf){\n\t\t\t\t\t\t\tctx.textBaseline = 'bottom';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tctx.textBaseline = 'top';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tctx.fillText(this.labels[i], pointLabelPosition.x, pointLabelPosition.y);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\t// Attach global event to resize each chart instance when the browser resizes\n\thelpers.addEvent(window, \"resize\", (function(){\n\t\t// Basic debounce of resize function so it doesn't hurt performance when resizing browser.\n\t\tvar timeout;\n\t\treturn function(){\n\t\t\tclearTimeout(timeout);\n\t\t\ttimeout = setTimeout(function(){\n\t\t\t\teach(Chart.instances,function(instance){\n\t\t\t\t\t// If the responsive flag is set in the chart instance config\n\t\t\t\t\t// Cascade the resize event down to the chart.\n\t\t\t\t\tif (instance.options.responsive){\n\t\t\t\t\t\tinstance.resize(instance.render, true);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}, 50);\n\t\t};\n\t})());\n\n\n\tif (amd) {\n\t\tdefine(function(){\n\t\t\treturn Chart;\n\t\t});\n\t} else if (typeof module === 'object' && module.exports) {\n\t\tmodule.exports = Chart;\n\t}\n\n\troot.Chart = Chart;\n\n\tChart.noConflict = function(){\n\t\troot.Chart = previous;\n\t\treturn Chart;\n\t};\n\n}).call(this);\n\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\thelpers = Chart.helpers;\n\n\n\tvar defaultConfig = {\n\t\t//Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value\n\t\tscaleBeginAtZero : true,\n\n\t\t//Boolean - Whether grid lines are shown across the chart\n\t\tscaleShowGridLines : true,\n\n\t\t//String - Colour of the grid lines\n\t\tscaleGridLineColor : \"rgba(0,0,0,.05)\",\n\n\t\t//Number - Width of the grid lines\n\t\tscaleGridLineWidth : 1,\n\n\t\t//Boolean - Whether to show horizontal lines (except X axis)\n\t\tscaleShowHorizontalLines: true,\n\n\t\t//Boolean - Whether to show vertical lines (except Y axis)\n\t\tscaleShowVerticalLines: true,\n\n\t\t//Boolean - If there is a stroke on each bar\n\t\tbarShowStroke : true,\n\n\t\t//Number - Pixel width of the bar stroke\n\t\tbarStrokeWidth : 2,\n\n\t\t//Number - Spacing between each of the X value sets\n\t\tbarValueSpacing : 5,\n\n\t\t//Number - Spacing between data sets within X values\n\t\tbarDatasetSpacing : 1,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\\\"background-color:<%=datasets[i].fillColor%>\\\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>\"\n\n\t};\n\n\n\tChart.Type.extend({\n\t\tname: \"Bar\",\n\t\tdefaults : defaultConfig,\n\t\tinitialize:  function(data){\n\n\t\t\t//Expose options as a scope variable here so we can access it in the ScaleClass\n\t\t\tvar options = this.options;\n\n\t\t\tthis.ScaleClass = Chart.Scale.extend({\n\t\t\t\toffsetGridLines : true,\n\t\t\t\tcalculateBarX : function(datasetCount, datasetIndex, barIndex){\n\t\t\t\t\t//Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar\n\t\t\t\t\tvar xWidth = this.calculateBaseWidth(),\n\t\t\t\t\t\txAbsolute = this.calculateX(barIndex) - (xWidth/2),\n\t\t\t\t\t\tbarWidth = this.calculateBarWidth(datasetCount);\n\n\t\t\t\t\treturn xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2;\n\t\t\t\t},\n\t\t\t\tcalculateBaseWidth : function(){\n\t\t\t\t\treturn (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);\n\t\t\t\t},\n\t\t\t\tcalculateBarWidth : function(datasetCount){\n\t\t\t\t\t//The padding between datasets is to the right of each bar, providing that there are more than 1 dataset\n\t\t\t\t\tvar baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);\n\n\t\t\t\t\treturn (baseWidth / datasetCount);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.datasets = [];\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];\n\n\t\t\t\t\tthis.eachBars(function(bar){\n\t\t\t\t\t\tbar.restore(['fillColor', 'strokeColor']);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activeBars, function(activeBar){\n\t\t\t\t\t\tactiveBar.fillColor = activeBar.highlightFill;\n\t\t\t\t\t\tactiveBar.strokeColor = activeBar.highlightStroke;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activeBars);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t//Declare the extension of the default point, to cater for the options passed in to the constructor\n\t\t\tthis.BarClass = Chart.Rectangle.extend({\n\t\t\t\tstrokeWidth : this.options.barStrokeWidth,\n\t\t\t\tshowStroke : this.options.barShowStroke,\n\t\t\t\tctx : this.chart.ctx\n\t\t\t});\n\n\t\t\t//Iterate through each of the datasets, and build this into a property of the chart\n\t\t\thelpers.each(data.datasets,function(dataset,datasetIndex){\n\n\t\t\t\tvar datasetObject = {\n\t\t\t\t\tlabel : dataset.label || null,\n\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\tbars : []\n\t\t\t\t};\n\n\t\t\t\tthis.datasets.push(datasetObject);\n\n\t\t\t\thelpers.each(dataset.data,function(dataPoint,index){\n\t\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\t\tdatasetObject.bars.push(new this.BarClass({\n\t\t\t\t\t\tvalue : dataPoint,\n\t\t\t\t\t\tlabel : data.labels[index],\n\t\t\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\t\thighlightFill : dataset.highlightFill || dataset.fillColor,\n\t\t\t\t\t\thighlightStroke : dataset.highlightStroke || dataset.strokeColor\n\t\t\t\t\t}));\n\t\t\t\t},this);\n\n\t\t\t},this);\n\n\t\t\tthis.buildScale(data.labels);\n\n\t\t\tthis.BarClass.prototype.base = this.scale.endPoint;\n\n\t\t\tthis.eachBars(function(bar, index, datasetIndex){\n\t\t\t\thelpers.extend(bar, {\n\t\t\t\t\twidth : this.scale.calculateBarWidth(this.datasets.length),\n\t\t\t\t\tx: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),\n\t\t\t\t\ty: this.scale.endPoint\n\t\t\t\t});\n\t\t\t\tbar.save();\n\t\t\t}, this);\n\n\t\t\tthis.render();\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.scale.update();\n\t\t\t// Reset any highlight colours before updating.\n\t\t\thelpers.each(this.activeElements, function(activeElement){\n\t\t\t\tactiveElement.restore(['fillColor', 'strokeColor']);\n\t\t\t});\n\n\t\t\tthis.eachBars(function(bar){\n\t\t\t\tbar.save();\n\t\t\t});\n\t\t\tthis.render();\n\t\t},\n\t\teachBars : function(callback){\n\t\t\thelpers.each(this.datasets,function(dataset, datasetIndex){\n\t\t\t\thelpers.each(dataset.bars, callback, this, datasetIndex);\n\t\t\t},this);\n\t\t},\n\t\tgetBarsAtEvent : function(e){\n\t\t\tvar barsArray = [],\n\t\t\t\teventPosition = helpers.getRelativePosition(e),\n\t\t\t\tdatasetIterator = function(dataset){\n\t\t\t\t\tbarsArray.push(dataset.bars[barIndex]);\n\t\t\t\t},\n\t\t\t\tbarIndex;\n\n\t\t\tfor (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {\n\t\t\t\tfor (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {\n\t\t\t\t\tif (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){\n\t\t\t\t\t\thelpers.each(this.datasets, datasetIterator);\n\t\t\t\t\t\treturn barsArray;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn barsArray;\n\t\t},\n\t\tbuildScale : function(labels){\n\t\t\tvar self = this;\n\n\t\t\tvar dataTotal = function(){\n\t\t\t\tvar values = [];\n\t\t\t\tself.eachBars(function(bar){\n\t\t\t\t\tvalues.push(bar.value);\n\t\t\t\t});\n\t\t\t\treturn values;\n\t\t\t};\n\n\t\t\tvar scaleOptions = {\n\t\t\t\ttemplateString : this.options.scaleLabel,\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttextColor : this.options.scaleFontColor,\n\t\t\t\tfontSize : this.options.scaleFontSize,\n\t\t\t\tfontStyle : this.options.scaleFontStyle,\n\t\t\t\tfontFamily : this.options.scaleFontFamily,\n\t\t\t\tvaluesCount : labels.length,\n\t\t\t\tbeginAtZero : this.options.scaleBeginAtZero,\n\t\t\t\tintegersOnly : this.options.scaleIntegersOnly,\n\t\t\t\tcalculateYRange: function(currentHeight){\n\t\t\t\t\tvar updatedRanges = helpers.calculateScaleRange(\n\t\t\t\t\t\tdataTotal(),\n\t\t\t\t\t\tcurrentHeight,\n\t\t\t\t\t\tthis.fontSize,\n\t\t\t\t\t\tthis.beginAtZero,\n\t\t\t\t\t\tthis.integersOnly\n\t\t\t\t\t);\n\t\t\t\t\thelpers.extend(this, updatedRanges);\n\t\t\t\t},\n\t\t\t\txLabels : labels,\n\t\t\t\tfont : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),\n\t\t\t\tlineWidth : this.options.scaleLineWidth,\n\t\t\t\tlineColor : this.options.scaleLineColor,\n\t\t\t\tshowHorizontalLines : this.options.scaleShowHorizontalLines,\n\t\t\t\tshowVerticalLines : this.options.scaleShowVerticalLines,\n\t\t\t\tgridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,\n\t\t\t\tgridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : \"rgba(0,0,0,0)\",\n\t\t\t\tpadding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,\n\t\t\t\tshowLabels : this.options.scaleShowLabels,\n\t\t\t\tdisplay : this.options.showScale\n\t\t\t};\n\n\t\t\tif (this.options.scaleOverride){\n\t\t\t\thelpers.extend(scaleOptions, {\n\t\t\t\t\tcalculateYRange: helpers.noop,\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.scale = new this.ScaleClass(scaleOptions);\n\t\t},\n\t\taddData : function(valuesArray,label){\n\t\t\t//Map the values array for each of the datasets\n\t\t\thelpers.each(valuesArray,function(value,datasetIndex){\n\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\tthis.datasets[datasetIndex].bars.push(new this.BarClass({\n\t\t\t\t\tvalue : value,\n\t\t\t\t\tlabel : label,\n\t\t\t\t\tx: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),\n\t\t\t\t\ty: this.scale.endPoint,\n\t\t\t\t\twidth : this.scale.calculateBarWidth(this.datasets.length),\n\t\t\t\t\tbase : this.scale.endPoint,\n\t\t\t\t\tstrokeColor : this.datasets[datasetIndex].strokeColor,\n\t\t\t\t\tfillColor : this.datasets[datasetIndex].fillColor\n\t\t\t\t}));\n\t\t\t},this);\n\n\t\t\tthis.scale.addXLabel(label);\n\t\t\t//Then re-render the chart.\n\t\t\tthis.update();\n\t\t},\n\t\tremoveData : function(){\n\t\t\tthis.scale.removeXLabel();\n\t\t\t//Then re-render the chart.\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tdataset.bars.shift();\n\t\t\t},this);\n\t\t\tthis.update();\n\t\t},\n\t\treflow : function(){\n\t\t\thelpers.extend(this.BarClass.prototype,{\n\t\t\t\ty: this.scale.endPoint,\n\t\t\t\tbase : this.scale.endPoint\n\t\t\t});\n\t\t\tvar newScaleProps = helpers.extend({\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width\n\t\t\t});\n\t\t\tthis.scale.update(newScaleProps);\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easingDecimal = ease || 1;\n\t\t\tthis.clear();\n\n\t\t\tvar ctx = this.chart.ctx;\n\n\t\t\tthis.scale.draw(easingDecimal);\n\n\t\t\t//Draw all the bars for each dataset\n\t\t\thelpers.each(this.datasets,function(dataset,datasetIndex){\n\t\t\t\thelpers.each(dataset.bars,function(bar,index){\n\t\t\t\t\tif (bar.hasValue()){\n\t\t\t\t\t\tbar.base = this.scale.endPoint;\n\t\t\t\t\t\t//Transition then draw\n\t\t\t\t\t\tbar.transition({\n\t\t\t\t\t\t\tx : this.scale.calculateBarX(this.datasets.length, datasetIndex, index),\n\t\t\t\t\t\t\ty : this.scale.calculateY(bar.value),\n\t\t\t\t\t\t\twidth : this.scale.calculateBarWidth(this.datasets.length)\n\t\t\t\t\t\t}, easingDecimal).draw();\n\t\t\t\t\t}\n\t\t\t\t},this);\n\n\t\t\t},this);\n\t\t}\n\t});\n\n\n}).call(this);\n\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\t//Cache a local reference to Chart.helpers\n\t\thelpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\t//Boolean - Whether we should show a stroke on each segment\n\t\tsegmentShowStroke : true,\n\n\t\t//String - The colour of each segment stroke\n\t\tsegmentStrokeColor : \"#fff\",\n\n\t\t//Number - The width of each segment stroke\n\t\tsegmentStrokeWidth : 2,\n\n\t\t//The percentage of the chart that we cut out of the middle.\n\t\tpercentageInnerCutout : 50,\n\n\t\t//Number - Amount of animation steps\n\t\tanimationSteps : 100,\n\n\t\t//String - Animation easing effect\n\t\tanimationEasing : \"easeOutBounce\",\n\n\t\t//Boolean - Whether we animate the rotation of the Doughnut\n\t\tanimateRotate : true,\n\n\t\t//Boolean - Whether we animate scaling the Doughnut from the centre\n\t\tanimateScale : false,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<segments.length; i++){%><li><span style=\\\"background-color:<%=segments[i].fillColor%>\\\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>\"\n\n\t};\n\n\n\tChart.Type.extend({\n\t\t//Passing in a name registers this chart in the Chart namespace\n\t\tname: \"Doughnut\",\n\t\t//Providing a defaults will also register the deafults in the chart namespace\n\t\tdefaults : defaultConfig,\n\t\t//Initialize is fired when the chart is initialized - Data is passed in as a parameter\n\t\t//Config is automatically merged by the core of Chart.js, and is available at this.options\n\t\tinitialize:  function(data){\n\n\t\t\t//Declare segments as a static property to prevent inheriting across the Chart type prototype\n\t\t\tthis.segments = [];\n\t\t\tthis.outerRadius = (helpers.min([this.chart.width,this.chart.height]) -\tthis.options.segmentStrokeWidth/2)/2;\n\n\t\t\tthis.SegmentArc = Chart.Arc.extend({\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];\n\n\t\t\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\t\t\tsegment.restore([\"fillColor\"]);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activeSegments,function(activeSegment){\n\t\t\t\t\t\tactiveSegment.fillColor = activeSegment.highlightColor;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activeSegments);\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.calculateTotal(data);\n\n\t\t\thelpers.each(data,function(datapoint, index){\n\t\t\t\tthis.addData(datapoint, index, true);\n\t\t\t},this);\n\n\t\t\tthis.render();\n\t\t},\n\t\tgetSegmentsAtEvent : function(e){\n\t\t\tvar segmentsArray = [];\n\n\t\t\tvar location = helpers.getRelativePosition(e);\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tif (segment.inRange(location.x,location.y)) segmentsArray.push(segment);\n\t\t\t},this);\n\t\t\treturn segmentsArray;\n\t\t},\n\t\taddData : function(segment, atIndex, silent){\n\t\t\tvar index = atIndex || this.segments.length;\n\t\t\tthis.segments.splice(index, 0, new this.SegmentArc({\n\t\t\t\tvalue : segment.value,\n\t\t\t\touterRadius : (this.options.animateScale) ? 0 : this.outerRadius,\n\t\t\t\tinnerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout,\n\t\t\t\tfillColor : segment.color,\n\t\t\t\thighlightColor : segment.highlight || segment.color,\n\t\t\t\tshowStroke : this.options.segmentShowStroke,\n\t\t\t\tstrokeWidth : this.options.segmentStrokeWidth,\n\t\t\t\tstrokeColor : this.options.segmentStrokeColor,\n\t\t\t\tstartAngle : Math.PI * 1.5,\n\t\t\t\tcircumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value),\n\t\t\t\tlabel : segment.label\n\t\t\t}));\n\t\t\tif (!silent){\n\t\t\t\tthis.reflow();\n\t\t\t\tthis.update();\n\t\t\t}\n\t\t},\n\t\tcalculateCircumference : function(value){\n\t\t\treturn (Math.PI*2)*(Math.abs(value) / this.total);\n\t\t},\n\t\tcalculateTotal : function(data){\n\t\t\tthis.total = 0;\n\t\t\thelpers.each(data,function(segment){\n\t\t\t\tthis.total += Math.abs(segment.value);\n\t\t\t},this);\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.calculateTotal(this.segments);\n\n\t\t\t// Reset any highlight colours before updating.\n\t\t\thelpers.each(this.activeElements, function(activeElement){\n\t\t\t\tactiveElement.restore(['fillColor']);\n\t\t\t});\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tsegment.save();\n\t\t\t});\n\t\t\tthis.render();\n\t\t},\n\n\t\tremoveData: function(atIndex){\n\t\t\tvar indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;\n\t\t\tthis.segments.splice(indexToDelete, 1);\n\t\t\tthis.reflow();\n\t\t\tthis.update();\n\t\t},\n\n\t\treflow : function(){\n\t\t\thelpers.extend(this.SegmentArc.prototype,{\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\t\t\tthis.outerRadius = (helpers.min([this.chart.width,this.chart.height]) -\tthis.options.segmentStrokeWidth/2)/2;\n\t\t\thelpers.each(this.segments, function(segment){\n\t\t\t\tsegment.update({\n\t\t\t\t\touterRadius : this.outerRadius,\n\t\t\t\t\tinnerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout\n\t\t\t\t});\n\t\t\t}, this);\n\t\t},\n\t\tdraw : function(easeDecimal){\n\t\t\tvar animDecimal = (easeDecimal) ? easeDecimal : 1;\n\t\t\tthis.clear();\n\t\t\thelpers.each(this.segments,function(segment,index){\n\t\t\t\tsegment.transition({\n\t\t\t\t\tcircumference : this.calculateCircumference(segment.value),\n\t\t\t\t\touterRadius : this.outerRadius,\n\t\t\t\t\tinnerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout\n\t\t\t\t},animDecimal);\n\n\t\t\t\tsegment.endAngle = segment.startAngle + segment.circumference;\n\n\t\t\t\tsegment.draw();\n\t\t\t\tif (index === 0){\n\t\t\t\t\tsegment.startAngle = Math.PI * 1.5;\n\t\t\t\t}\n\t\t\t\t//Check to see if it's the last segment, if not get the next and update the start angle\n\t\t\t\tif (index < this.segments.length-1){\n\t\t\t\t\tthis.segments[index+1].startAngle = segment.endAngle;\n\t\t\t\t}\n\t\t\t},this);\n\n\t\t}\n\t});\n\n\tChart.types.Doughnut.extend({\n\t\tname : \"Pie\",\n\t\tdefaults : helpers.merge(defaultConfig,{percentageInnerCutout : 0})\n\t});\n\n}).call(this);\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\thelpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\n\t\t///Boolean - Whether grid lines are shown across the chart\n\t\tscaleShowGridLines : true,\n\n\t\t//String - Colour of the grid lines\n\t\tscaleGridLineColor : \"rgba(0,0,0,.05)\",\n\n\t\t//Number - Width of the grid lines\n\t\tscaleGridLineWidth : 1,\n\n\t\t//Boolean - Whether to show horizontal lines (except X axis)\n\t\tscaleShowHorizontalLines: true,\n\n\t\t//Boolean - Whether to show vertical lines (except Y axis)\n\t\tscaleShowVerticalLines: true,\n\n\t\t//Boolean - Whether the line is curved between points\n\t\tbezierCurve : true,\n\n\t\t//Number - Tension of the bezier curve between points\n\t\tbezierCurveTension : 0.4,\n\n\t\t//Boolean - Whether to show a dot for each point\n\t\tpointDot : true,\n\n\t\t//Number - Radius of each point dot in pixels\n\t\tpointDotRadius : 4,\n\n\t\t//Number - Pixel width of point dot stroke\n\t\tpointDotStrokeWidth : 1,\n\n\t\t//Number - amount extra to add to the radius to cater for hit detection outside the drawn point\n\t\tpointHitDetectionRadius : 20,\n\n\t\t//Boolean - Whether to show a stroke for datasets\n\t\tdatasetStroke : true,\n\n\t\t//Number - Pixel width of dataset stroke\n\t\tdatasetStrokeWidth : 2,\n\n\t\t//Boolean - Whether to fill the dataset with a colour\n\t\tdatasetFill : true,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\\\"background-color:<%=datasets[i].strokeColor%>\\\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>\"\n\n\t};\n\n\n\tChart.Type.extend({\n\t\tname: \"Line\",\n\t\tdefaults : defaultConfig,\n\t\tinitialize:  function(data){\n\t\t\t//Declare the extension of the default point, to cater for the options passed in to the constructor\n\t\t\tthis.PointClass = Chart.Point.extend({\n\t\t\t\tstrokeWidth : this.options.pointDotStrokeWidth,\n\t\t\t\tradius : this.options.pointDotRadius,\n\t\t\t\tdisplay: this.options.pointDot,\n\t\t\t\thitDetectionRadius : this.options.pointHitDetectionRadius,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\tinRange : function(mouseX){\n\t\t\t\t\treturn (Math.pow(mouseX-this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius,2));\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.datasets = [];\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];\n\t\t\t\t\tthis.eachPoints(function(point){\n\t\t\t\t\t\tpoint.restore(['fillColor', 'strokeColor']);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activePoints, function(activePoint){\n\t\t\t\t\t\tactivePoint.fillColor = activePoint.highlightFill;\n\t\t\t\t\t\tactivePoint.strokeColor = activePoint.highlightStroke;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activePoints);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t//Iterate through each of the datasets, and build this into a property of the chart\n\t\t\thelpers.each(data.datasets,function(dataset){\n\n\t\t\t\tvar datasetObject = {\n\t\t\t\t\tlabel : dataset.label || null,\n\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\tpointColor : dataset.pointColor,\n\t\t\t\t\tpointStrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\tpoints : []\n\t\t\t\t};\n\n\t\t\t\tthis.datasets.push(datasetObject);\n\n\n\t\t\t\thelpers.each(dataset.data,function(dataPoint,index){\n\t\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\t\tdatasetObject.points.push(new this.PointClass({\n\t\t\t\t\t\tvalue : dataPoint,\n\t\t\t\t\t\tlabel : data.labels[index],\n\t\t\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\t\t\tstrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\t\tfillColor : dataset.pointColor,\n\t\t\t\t\t\thighlightFill : dataset.pointHighlightFill || dataset.pointColor,\n\t\t\t\t\t\thighlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor\n\t\t\t\t\t}));\n\t\t\t\t},this);\n\n\t\t\t\tthis.buildScale(data.labels);\n\n\n\t\t\t\tthis.eachPoints(function(point, index){\n\t\t\t\t\thelpers.extend(point, {\n\t\t\t\t\t\tx: this.scale.calculateX(index),\n\t\t\t\t\t\ty: this.scale.endPoint\n\t\t\t\t\t});\n\t\t\t\t\tpoint.save();\n\t\t\t\t}, this);\n\n\t\t\t},this);\n\n\n\t\t\tthis.render();\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.scale.update();\n\t\t\t// Reset any highlight colours before updating.\n\t\t\thelpers.each(this.activeElements, function(activeElement){\n\t\t\t\tactiveElement.restore(['fillColor', 'strokeColor']);\n\t\t\t});\n\t\t\tthis.eachPoints(function(point){\n\t\t\t\tpoint.save();\n\t\t\t});\n\t\t\tthis.render();\n\t\t},\n\t\teachPoints : function(callback){\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\thelpers.each(dataset.points,callback,this);\n\t\t\t},this);\n\t\t},\n\t\tgetPointsAtEvent : function(e){\n\t\t\tvar pointsArray = [],\n\t\t\t\teventPosition = helpers.getRelativePosition(e);\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\thelpers.each(dataset.points,function(point){\n\t\t\t\t\tif (point.inRange(eventPosition.x,eventPosition.y)) pointsArray.push(point);\n\t\t\t\t});\n\t\t\t},this);\n\t\t\treturn pointsArray;\n\t\t},\n\t\tbuildScale : function(labels){\n\t\t\tvar self = this;\n\n\t\t\tvar dataTotal = function(){\n\t\t\t\tvar values = [];\n\t\t\t\tself.eachPoints(function(point){\n\t\t\t\t\tvalues.push(point.value);\n\t\t\t\t});\n\n\t\t\t\treturn values;\n\t\t\t};\n\n\t\t\tvar scaleOptions = {\n\t\t\t\ttemplateString : this.options.scaleLabel,\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttextColor : this.options.scaleFontColor,\n\t\t\t\tfontSize : this.options.scaleFontSize,\n\t\t\t\tfontStyle : this.options.scaleFontStyle,\n\t\t\t\tfontFamily : this.options.scaleFontFamily,\n\t\t\t\tvaluesCount : labels.length,\n\t\t\t\tbeginAtZero : this.options.scaleBeginAtZero,\n\t\t\t\tintegersOnly : this.options.scaleIntegersOnly,\n\t\t\t\tcalculateYRange : function(currentHeight){\n\t\t\t\t\tvar updatedRanges = helpers.calculateScaleRange(\n\t\t\t\t\t\tdataTotal(),\n\t\t\t\t\t\tcurrentHeight,\n\t\t\t\t\t\tthis.fontSize,\n\t\t\t\t\t\tthis.beginAtZero,\n\t\t\t\t\t\tthis.integersOnly\n\t\t\t\t\t);\n\t\t\t\t\thelpers.extend(this, updatedRanges);\n\t\t\t\t},\n\t\t\t\txLabels : labels,\n\t\t\t\tfont : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),\n\t\t\t\tlineWidth : this.options.scaleLineWidth,\n\t\t\t\tlineColor : this.options.scaleLineColor,\n\t\t\t\tshowHorizontalLines : this.options.scaleShowHorizontalLines,\n\t\t\t\tshowVerticalLines : this.options.scaleShowVerticalLines,\n\t\t\t\tgridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,\n\t\t\t\tgridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : \"rgba(0,0,0,0)\",\n\t\t\t\tpadding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,\n\t\t\t\tshowLabels : this.options.scaleShowLabels,\n\t\t\t\tdisplay : this.options.showScale\n\t\t\t};\n\n\t\t\tif (this.options.scaleOverride){\n\t\t\t\thelpers.extend(scaleOptions, {\n\t\t\t\t\tcalculateYRange: helpers.noop,\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t});\n\t\t\t}\n\n\n\t\t\tthis.scale = new Chart.Scale(scaleOptions);\n\t\t},\n\t\taddData : function(valuesArray,label){\n\t\t\t//Map the values array for each of the datasets\n\n\t\t\thelpers.each(valuesArray,function(value,datasetIndex){\n\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\tthis.datasets[datasetIndex].points.push(new this.PointClass({\n\t\t\t\t\tvalue : value,\n\t\t\t\t\tlabel : label,\n\t\t\t\t\tx: this.scale.calculateX(this.scale.valuesCount+1),\n\t\t\t\t\ty: this.scale.endPoint,\n\t\t\t\t\tstrokeColor : this.datasets[datasetIndex].pointStrokeColor,\n\t\t\t\t\tfillColor : this.datasets[datasetIndex].pointColor\n\t\t\t\t}));\n\t\t\t},this);\n\n\t\t\tthis.scale.addXLabel(label);\n\t\t\t//Then re-render the chart.\n\t\t\tthis.update();\n\t\t},\n\t\tremoveData : function(){\n\t\t\tthis.scale.removeXLabel();\n\t\t\t//Then re-render the chart.\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tdataset.points.shift();\n\t\t\t},this);\n\t\t\tthis.update();\n\t\t},\n\t\treflow : function(){\n\t\t\tvar newScaleProps = helpers.extend({\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width\n\t\t\t});\n\t\t\tthis.scale.update(newScaleProps);\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easingDecimal = ease || 1;\n\t\t\tthis.clear();\n\n\t\t\tvar ctx = this.chart.ctx;\n\n\t\t\t// Some helper methods for getting the next/prev points\n\t\t\tvar hasValue = function(item){\n\t\t\t\treturn item.value !== null;\n\t\t\t},\n\t\t\tnextPoint = function(point, collection, index){\n\t\t\t\treturn helpers.findNextWhere(collection, hasValue, index) || point;\n\t\t\t},\n\t\t\tpreviousPoint = function(point, collection, index){\n\t\t\t\treturn helpers.findPreviousWhere(collection, hasValue, index) || point;\n\t\t\t};\n\n\t\t\tthis.scale.draw(easingDecimal);\n\n\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tvar pointsWithValues = helpers.where(dataset.points, hasValue);\n\n\t\t\t\t//Transition each point first so that the line and point drawing isn't out of sync\n\t\t\t\t//We can use this extra loop to calculate the control points of this dataset also in this loop\n\n\t\t\t\thelpers.each(dataset.points, function(point, index){\n\t\t\t\t\tif (point.hasValue()){\n\t\t\t\t\t\tpoint.transition({\n\t\t\t\t\t\t\ty : this.scale.calculateY(point.value),\n\t\t\t\t\t\t\tx : this.scale.calculateX(index)\n\t\t\t\t\t\t}, easingDecimal);\n\t\t\t\t\t}\n\t\t\t\t},this);\n\n\n\t\t\t\t// Control points need to be calculated in a seperate loop, because we need to know the current x/y of the point\n\t\t\t\t// This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed\n\t\t\t\tif (this.options.bezierCurve){\n\t\t\t\t\thelpers.each(pointsWithValues, function(point, index){\n\t\t\t\t\t\tvar tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0;\n\t\t\t\t\t\tpoint.controlPoints = helpers.splineCurve(\n\t\t\t\t\t\t\tpreviousPoint(point, pointsWithValues, index),\n\t\t\t\t\t\t\tpoint,\n\t\t\t\t\t\t\tnextPoint(point, pointsWithValues, index),\n\t\t\t\t\t\t\ttension\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// Prevent the bezier going outside of the bounds of the graph\n\n\t\t\t\t\t\t// Cap puter bezier handles to the upper/lower scale bounds\n\t\t\t\t\t\tif (point.controlPoints.outer.y > this.scale.endPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.outer.y = this.scale.endPoint;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (point.controlPoints.outer.y < this.scale.startPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.outer.y = this.scale.startPoint;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Cap inner bezier handles to the upper/lower scale bounds\n\t\t\t\t\t\tif (point.controlPoints.inner.y > this.scale.endPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.inner.y = this.scale.endPoint;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (point.controlPoints.inner.y < this.scale.startPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.inner.y = this.scale.startPoint;\n\t\t\t\t\t\t}\n\t\t\t\t\t},this);\n\t\t\t\t}\n\n\n\t\t\t\t//Draw the line between all the points\n\t\t\t\tctx.lineWidth = this.options.datasetStrokeWidth;\n\t\t\t\tctx.strokeStyle = dataset.strokeColor;\n\t\t\t\tctx.beginPath();\n\n\t\t\t\thelpers.each(pointsWithValues, function(point, index){\n\t\t\t\t\tif (index === 0){\n\t\t\t\t\t\tctx.moveTo(point.x, point.y);\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\tif(this.options.bezierCurve){\n\t\t\t\t\t\t\tvar previous = previousPoint(point, pointsWithValues, index);\n\n\t\t\t\t\t\t\tctx.bezierCurveTo(\n\t\t\t\t\t\t\t\tprevious.controlPoints.outer.x,\n\t\t\t\t\t\t\t\tprevious.controlPoints.outer.y,\n\t\t\t\t\t\t\t\tpoint.controlPoints.inner.x,\n\t\t\t\t\t\t\t\tpoint.controlPoints.inner.y,\n\t\t\t\t\t\t\t\tpoint.x,\n\t\t\t\t\t\t\t\tpoint.y\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\tctx.lineTo(point.x,point.y);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\n\t\t\t\tctx.stroke();\n\n\t\t\t\tif (this.options.datasetFill && pointsWithValues.length > 0){\n\t\t\t\t\t//Round off the line by going to the base of the chart, back to the start, then fill.\n\t\t\t\t\tctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint);\n\t\t\t\t\tctx.lineTo(pointsWithValues[0].x, this.scale.endPoint);\n\t\t\t\t\tctx.fillStyle = dataset.fillColor;\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tctx.fill();\n\t\t\t\t}\n\n\t\t\t\t//Now draw the points over the line\n\t\t\t\t//A little inefficient double looping, but better than the line\n\t\t\t\t//lagging behind the point positions\n\t\t\t\thelpers.each(pointsWithValues,function(point){\n\t\t\t\t\tpoint.draw();\n\t\t\t\t});\n\t\t\t},this);\n\t\t}\n\t});\n\n\n}).call(this);\n\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\t//Cache a local reference to Chart.helpers\n\t\thelpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\t//Boolean - Show a backdrop to the scale label\n\t\tscaleShowLabelBackdrop : true,\n\n\t\t//String - The colour of the label backdrop\n\t\tscaleBackdropColor : \"rgba(255,255,255,0.75)\",\n\n\t\t// Boolean - Whether the scale should begin at zero\n\t\tscaleBeginAtZero : true,\n\n\t\t//Number - The backdrop padding above & below the label in pixels\n\t\tscaleBackdropPaddingY : 2,\n\n\t\t//Number - The backdrop padding to the side of the label in pixels\n\t\tscaleBackdropPaddingX : 2,\n\n\t\t//Boolean - Show line for each value in the scale\n\t\tscaleShowLine : true,\n\n\t\t//Boolean - Stroke a line around each segment in the chart\n\t\tsegmentShowStroke : true,\n\n\t\t//String - The colour of the stroke on each segement.\n\t\tsegmentStrokeColor : \"#fff\",\n\n\t\t//Number - The width of the stroke value in pixels\n\t\tsegmentStrokeWidth : 2,\n\n\t\t//Number - Amount of animation steps\n\t\tanimationSteps : 100,\n\n\t\t//String - Animation easing effect.\n\t\tanimationEasing : \"easeOutBounce\",\n\n\t\t//Boolean - Whether to animate the rotation of the chart\n\t\tanimateRotate : true,\n\n\t\t//Boolean - Whether to animate scaling the chart from the centre\n\t\tanimateScale : false,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<segments.length; i++){%><li><span style=\\\"background-color:<%=segments[i].fillColor%>\\\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>\"\n\t};\n\n\n\tChart.Type.extend({\n\t\t//Passing in a name registers this chart in the Chart namespace\n\t\tname: \"PolarArea\",\n\t\t//Providing a defaults will also register the deafults in the chart namespace\n\t\tdefaults : defaultConfig,\n\t\t//Initialize is fired when the chart is initialized - Data is passed in as a parameter\n\t\t//Config is automatically merged by the core of Chart.js, and is available at this.options\n\t\tinitialize:  function(data){\n\t\t\tthis.segments = [];\n\t\t\t//Declare segment class as a chart instance specific class, so it can share props for this instance\n\t\t\tthis.SegmentArc = Chart.Arc.extend({\n\t\t\t\tshowStroke : this.options.segmentShowStroke,\n\t\t\t\tstrokeWidth : this.options.segmentStrokeWidth,\n\t\t\t\tstrokeColor : this.options.segmentStrokeColor,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\tinnerRadius : 0,\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\t\t\tthis.scale = new Chart.RadialScale({\n\t\t\t\tdisplay: this.options.showScale,\n\t\t\t\tfontStyle: this.options.scaleFontStyle,\n\t\t\t\tfontSize: this.options.scaleFontSize,\n\t\t\t\tfontFamily: this.options.scaleFontFamily,\n\t\t\t\tfontColor: this.options.scaleFontColor,\n\t\t\t\tshowLabels: this.options.scaleShowLabels,\n\t\t\t\tshowLabelBackdrop: this.options.scaleShowLabelBackdrop,\n\t\t\t\tbackdropColor: this.options.scaleBackdropColor,\n\t\t\t\tbackdropPaddingY : this.options.scaleBackdropPaddingY,\n\t\t\t\tbackdropPaddingX: this.options.scaleBackdropPaddingX,\n\t\t\t\tlineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,\n\t\t\t\tlineColor: this.options.scaleLineColor,\n\t\t\t\tlineArc: true,\n\t\t\t\twidth: this.chart.width,\n\t\t\t\theight: this.chart.height,\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttemplateString: this.options.scaleLabel,\n\t\t\t\tvaluesCount: data.length\n\t\t\t});\n\n\t\t\tthis.updateScaleRange(data);\n\n\t\t\tthis.scale.update();\n\n\t\t\thelpers.each(data,function(segment,index){\n\t\t\t\tthis.addData(segment,index,true);\n\t\t\t},this);\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];\n\t\t\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\t\t\tsegment.restore([\"fillColor\"]);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activeSegments,function(activeSegment){\n\t\t\t\t\t\tactiveSegment.fillColor = activeSegment.highlightColor;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activeSegments);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.render();\n\t\t},\n\t\tgetSegmentsAtEvent : function(e){\n\t\t\tvar segmentsArray = [];\n\n\t\t\tvar location = helpers.getRelativePosition(e);\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tif (segment.inRange(location.x,location.y)) segmentsArray.push(segment);\n\t\t\t},this);\n\t\t\treturn segmentsArray;\n\t\t},\n\t\taddData : function(segment, atIndex, silent){\n\t\t\tvar index = atIndex || this.segments.length;\n\n\t\t\tthis.segments.splice(index, 0, new this.SegmentArc({\n\t\t\t\tfillColor: segment.color,\n\t\t\t\thighlightColor: segment.highlight || segment.color,\n\t\t\t\tlabel: segment.label,\n\t\t\t\tvalue: segment.value,\n\t\t\t\touterRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),\n\t\t\t\tcircumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),\n\t\t\t\tstartAngle: Math.PI * 1.5\n\t\t\t}));\n\t\t\tif (!silent){\n\t\t\t\tthis.reflow();\n\t\t\t\tthis.update();\n\t\t\t}\n\t\t},\n\t\tremoveData: function(atIndex){\n\t\t\tvar indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;\n\t\t\tthis.segments.splice(indexToDelete, 1);\n\t\t\tthis.reflow();\n\t\t\tthis.update();\n\t\t},\n\t\tcalculateTotal: function(data){\n\t\t\tthis.total = 0;\n\t\t\thelpers.each(data,function(segment){\n\t\t\t\tthis.total += segment.value;\n\t\t\t},this);\n\t\t\tthis.scale.valuesCount = this.segments.length;\n\t\t},\n\t\tupdateScaleRange: function(datapoints){\n\t\t\tvar valuesArray = [];\n\t\t\thelpers.each(datapoints,function(segment){\n\t\t\t\tvaluesArray.push(segment.value);\n\t\t\t});\n\n\t\t\tvar scaleSizes = (this.options.scaleOverride) ?\n\t\t\t\t{\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t} :\n\t\t\t\thelpers.calculateScaleRange(\n\t\t\t\t\tvaluesArray,\n\t\t\t\t\thelpers.min([this.chart.width, this.chart.height])/2,\n\t\t\t\t\tthis.options.scaleFontSize,\n\t\t\t\t\tthis.options.scaleBeginAtZero,\n\t\t\t\t\tthis.options.scaleIntegersOnly\n\t\t\t\t);\n\n\t\t\thelpers.extend(\n\t\t\t\tthis.scale,\n\t\t\t\tscaleSizes,\n\t\t\t\t{\n\t\t\t\t\tsize: helpers.min([this.chart.width, this.chart.height]),\n\t\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\t\tyCenter: this.chart.height/2\n\t\t\t\t}\n\t\t\t);\n\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.calculateTotal(this.segments);\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tsegment.save();\n\t\t\t});\n\t\t\t\n\t\t\tthis.reflow();\n\t\t\tthis.render();\n\t\t},\n\t\treflow : function(){\n\t\t\thelpers.extend(this.SegmentArc.prototype,{\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\t\t\tthis.updateScaleRange(this.segments);\n\t\t\tthis.scale.update();\n\n\t\t\thelpers.extend(this.scale,{\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2\n\t\t\t});\n\n\t\t\thelpers.each(this.segments, function(segment){\n\t\t\t\tsegment.update({\n\t\t\t\t\touterRadius : this.scale.calculateCenterOffset(segment.value)\n\t\t\t\t});\n\t\t\t}, this);\n\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easingDecimal = ease || 1;\n\t\t\t//Clear & draw the canvas\n\t\t\tthis.clear();\n\t\t\thelpers.each(this.segments,function(segment, index){\n\t\t\t\tsegment.transition({\n\t\t\t\t\tcircumference : this.scale.getCircumference(),\n\t\t\t\t\touterRadius : this.scale.calculateCenterOffset(segment.value)\n\t\t\t\t},easingDecimal);\n\n\t\t\t\tsegment.endAngle = segment.startAngle + segment.circumference;\n\n\t\t\t\t// If we've removed the first segment we need to set the first one to\n\t\t\t\t// start at the top.\n\t\t\t\tif (index === 0){\n\t\t\t\t\tsegment.startAngle = Math.PI * 1.5;\n\t\t\t\t}\n\n\t\t\t\t//Check to see if it's the last segment, if not get the next and update the start angle\n\t\t\t\tif (index < this.segments.length - 1){\n\t\t\t\t\tthis.segments[index+1].startAngle = segment.endAngle;\n\t\t\t\t}\n\t\t\t\tsegment.draw();\n\t\t\t}, this);\n\t\t\tthis.scale.draw();\n\t\t}\n\t});\n\n}).call(this);\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\thelpers = Chart.helpers;\n\n\n\n\tChart.Type.extend({\n\t\tname: \"Radar\",\n\t\tdefaults:{\n\t\t\t//Boolean - Whether to show lines for each scale point\n\t\t\tscaleShowLine : true,\n\n\t\t\t//Boolean - Whether we show the angle lines out of the radar\n\t\t\tangleShowLineOut : true,\n\n\t\t\t//Boolean - Whether to show labels on the scale\n\t\t\tscaleShowLabels : false,\n\n\t\t\t// Boolean - Whether the scale should begin at zero\n\t\t\tscaleBeginAtZero : true,\n\n\t\t\t//String - Colour of the angle line\n\t\t\tangleLineColor : \"rgba(0,0,0,.1)\",\n\n\t\t\t//Number - Pixel width of the angle line\n\t\t\tangleLineWidth : 1,\n\n\t\t\t//String - Point label font declaration\n\t\t\tpointLabelFontFamily : \"'Arial'\",\n\n\t\t\t//String - Point label font weight\n\t\t\tpointLabelFontStyle : \"normal\",\n\n\t\t\t//Number - Point label font size in pixels\n\t\t\tpointLabelFontSize : 10,\n\n\t\t\t//String - Point label font colour\n\t\t\tpointLabelFontColor : \"#666\",\n\n\t\t\t//Boolean - Whether to show a dot for each point\n\t\t\tpointDot : true,\n\n\t\t\t//Number - Radius of each point dot in pixels\n\t\t\tpointDotRadius : 3,\n\n\t\t\t//Number - Pixel width of point dot stroke\n\t\t\tpointDotStrokeWidth : 1,\n\n\t\t\t//Number - amount extra to add to the radius to cater for hit detection outside the drawn point\n\t\t\tpointHitDetectionRadius : 20,\n\n\t\t\t//Boolean - Whether to show a stroke for datasets\n\t\t\tdatasetStroke : true,\n\n\t\t\t//Number - Pixel width of dataset stroke\n\t\t\tdatasetStrokeWidth : 2,\n\n\t\t\t//Boolean - Whether to fill the dataset with a colour\n\t\t\tdatasetFill : true,\n\n\t\t\t//String - A legend template\n\t\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\\\"background-color:<%=datasets[i].strokeColor%>\\\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>\"\n\n\t\t},\n\n\t\tinitialize: function(data){\n\t\t\tthis.PointClass = Chart.Point.extend({\n\t\t\t\tstrokeWidth : this.options.pointDotStrokeWidth,\n\t\t\t\tradius : this.options.pointDotRadius,\n\t\t\t\tdisplay: this.options.pointDot,\n\t\t\t\thitDetectionRadius : this.options.pointHitDetectionRadius,\n\t\t\t\tctx : this.chart.ctx\n\t\t\t});\n\n\t\t\tthis.datasets = [];\n\n\t\t\tthis.buildScale(data);\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activePointsCollection = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];\n\n\t\t\t\t\tthis.eachPoints(function(point){\n\t\t\t\t\t\tpoint.restore(['fillColor', 'strokeColor']);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activePointsCollection, function(activePoint){\n\t\t\t\t\t\tactivePoint.fillColor = activePoint.highlightFill;\n\t\t\t\t\t\tactivePoint.strokeColor = activePoint.highlightStroke;\n\t\t\t\t\t});\n\n\t\t\t\t\tthis.showTooltip(activePointsCollection);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t//Iterate through each of the datasets, and build this into a property of the chart\n\t\t\thelpers.each(data.datasets,function(dataset){\n\n\t\t\t\tvar datasetObject = {\n\t\t\t\t\tlabel: dataset.label || null,\n\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\tpointColor : dataset.pointColor,\n\t\t\t\t\tpointStrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\tpoints : []\n\t\t\t\t};\n\n\t\t\t\tthis.datasets.push(datasetObject);\n\n\t\t\t\thelpers.each(dataset.data,function(dataPoint,index){\n\t\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\t\tvar pointPosition;\n\t\t\t\t\tif (!this.scale.animation){\n\t\t\t\t\t\tpointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint));\n\t\t\t\t\t}\n\t\t\t\t\tdatasetObject.points.push(new this.PointClass({\n\t\t\t\t\t\tvalue : dataPoint,\n\t\t\t\t\t\tlabel : data.labels[index],\n\t\t\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\t\t\tx: (this.options.animation) ? this.scale.xCenter : pointPosition.x,\n\t\t\t\t\t\ty: (this.options.animation) ? this.scale.yCenter : pointPosition.y,\n\t\t\t\t\t\tstrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\t\tfillColor : dataset.pointColor,\n\t\t\t\t\t\thighlightFill : dataset.pointHighlightFill || dataset.pointColor,\n\t\t\t\t\t\thighlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor\n\t\t\t\t\t}));\n\t\t\t\t},this);\n\n\t\t\t},this);\n\n\t\t\tthis.render();\n\t\t},\n\t\teachPoints : function(callback){\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\thelpers.each(dataset.points,callback,this);\n\t\t\t},this);\n\t\t},\n\n\t\tgetPointsAtEvent : function(evt){\n\t\t\tvar mousePosition = helpers.getRelativePosition(evt),\n\t\t\t\tfromCenter = helpers.getAngleFromPoint({\n\t\t\t\t\tx: this.scale.xCenter,\n\t\t\t\t\ty: this.scale.yCenter\n\t\t\t\t}, mousePosition);\n\n\t\t\tvar anglePerIndex = (Math.PI * 2) /this.scale.valuesCount,\n\t\t\t\tpointIndex = Math.round((fromCenter.angle - Math.PI * 1.5) / anglePerIndex),\n\t\t\t\tactivePointsCollection = [];\n\n\t\t\t// If we're at the top, make the pointIndex 0 to get the first of the array.\n\t\t\tif (pointIndex >= this.scale.valuesCount || pointIndex < 0){\n\t\t\t\tpointIndex = 0;\n\t\t\t}\n\n\t\t\tif (fromCenter.distance <= this.scale.drawingArea){\n\t\t\t\thelpers.each(this.datasets, function(dataset){\n\t\t\t\t\tactivePointsCollection.push(dataset.points[pointIndex]);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn activePointsCollection;\n\t\t},\n\n\t\tbuildScale : function(data){\n\t\t\tthis.scale = new Chart.RadialScale({\n\t\t\t\tdisplay: this.options.showScale,\n\t\t\t\tfontStyle: this.options.scaleFontStyle,\n\t\t\t\tfontSize: this.options.scaleFontSize,\n\t\t\t\tfontFamily: this.options.scaleFontFamily,\n\t\t\t\tfontColor: this.options.scaleFontColor,\n\t\t\t\tshowLabels: this.options.scaleShowLabels,\n\t\t\t\tshowLabelBackdrop: this.options.scaleShowLabelBackdrop,\n\t\t\t\tbackdropColor: this.options.scaleBackdropColor,\n\t\t\t\tbackdropPaddingY : this.options.scaleBackdropPaddingY,\n\t\t\t\tbackdropPaddingX: this.options.scaleBackdropPaddingX,\n\t\t\t\tlineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,\n\t\t\t\tlineColor: this.options.scaleLineColor,\n\t\t\t\tangleLineColor : this.options.angleLineColor,\n\t\t\t\tangleLineWidth : (this.options.angleShowLineOut) ? this.options.angleLineWidth : 0,\n\t\t\t\t// Point labels at the edge of each line\n\t\t\t\tpointLabelFontColor : this.options.pointLabelFontColor,\n\t\t\t\tpointLabelFontSize : this.options.pointLabelFontSize,\n\t\t\t\tpointLabelFontFamily : this.options.pointLabelFontFamily,\n\t\t\t\tpointLabelFontStyle : this.options.pointLabelFontStyle,\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth: this.chart.width,\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttemplateString: this.options.scaleLabel,\n\t\t\t\tlabels: data.labels,\n\t\t\t\tvaluesCount: data.datasets[0].data.length\n\t\t\t});\n\n\t\t\tthis.scale.setScaleSize();\n\t\t\tthis.updateScaleRange(data.datasets);\n\t\t\tthis.scale.buildYLabels();\n\t\t},\n\t\tupdateScaleRange: function(datasets){\n\t\t\tvar valuesArray = (function(){\n\t\t\t\tvar totalDataArray = [];\n\t\t\t\thelpers.each(datasets,function(dataset){\n\t\t\t\t\tif (dataset.data){\n\t\t\t\t\t\ttotalDataArray = totalDataArray.concat(dataset.data);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\thelpers.each(dataset.points, function(point){\n\t\t\t\t\t\t\ttotalDataArray.push(point.value);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn totalDataArray;\n\t\t\t})();\n\n\n\t\t\tvar scaleSizes = (this.options.scaleOverride) ?\n\t\t\t\t{\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t} :\n\t\t\t\thelpers.calculateScaleRange(\n\t\t\t\t\tvaluesArray,\n\t\t\t\t\thelpers.min([this.chart.width, this.chart.height])/2,\n\t\t\t\t\tthis.options.scaleFontSize,\n\t\t\t\t\tthis.options.scaleBeginAtZero,\n\t\t\t\t\tthis.options.scaleIntegersOnly\n\t\t\t\t);\n\n\t\t\thelpers.extend(\n\t\t\t\tthis.scale,\n\t\t\t\tscaleSizes\n\t\t\t);\n\n\t\t},\n\t\taddData : function(valuesArray,label){\n\t\t\t//Map the values array for each of the datasets\n\t\t\tthis.scale.valuesCount++;\n\t\t\thelpers.each(valuesArray,function(value,datasetIndex){\n\t\t\t\tvar pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value));\n\t\t\t\tthis.datasets[datasetIndex].points.push(new this.PointClass({\n\t\t\t\t\tvalue : value,\n\t\t\t\t\tlabel : label,\n\t\t\t\t\tx: pointPosition.x,\n\t\t\t\t\ty: pointPosition.y,\n\t\t\t\t\tstrokeColor : this.datasets[datasetIndex].pointStrokeColor,\n\t\t\t\t\tfillColor : this.datasets[datasetIndex].pointColor\n\t\t\t\t}));\n\t\t\t},this);\n\n\t\t\tthis.scale.labels.push(label);\n\n\t\t\tthis.reflow();\n\n\t\t\tthis.update();\n\t\t},\n\t\tremoveData : function(){\n\t\t\tthis.scale.valuesCount--;\n\t\t\tthis.scale.labels.shift();\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tdataset.points.shift();\n\t\t\t},this);\n\t\t\tthis.reflow();\n\t\t\tthis.update();\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.eachPoints(function(point){\n\t\t\t\tpoint.save();\n\t\t\t});\n\t\t\tthis.reflow();\n\t\t\tthis.render();\n\t\t},\n\t\treflow: function(){\n\t\t\thelpers.extend(this.scale, {\n\t\t\t\twidth : this.chart.width,\n\t\t\t\theight: this.chart.height,\n\t\t\t\tsize : helpers.min([this.chart.width, this.chart.height]),\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2\n\t\t\t});\n\t\t\tthis.updateScaleRange(this.datasets);\n\t\t\tthis.scale.setScaleSize();\n\t\t\tthis.scale.buildYLabels();\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easeDecimal = ease || 1,\n\t\t\t\tctx = this.chart.ctx;\n\t\t\tthis.clear();\n\t\t\tthis.scale.draw();\n\n\t\t\thelpers.each(this.datasets,function(dataset){\n\n\t\t\t\t//Transition each point first so that the line and point drawing isn't out of sync\n\t\t\t\thelpers.each(dataset.points,function(point,index){\n\t\t\t\t\tif (point.hasValue()){\n\t\t\t\t\t\tpoint.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);\n\t\t\t\t\t}\n\t\t\t\t},this);\n\n\n\n\t\t\t\t//Draw the line between all the points\n\t\t\t\tctx.lineWidth = this.options.datasetStrokeWidth;\n\t\t\t\tctx.strokeStyle = dataset.strokeColor;\n\t\t\t\tctx.beginPath();\n\t\t\t\thelpers.each(dataset.points,function(point,index){\n\t\t\t\t\tif (index === 0){\n\t\t\t\t\t\tctx.moveTo(point.x,point.y);\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\tctx.lineTo(point.x,point.y);\n\t\t\t\t\t}\n\t\t\t\t},this);\n\t\t\t\tctx.closePath();\n\t\t\t\tctx.stroke();\n\n\t\t\t\tctx.fillStyle = dataset.fillColor;\n\t\t\t\tctx.fill();\n\n\t\t\t\t//Now draw the points over the line\n\t\t\t\t//A little inefficient double looping, but better than the line\n\t\t\t\t//lagging behind the point positions\n\t\t\t\thelpers.each(dataset.points,function(point){\n\t\t\t\t\tif (point.hasValue()){\n\t\t\t\t\t\tpoint.draw();\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t},this);\n\n\t\t}\n\n\t});\n\n\n\n\n\n}).call(this);"
  },
  {
    "path": "static/assets/plugins/Chart.js/src/Chart.Bar.js",
    "content": "(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\thelpers = Chart.helpers;\n\n\n\tvar defaultConfig = {\n\t\t//Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value\n\t\tscaleBeginAtZero : true,\n\n\t\t//Boolean - Whether grid lines are shown across the chart\n\t\tscaleShowGridLines : true,\n\n\t\t//String - Colour of the grid lines\n\t\tscaleGridLineColor : \"rgba(0,0,0,.05)\",\n\n\t\t//Number - Width of the grid lines\n\t\tscaleGridLineWidth : 1,\n\n\t\t//Boolean - Whether to show horizontal lines (except X axis)\n\t\tscaleShowHorizontalLines: true,\n\n\t\t//Boolean - Whether to show vertical lines (except Y axis)\n\t\tscaleShowVerticalLines: true,\n\n\t\t//Boolean - If there is a stroke on each bar\n\t\tbarShowStroke : true,\n\n\t\t//Number - Pixel width of the bar stroke\n\t\tbarStrokeWidth : 2,\n\n\t\t//Number - Spacing between each of the X value sets\n\t\tbarValueSpacing : 5,\n\n\t\t//Number - Spacing between data sets within X values\n\t\tbarDatasetSpacing : 1,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\\\"background-color:<%=datasets[i].fillColor%>\\\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>\"\n\n\t};\n\n\n\tChart.Type.extend({\n\t\tname: \"Bar\",\n\t\tdefaults : defaultConfig,\n\t\tinitialize:  function(data){\n\n\t\t\t//Expose options as a scope variable here so we can access it in the ScaleClass\n\t\t\tvar options = this.options;\n\n\t\t\tthis.ScaleClass = Chart.Scale.extend({\n\t\t\t\toffsetGridLines : true,\n\t\t\t\tcalculateBarX : function(datasetCount, datasetIndex, barIndex){\n\t\t\t\t\t//Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar\n\t\t\t\t\tvar xWidth = this.calculateBaseWidth(),\n\t\t\t\t\t\txAbsolute = this.calculateX(barIndex) - (xWidth/2),\n\t\t\t\t\t\tbarWidth = this.calculateBarWidth(datasetCount);\n\n\t\t\t\t\treturn xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2;\n\t\t\t\t},\n\t\t\t\tcalculateBaseWidth : function(){\n\t\t\t\t\treturn (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);\n\t\t\t\t},\n\t\t\t\tcalculateBarWidth : function(datasetCount){\n\t\t\t\t\t//The padding between datasets is to the right of each bar, providing that there are more than 1 dataset\n\t\t\t\t\tvar baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);\n\n\t\t\t\t\treturn (baseWidth / datasetCount);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.datasets = [];\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];\n\n\t\t\t\t\tthis.eachBars(function(bar){\n\t\t\t\t\t\tbar.restore(['fillColor', 'strokeColor']);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activeBars, function(activeBar){\n\t\t\t\t\t\tactiveBar.fillColor = activeBar.highlightFill;\n\t\t\t\t\t\tactiveBar.strokeColor = activeBar.highlightStroke;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activeBars);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t//Declare the extension of the default point, to cater for the options passed in to the constructor\n\t\t\tthis.BarClass = Chart.Rectangle.extend({\n\t\t\t\tstrokeWidth : this.options.barStrokeWidth,\n\t\t\t\tshowStroke : this.options.barShowStroke,\n\t\t\t\tctx : this.chart.ctx\n\t\t\t});\n\n\t\t\t//Iterate through each of the datasets, and build this into a property of the chart\n\t\t\thelpers.each(data.datasets,function(dataset,datasetIndex){\n\n\t\t\t\tvar datasetObject = {\n\t\t\t\t\tlabel : dataset.label || null,\n\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\tbars : []\n\t\t\t\t};\n\n\t\t\t\tthis.datasets.push(datasetObject);\n\n\t\t\t\thelpers.each(dataset.data,function(dataPoint,index){\n\t\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\t\tdatasetObject.bars.push(new this.BarClass({\n\t\t\t\t\t\tvalue : dataPoint,\n\t\t\t\t\t\tlabel : data.labels[index],\n\t\t\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\t\thighlightFill : dataset.highlightFill || dataset.fillColor,\n\t\t\t\t\t\thighlightStroke : dataset.highlightStroke || dataset.strokeColor\n\t\t\t\t\t}));\n\t\t\t\t},this);\n\n\t\t\t},this);\n\n\t\t\tthis.buildScale(data.labels);\n\n\t\t\tthis.BarClass.prototype.base = this.scale.endPoint;\n\n\t\t\tthis.eachBars(function(bar, index, datasetIndex){\n\t\t\t\thelpers.extend(bar, {\n\t\t\t\t\twidth : this.scale.calculateBarWidth(this.datasets.length),\n\t\t\t\t\tx: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),\n\t\t\t\t\ty: this.scale.endPoint\n\t\t\t\t});\n\t\t\t\tbar.save();\n\t\t\t}, this);\n\n\t\t\tthis.render();\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.scale.update();\n\t\t\t// Reset any highlight colours before updating.\n\t\t\thelpers.each(this.activeElements, function(activeElement){\n\t\t\t\tactiveElement.restore(['fillColor', 'strokeColor']);\n\t\t\t});\n\n\t\t\tthis.eachBars(function(bar){\n\t\t\t\tbar.save();\n\t\t\t});\n\t\t\tthis.render();\n\t\t},\n\t\teachBars : function(callback){\n\t\t\thelpers.each(this.datasets,function(dataset, datasetIndex){\n\t\t\t\thelpers.each(dataset.bars, callback, this, datasetIndex);\n\t\t\t},this);\n\t\t},\n\t\tgetBarsAtEvent : function(e){\n\t\t\tvar barsArray = [],\n\t\t\t\teventPosition = helpers.getRelativePosition(e),\n\t\t\t\tdatasetIterator = function(dataset){\n\t\t\t\t\tbarsArray.push(dataset.bars[barIndex]);\n\t\t\t\t},\n\t\t\t\tbarIndex;\n\n\t\t\tfor (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {\n\t\t\t\tfor (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {\n\t\t\t\t\tif (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){\n\t\t\t\t\t\thelpers.each(this.datasets, datasetIterator);\n\t\t\t\t\t\treturn barsArray;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn barsArray;\n\t\t},\n\t\tbuildScale : function(labels){\n\t\t\tvar self = this;\n\n\t\t\tvar dataTotal = function(){\n\t\t\t\tvar values = [];\n\t\t\t\tself.eachBars(function(bar){\n\t\t\t\t\tvalues.push(bar.value);\n\t\t\t\t});\n\t\t\t\treturn values;\n\t\t\t};\n\n\t\t\tvar scaleOptions = {\n\t\t\t\ttemplateString : this.options.scaleLabel,\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttextColor : this.options.scaleFontColor,\n\t\t\t\tfontSize : this.options.scaleFontSize,\n\t\t\t\tfontStyle : this.options.scaleFontStyle,\n\t\t\t\tfontFamily : this.options.scaleFontFamily,\n\t\t\t\tvaluesCount : labels.length,\n\t\t\t\tbeginAtZero : this.options.scaleBeginAtZero,\n\t\t\t\tintegersOnly : this.options.scaleIntegersOnly,\n\t\t\t\tcalculateYRange: function(currentHeight){\n\t\t\t\t\tvar updatedRanges = helpers.calculateScaleRange(\n\t\t\t\t\t\tdataTotal(),\n\t\t\t\t\t\tcurrentHeight,\n\t\t\t\t\t\tthis.fontSize,\n\t\t\t\t\t\tthis.beginAtZero,\n\t\t\t\t\t\tthis.integersOnly\n\t\t\t\t\t);\n\t\t\t\t\thelpers.extend(this, updatedRanges);\n\t\t\t\t},\n\t\t\t\txLabels : labels,\n\t\t\t\tfont : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),\n\t\t\t\tlineWidth : this.options.scaleLineWidth,\n\t\t\t\tlineColor : this.options.scaleLineColor,\n\t\t\t\tshowHorizontalLines : this.options.scaleShowHorizontalLines,\n\t\t\t\tshowVerticalLines : this.options.scaleShowVerticalLines,\n\t\t\t\tgridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,\n\t\t\t\tgridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : \"rgba(0,0,0,0)\",\n\t\t\t\tpadding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,\n\t\t\t\tshowLabels : this.options.scaleShowLabels,\n\t\t\t\tdisplay : this.options.showScale\n\t\t\t};\n\n\t\t\tif (this.options.scaleOverride){\n\t\t\t\thelpers.extend(scaleOptions, {\n\t\t\t\t\tcalculateYRange: helpers.noop,\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.scale = new this.ScaleClass(scaleOptions);\n\t\t},\n\t\taddData : function(valuesArray,label){\n\t\t\t//Map the values array for each of the datasets\n\t\t\thelpers.each(valuesArray,function(value,datasetIndex){\n\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\tthis.datasets[datasetIndex].bars.push(new this.BarClass({\n\t\t\t\t\tvalue : value,\n\t\t\t\t\tlabel : label,\n\t\t\t\t\tx: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),\n\t\t\t\t\ty: this.scale.endPoint,\n\t\t\t\t\twidth : this.scale.calculateBarWidth(this.datasets.length),\n\t\t\t\t\tbase : this.scale.endPoint,\n\t\t\t\t\tstrokeColor : this.datasets[datasetIndex].strokeColor,\n\t\t\t\t\tfillColor : this.datasets[datasetIndex].fillColor\n\t\t\t\t}));\n\t\t\t},this);\n\n\t\t\tthis.scale.addXLabel(label);\n\t\t\t//Then re-render the chart.\n\t\t\tthis.update();\n\t\t},\n\t\tremoveData : function(){\n\t\t\tthis.scale.removeXLabel();\n\t\t\t//Then re-render the chart.\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tdataset.bars.shift();\n\t\t\t},this);\n\t\t\tthis.update();\n\t\t},\n\t\treflow : function(){\n\t\t\thelpers.extend(this.BarClass.prototype,{\n\t\t\t\ty: this.scale.endPoint,\n\t\t\t\tbase : this.scale.endPoint\n\t\t\t});\n\t\t\tvar newScaleProps = helpers.extend({\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width\n\t\t\t});\n\t\t\tthis.scale.update(newScaleProps);\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easingDecimal = ease || 1;\n\t\t\tthis.clear();\n\n\t\t\tvar ctx = this.chart.ctx;\n\n\t\t\tthis.scale.draw(easingDecimal);\n\n\t\t\t//Draw all the bars for each dataset\n\t\t\thelpers.each(this.datasets,function(dataset,datasetIndex){\n\t\t\t\thelpers.each(dataset.bars,function(bar,index){\n\t\t\t\t\tif (bar.hasValue()){\n\t\t\t\t\t\tbar.base = this.scale.endPoint;\n\t\t\t\t\t\t//Transition then draw\n\t\t\t\t\t\tbar.transition({\n\t\t\t\t\t\t\tx : this.scale.calculateBarX(this.datasets.length, datasetIndex, index),\n\t\t\t\t\t\t\ty : this.scale.calculateY(bar.value),\n\t\t\t\t\t\t\twidth : this.scale.calculateBarWidth(this.datasets.length)\n\t\t\t\t\t\t}, easingDecimal).draw();\n\t\t\t\t\t}\n\t\t\t\t},this);\n\n\t\t\t},this);\n\t\t}\n\t});\n\n\n}).call(this);\n"
  },
  {
    "path": "static/assets/plugins/Chart.js/src/Chart.Core.js",
    "content": "/*!\n * Chart.js\n * http://chartjs.org/\n * Version: {{ version }}\n *\n * Copyright 2015 Nick Downie\n * Released under the MIT license\n * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md\n */\n\n\n(function(){\n\n\t\"use strict\";\n\n\t//Declare root variable - window in the browser, global on the server\n\tvar root = this,\n\t\tprevious = root.Chart;\n\n\t//Occupy the global variable of Chart, and create a simple base class\n\tvar Chart = function(context){\n\t\tvar chart = this;\n\t\tthis.canvas = context.canvas;\n\n\t\tthis.ctx = context;\n\n\t\t//Variables global to the chart\n\t\tvar computeDimension = function(element,dimension)\n\t\t{\n\t\t\tif (element['offset'+dimension])\n\t\t\t{\n\t\t\t\treturn element['offset'+dimension];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn document.defaultView.getComputedStyle(element).getPropertyValue(dimension);\n\t\t\t}\n\t\t}\n\n\t\tvar width = this.width = computeDimension(context.canvas,'Width');\n\t\tvar height = this.height = computeDimension(context.canvas,'Height');\n\n\t\t// Firefox requires this to work correctly\n\t\tcontext.canvas.width  = width;\n\t\tcontext.canvas.height = height;\n\n\t\tvar width = this.width = context.canvas.width;\n\t\tvar height = this.height = context.canvas.height;\n\t\tthis.aspectRatio = this.width / this.height;\n\t\t//High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.\n\t\thelpers.retinaScale(this);\n\n\t\treturn this;\n\t};\n\t//Globally expose the defaults to allow for user updating/changing\n\tChart.defaults = {\n\t\tglobal: {\n\t\t\t// Boolean - Whether to animate the chart\n\t\t\tanimation: true,\n\n\t\t\t// Number - Number of animation steps\n\t\t\tanimationSteps: 60,\n\n\t\t\t// String - Animation easing effect\n\t\t\tanimationEasing: \"easeOutQuart\",\n\n\t\t\t// Boolean - If we should show the scale at all\n\t\t\tshowScale: true,\n\n\t\t\t// Boolean - If we want to override with a hard coded scale\n\t\t\tscaleOverride: false,\n\n\t\t\t// ** Required if scaleOverride is true **\n\t\t\t// Number - The number of steps in a hard coded scale\n\t\t\tscaleSteps: null,\n\t\t\t// Number - The value jump in the hard coded scale\n\t\t\tscaleStepWidth: null,\n\t\t\t// Number - The scale starting value\n\t\t\tscaleStartValue: null,\n\n\t\t\t// String - Colour of the scale line\n\t\t\tscaleLineColor: \"rgba(0,0,0,.1)\",\n\n\t\t\t// Number - Pixel width of the scale line\n\t\t\tscaleLineWidth: 1,\n\n\t\t\t// Boolean - Whether to show labels on the scale\n\t\t\tscaleShowLabels: true,\n\n\t\t\t// Interpolated JS string - can access value\n\t\t\tscaleLabel: \"<%=value%>\",\n\n\t\t\t// Boolean - Whether the scale should stick to integers, and not show any floats even if drawing space is there\n\t\t\tscaleIntegersOnly: true,\n\n\t\t\t// Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value\n\t\t\tscaleBeginAtZero: false,\n\n\t\t\t// String - Scale label font declaration for the scale label\n\t\t\tscaleFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\n\t\t\t// Number - Scale label font size in pixels\n\t\t\tscaleFontSize: 12,\n\n\t\t\t// String - Scale label font weight style\n\t\t\tscaleFontStyle: \"normal\",\n\n\t\t\t// String - Scale label font colour\n\t\t\tscaleFontColor: \"#666\",\n\n\t\t\t// Boolean - whether or not the chart should be responsive and resize when the browser does.\n\t\t\tresponsive: false,\n\n\t\t\t// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container\n\t\t\tmaintainAspectRatio: true,\n\n\t\t\t// Boolean - Determines whether to draw tooltips on the canvas or not - attaches events to touchmove & mousemove\n\t\t\tshowTooltips: true,\n\n\t\t\t// Boolean - Determines whether to draw built-in tooltip or call custom tooltip function\n\t\t\tcustomTooltips: false,\n\n\t\t\t// Array - Array of string names to attach tooltip events\n\t\t\ttooltipEvents: [\"mousemove\", \"touchstart\", \"touchmove\", \"mouseout\"],\n\n\t\t\t// String - Tooltip background colour\n\t\t\ttooltipFillColor: \"rgba(0,0,0,0.8)\",\n\n\t\t\t// String - Tooltip label font declaration for the scale label\n\t\t\ttooltipFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\n\t\t\t// Number - Tooltip label font size in pixels\n\t\t\ttooltipFontSize: 14,\n\n\t\t\t// String - Tooltip font weight style\n\t\t\ttooltipFontStyle: \"normal\",\n\n\t\t\t// String - Tooltip label font colour\n\t\t\ttooltipFontColor: \"#fff\",\n\n\t\t\t// String - Tooltip title font declaration for the scale label\n\t\t\ttooltipTitleFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\n\t\t\t// Number - Tooltip title font size in pixels\n\t\t\ttooltipTitleFontSize: 14,\n\n\t\t\t// String - Tooltip title font weight style\n\t\t\ttooltipTitleFontStyle: \"bold\",\n\n\t\t\t// String - Tooltip title font colour\n\t\t\ttooltipTitleFontColor: \"#fff\",\n\n\t\t\t// Number - pixel width of padding around tooltip text\n\t\t\ttooltipYPadding: 6,\n\n\t\t\t// Number - pixel width of padding around tooltip text\n\t\t\ttooltipXPadding: 6,\n\n\t\t\t// Number - Size of the caret on the tooltip\n\t\t\ttooltipCaretSize: 8,\n\n\t\t\t// Number - Pixel radius of the tooltip border\n\t\t\ttooltipCornerRadius: 6,\n\n\t\t\t// Number - Pixel offset from point x to tooltip edge\n\t\t\ttooltipXOffset: 10,\n\n\t\t\t// String - Template string for single tooltips\n\t\t\ttooltipTemplate: \"<%if (label){%><%=label%>: <%}%><%= value %>\",\n\n\t\t\t// String - Template string for single tooltips\n\t\t\tmultiTooltipTemplate: \"<%= value %>\",\n\n\t\t\t// String - Colour behind the legend colour block\n\t\t\tmultiTooltipKeyBackground: '#fff',\n\n\t\t\t// Function - Will fire on animation progression.\n\t\t\tonAnimationProgress: function(){},\n\n\t\t\t// Function - Will fire on animation completion.\n\t\t\tonAnimationComplete: function(){}\n\n\t\t}\n\t};\n\n\t//Create a dictionary of chart types, to allow for extension of existing types\n\tChart.types = {};\n\n\t//Global Chart helpers object for utility methods and classes\n\tvar helpers = Chart.helpers = {};\n\n\t\t//-- Basic js utility methods\n\tvar each = helpers.each = function(loopable,callback,self){\n\t\t\tvar additionalArgs = Array.prototype.slice.call(arguments, 3);\n\t\t\t// Check to see if null or undefined firstly.\n\t\t\tif (loopable){\n\t\t\t\tif (loopable.length === +loopable.length){\n\t\t\t\t\tvar i;\n\t\t\t\t\tfor (i=0; i<loopable.length; i++){\n\t\t\t\t\t\tcallback.apply(self,[loopable[i], i].concat(additionalArgs));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\tfor (var item in loopable){\n\t\t\t\t\t\tcallback.apply(self,[loopable[item],item].concat(additionalArgs));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tclone = helpers.clone = function(obj){\n\t\t\tvar objClone = {};\n\t\t\teach(obj,function(value,key){\n\t\t\t\tif (obj.hasOwnProperty(key)) objClone[key] = value;\n\t\t\t});\n\t\t\treturn objClone;\n\t\t},\n\t\textend = helpers.extend = function(base){\n\t\t\teach(Array.prototype.slice.call(arguments,1), function(extensionObject) {\n\t\t\t\teach(extensionObject,function(value,key){\n\t\t\t\t\tif (extensionObject.hasOwnProperty(key)) base[key] = value;\n\t\t\t\t});\n\t\t\t});\n\t\t\treturn base;\n\t\t},\n\t\tmerge = helpers.merge = function(base,master){\n\t\t\t//Merge properties in left object over to a shallow clone of object right.\n\t\t\tvar args = Array.prototype.slice.call(arguments,0);\n\t\t\targs.unshift({});\n\t\t\treturn extend.apply(null, args);\n\t\t},\n\t\tindexOf = helpers.indexOf = function(arrayToSearch, item){\n\t\t\tif (Array.prototype.indexOf) {\n\t\t\t\treturn arrayToSearch.indexOf(item);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tfor (var i = 0; i < arrayToSearch.length; i++) {\n\t\t\t\t\tif (arrayToSearch[i] === item) return i;\n\t\t\t\t}\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t},\n\t\twhere = helpers.where = function(collection, filterCallback){\n\t\t\tvar filtered = [];\n\n\t\t\thelpers.each(collection, function(item){\n\t\t\t\tif (filterCallback(item)){\n\t\t\t\t\tfiltered.push(item);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn filtered;\n\t\t},\n\t\tfindNextWhere = helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex){\n\t\t\t// Default to start of the array\n\t\t\tif (!startIndex){\n\t\t\t\tstartIndex = -1;\n\t\t\t}\n\t\t\tfor (var i = startIndex + 1; i < arrayToSearch.length; i++) {\n\t\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\t\tif (filterCallback(currentItem)){\n\t\t\t\t\treturn currentItem;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tfindPreviousWhere = helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex){\n\t\t\t// Default to end of the array\n\t\t\tif (!startIndex){\n\t\t\t\tstartIndex = arrayToSearch.length;\n\t\t\t}\n\t\t\tfor (var i = startIndex - 1; i >= 0; i--) {\n\t\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\t\tif (filterCallback(currentItem)){\n\t\t\t\t\treturn currentItem;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tinherits = helpers.inherits = function(extensions){\n\t\t\t//Basic javascript inheritance based on the model created in Backbone.js\n\t\t\tvar parent = this;\n\t\t\tvar ChartElement = (extensions && extensions.hasOwnProperty(\"constructor\")) ? extensions.constructor : function(){ return parent.apply(this, arguments); };\n\n\t\t\tvar Surrogate = function(){ this.constructor = ChartElement;};\n\t\t\tSurrogate.prototype = parent.prototype;\n\t\t\tChartElement.prototype = new Surrogate();\n\n\t\t\tChartElement.extend = inherits;\n\n\t\t\tif (extensions) extend(ChartElement.prototype, extensions);\n\n\t\t\tChartElement.__super__ = parent.prototype;\n\n\t\t\treturn ChartElement;\n\t\t},\n\t\tnoop = helpers.noop = function(){},\n\t\tuid = helpers.uid = (function(){\n\t\t\tvar id=0;\n\t\t\treturn function(){\n\t\t\t\treturn \"chart-\" + id++;\n\t\t\t};\n\t\t})(),\n\t\twarn = helpers.warn = function(str){\n\t\t\t//Method for warning of errors\n\t\t\tif (window.console && typeof window.console.warn == \"function\") console.warn(str);\n\t\t},\n\t\tamd = helpers.amd = (typeof define == 'function' && define.amd),\n\t\t//-- Math methods\n\t\tisNumber = helpers.isNumber = function(n){\n\t\t\treturn !isNaN(parseFloat(n)) && isFinite(n);\n\t\t},\n\t\tmax = helpers.max = function(array){\n\t\t\treturn Math.max.apply( Math, array );\n\t\t},\n\t\tmin = helpers.min = function(array){\n\t\t\treturn Math.min.apply( Math, array );\n\t\t},\n\t\tcap = helpers.cap = function(valueToCap,maxValue,minValue){\n\t\t\tif(isNumber(maxValue)) {\n\t\t\t\tif( valueToCap > maxValue ) {\n\t\t\t\t\treturn maxValue;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(isNumber(minValue)){\n\t\t\t\tif ( valueToCap < minValue ){\n\t\t\t\t\treturn minValue;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn valueToCap;\n\t\t},\n\t\tgetDecimalPlaces = helpers.getDecimalPlaces = function(num){\n\t\t\tif (num%1!==0 && isNumber(num)){\n\t\t\t\treturn num.toString().split(\".\")[1].length;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t},\n\t\ttoRadians = helpers.radians = function(degrees){\n\t\t\treturn degrees * (Math.PI/180);\n\t\t},\n\t\t// Gets the angle from vertical upright to the point about a centre.\n\t\tgetAngleFromPoint = helpers.getAngleFromPoint = function(centrePoint, anglePoint){\n\t\t\tvar distanceFromXCenter = anglePoint.x - centrePoint.x,\n\t\t\t\tdistanceFromYCenter = anglePoint.y - centrePoint.y,\n\t\t\t\tradialDistanceFromCenter = Math.sqrt( distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);\n\n\n\t\t\tvar angle = Math.PI * 2 + Math.atan2(distanceFromYCenter, distanceFromXCenter);\n\n\t\t\t//If the segment is in the top left quadrant, we need to add another rotation to the angle\n\t\t\tif (distanceFromXCenter < 0 && distanceFromYCenter < 0){\n\t\t\t\tangle += Math.PI*2;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tangle: angle,\n\t\t\t\tdistance: radialDistanceFromCenter\n\t\t\t};\n\t\t},\n\t\taliasPixel = helpers.aliasPixel = function(pixelWidth){\n\t\t\treturn (pixelWidth % 2 === 0) ? 0 : 0.5;\n\t\t},\n\t\tsplineCurve = helpers.splineCurve = function(FirstPoint,MiddlePoint,AfterPoint,t){\n\t\t\t//Props to Rob Spencer at scaled innovation for his post on splining between points\n\t\t\t//http://scaledinnovation.com/analytics/splines/aboutSplines.html\n\t\t\tvar d01=Math.sqrt(Math.pow(MiddlePoint.x-FirstPoint.x,2)+Math.pow(MiddlePoint.y-FirstPoint.y,2)),\n\t\t\t\td12=Math.sqrt(Math.pow(AfterPoint.x-MiddlePoint.x,2)+Math.pow(AfterPoint.y-MiddlePoint.y,2)),\n\t\t\t\tfa=t*d01/(d01+d12),// scaling factor for triangle Ta\n\t\t\t\tfb=t*d12/(d01+d12);\n\t\t\treturn {\n\t\t\t\tinner : {\n\t\t\t\t\tx : MiddlePoint.x-fa*(AfterPoint.x-FirstPoint.x),\n\t\t\t\t\ty : MiddlePoint.y-fa*(AfterPoint.y-FirstPoint.y)\n\t\t\t\t},\n\t\t\t\touter : {\n\t\t\t\t\tx: MiddlePoint.x+fb*(AfterPoint.x-FirstPoint.x),\n\t\t\t\t\ty : MiddlePoint.y+fb*(AfterPoint.y-FirstPoint.y)\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\tcalculateOrderOfMagnitude = helpers.calculateOrderOfMagnitude = function(val){\n\t\t\treturn Math.floor(Math.log(val) / Math.LN10);\n\t\t},\n\t\tcalculateScaleRange = helpers.calculateScaleRange = function(valuesArray, drawingSize, textSize, startFromZero, integersOnly){\n\n\t\t\t//Set a minimum step of two - a point at the top of the graph, and a point at the base\n\t\t\tvar minSteps = 2,\n\t\t\t\tmaxSteps = Math.floor(drawingSize/(textSize * 1.5)),\n\t\t\t\tskipFitting = (minSteps >= maxSteps);\n\n\t\t\tvar maxValue = max(valuesArray),\n\t\t\t\tminValue = min(valuesArray);\n\n\t\t\t// We need some degree of seperation here to calculate the scales if all the values are the same\n\t\t\t// Adding/minusing 0.5 will give us a range of 1.\n\t\t\tif (maxValue === minValue){\n\t\t\t\tmaxValue += 0.5;\n\t\t\t\t// So we don't end up with a graph with a negative start value if we've said always start from zero\n\t\t\t\tif (minValue >= 0.5 && !startFromZero){\n\t\t\t\t\tminValue -= 0.5;\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\t// Make up a whole number above the values\n\t\t\t\t\tmaxValue += 0.5;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar\tvalueRange = Math.abs(maxValue - minValue),\n\t\t\t\trangeOrderOfMagnitude = calculateOrderOfMagnitude(valueRange),\n\t\t\t\tgraphMax = Math.ceil(maxValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),\n\t\t\t\tgraphMin = (startFromZero) ? 0 : Math.floor(minValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),\n\t\t\t\tgraphRange = graphMax - graphMin,\n\t\t\t\tstepValue = Math.pow(10, rangeOrderOfMagnitude),\n\t\t\t\tnumberOfSteps = Math.round(graphRange / stepValue);\n\n\t\t\t//If we have more space on the graph we'll use it to give more definition to the data\n\t\t\twhile((numberOfSteps > maxSteps || (numberOfSteps * 2) < maxSteps) && !skipFitting) {\n\t\t\t\tif(numberOfSteps > maxSteps){\n\t\t\t\t\tstepValue *=2;\n\t\t\t\t\tnumberOfSteps = Math.round(graphRange/stepValue);\n\t\t\t\t\t// Don't ever deal with a decimal number of steps - cancel fitting and just use the minimum number of steps.\n\t\t\t\t\tif (numberOfSteps % 1 !== 0){\n\t\t\t\t\t\tskipFitting = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//We can fit in double the amount of scale points on the scale\n\t\t\t\telse{\n\t\t\t\t\t//If user has declared ints only, and the step value isn't a decimal\n\t\t\t\t\tif (integersOnly && rangeOrderOfMagnitude >= 0){\n\t\t\t\t\t\t//If the user has said integers only, we need to check that making the scale more granular wouldn't make it a float\n\t\t\t\t\t\tif(stepValue/2 % 1 === 0){\n\t\t\t\t\t\t\tstepValue /=2;\n\t\t\t\t\t\t\tnumberOfSteps = Math.round(graphRange/stepValue);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//If it would make it a float break out of the loop\n\t\t\t\t\t\telse{\n\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\t//If the scale doesn't have to be an int, make the scale more granular anyway.\n\t\t\t\t\telse{\n\t\t\t\t\t\tstepValue /=2;\n\t\t\t\t\t\tnumberOfSteps = Math.round(graphRange/stepValue);\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (skipFitting){\n\t\t\t\tnumberOfSteps = minSteps;\n\t\t\t\tstepValue = graphRange / numberOfSteps;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsteps : numberOfSteps,\n\t\t\t\tstepValue : stepValue,\n\t\t\t\tmin : graphMin,\n\t\t\t\tmax\t: graphMin + (numberOfSteps * stepValue)\n\t\t\t};\n\n\t\t},\n\t\t/* jshint ignore:start */\n\t\t// Blows up jshint errors based on the new Function constructor\n\t\t//Templating methods\n\t\t//Javascript micro templating by John Resig - source at http://ejohn.org/blog/javascript-micro-templating/\n\t\ttemplate = helpers.template = function(templateString, valuesObject){\n\n\t\t\t// If templateString is function rather than string-template - call the function for valuesObject\n\n\t\t\tif(templateString instanceof Function){\n\t\t\t \treturn templateString(valuesObject);\n\t\t \t}\n\n\t\t\tvar cache = {};\n\t\t\tfunction tmpl(str, data){\n\t\t\t\t// Figure out if we're getting a template, or if we need to\n\t\t\t\t// load the template - and be sure to cache the result.\n\t\t\t\tvar fn = !/\\W/.test(str) ?\n\t\t\t\tcache[str] = cache[str] :\n\n\t\t\t\t// Generate a reusable function that will serve as a template\n\t\t\t\t// generator (and which will be cached).\n\t\t\t\tnew Function(\"obj\",\n\t\t\t\t\t\"var p=[],print=function(){p.push.apply(p,arguments);};\" +\n\n\t\t\t\t\t// Introduce the data as local variables using with(){}\n\t\t\t\t\t\"with(obj){p.push('\" +\n\n\t\t\t\t\t// Convert the template into pure JavaScript\n\t\t\t\t\tstr\n\t\t\t\t\t\t.replace(/[\\r\\t\\n]/g, \" \")\n\t\t\t\t\t\t.split(\"<%\").join(\"\\t\")\n\t\t\t\t\t\t.replace(/((^|%>)[^\\t]*)'/g, \"$1\\r\")\n\t\t\t\t\t\t.replace(/\\t=(.*?)%>/g, \"',$1,'\")\n\t\t\t\t\t\t.split(\"\\t\").join(\"');\")\n\t\t\t\t\t\t.split(\"%>\").join(\"p.push('\")\n\t\t\t\t\t\t.split(\"\\r\").join(\"\\\\'\") +\n\t\t\t\t\t\"');}return p.join('');\"\n\t\t\t\t);\n\n\t\t\t\t// Provide some basic currying to the user\n\t\t\t\treturn data ? fn( data ) : fn;\n\t\t\t}\n\t\t\treturn tmpl(templateString,valuesObject);\n\t\t},\n\t\t/* jshint ignore:end */\n\t\tgenerateLabels = helpers.generateLabels = function(templateString,numberOfSteps,graphMin,stepValue){\n\t\t\tvar labelsArray = new Array(numberOfSteps);\n\t\t\tif (labelTemplateString){\n\t\t\t\teach(labelsArray,function(val,index){\n\t\t\t\t\tlabelsArray[index] = template(templateString,{value: (graphMin + (stepValue*(index+1)))});\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn labelsArray;\n\t\t},\n\t\t//--Animation methods\n\t\t//Easing functions adapted from Robert Penner's easing equations\n\t\t//http://www.robertpenner.com/easing/\n\t\teasingEffects = helpers.easingEffects = {\n\t\t\tlinear: function (t) {\n\t\t\t\treturn t;\n\t\t\t},\n\t\t\teaseInQuad: function (t) {\n\t\t\t\treturn t * t;\n\t\t\t},\n\t\t\teaseOutQuad: function (t) {\n\t\t\t\treturn -1 * t * (t - 2);\n\t\t\t},\n\t\t\teaseInOutQuad: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * t * t;\n\t\t\t\treturn -1 / 2 * ((--t) * (t - 2) - 1);\n\t\t\t},\n\t\t\teaseInCubic: function (t) {\n\t\t\t\treturn t * t * t;\n\t\t\t},\n\t\t\teaseOutCubic: function (t) {\n\t\t\t\treturn 1 * ((t = t / 1 - 1) * t * t + 1);\n\t\t\t},\n\t\t\teaseInOutCubic: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t;\n\t\t\t\treturn 1 / 2 * ((t -= 2) * t * t + 2);\n\t\t\t},\n\t\t\teaseInQuart: function (t) {\n\t\t\t\treturn t * t * t * t;\n\t\t\t},\n\t\t\teaseOutQuart: function (t) {\n\t\t\t\treturn -1 * ((t = t / 1 - 1) * t * t * t - 1);\n\t\t\t},\n\t\t\teaseInOutQuart: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t;\n\t\t\t\treturn -1 / 2 * ((t -= 2) * t * t * t - 2);\n\t\t\t},\n\t\t\teaseInQuint: function (t) {\n\t\t\t\treturn 1 * (t /= 1) * t * t * t * t;\n\t\t\t},\n\t\t\teaseOutQuint: function (t) {\n\t\t\t\treturn 1 * ((t = t / 1 - 1) * t * t * t * t + 1);\n\t\t\t},\n\t\t\teaseInOutQuint: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t * t;\n\t\t\t\treturn 1 / 2 * ((t -= 2) * t * t * t * t + 2);\n\t\t\t},\n\t\t\teaseInSine: function (t) {\n\t\t\t\treturn -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;\n\t\t\t},\n\t\t\teaseOutSine: function (t) {\n\t\t\t\treturn 1 * Math.sin(t / 1 * (Math.PI / 2));\n\t\t\t},\n\t\t\teaseInOutSine: function (t) {\n\t\t\t\treturn -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);\n\t\t\t},\n\t\t\teaseInExpo: function (t) {\n\t\t\t\treturn (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));\n\t\t\t},\n\t\t\teaseOutExpo: function (t) {\n\t\t\t\treturn (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);\n\t\t\t},\n\t\t\teaseInOutExpo: function (t) {\n\t\t\t\tif (t === 0) return 0;\n\t\t\t\tif (t === 1) return 1;\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * Math.pow(2, 10 * (t - 1));\n\t\t\t\treturn 1 / 2 * (-Math.pow(2, -10 * --t) + 2);\n\t\t\t},\n\t\t\teaseInCirc: function (t) {\n\t\t\t\tif (t >= 1) return t;\n\t\t\t\treturn -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);\n\t\t\t},\n\t\t\teaseOutCirc: function (t) {\n\t\t\t\treturn 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);\n\t\t\t},\n\t\t\teaseInOutCirc: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return -1 / 2 * (Math.sqrt(1 - t * t) - 1);\n\t\t\t\treturn 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);\n\t\t\t},\n\t\t\teaseInElastic: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tvar p = 0;\n\t\t\t\tvar a = 1;\n\t\t\t\tif (t === 0) return 0;\n\t\t\t\tif ((t /= 1) == 1) return 1;\n\t\t\t\tif (!p) p = 1 * 0.3;\n\t\t\t\tif (a < Math.abs(1)) {\n\t\t\t\t\ta = 1;\n\t\t\t\t\ts = p / 4;\n\t\t\t\t} else s = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t\treturn -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\n\t\t\t},\n\t\t\teaseOutElastic: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tvar p = 0;\n\t\t\t\tvar a = 1;\n\t\t\t\tif (t === 0) return 0;\n\t\t\t\tif ((t /= 1) == 1) return 1;\n\t\t\t\tif (!p) p = 1 * 0.3;\n\t\t\t\tif (a < Math.abs(1)) {\n\t\t\t\t\ta = 1;\n\t\t\t\t\ts = p / 4;\n\t\t\t\t} else s = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t\treturn a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;\n\t\t\t},\n\t\t\teaseInOutElastic: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tvar p = 0;\n\t\t\t\tvar a = 1;\n\t\t\t\tif (t === 0) return 0;\n\t\t\t\tif ((t /= 1 / 2) == 2) return 1;\n\t\t\t\tif (!p) p = 1 * (0.3 * 1.5);\n\t\t\t\tif (a < Math.abs(1)) {\n\t\t\t\t\ta = 1;\n\t\t\t\t\ts = p / 4;\n\t\t\t\t} else s = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t\tif (t < 1) return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\n\t\t\t\treturn a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;\n\t\t\t},\n\t\t\teaseInBack: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\treturn 1 * (t /= 1) * t * ((s + 1) * t - s);\n\t\t\t},\n\t\t\teaseOutBack: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\treturn 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);\n\t\t\t},\n\t\t\teaseInOutBack: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));\n\t\t\t\treturn 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);\n\t\t\t},\n\t\t\teaseInBounce: function (t) {\n\t\t\t\treturn 1 - easingEffects.easeOutBounce(1 - t);\n\t\t\t},\n\t\t\teaseOutBounce: function (t) {\n\t\t\t\tif ((t /= 1) < (1 / 2.75)) {\n\t\t\t\t\treturn 1 * (7.5625 * t * t);\n\t\t\t\t} else if (t < (2 / 2.75)) {\n\t\t\t\t\treturn 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);\n\t\t\t\t} else if (t < (2.5 / 2.75)) {\n\t\t\t\t\treturn 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);\n\t\t\t\t} else {\n\t\t\t\t\treturn 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);\n\t\t\t\t}\n\t\t\t},\n\t\t\teaseInOutBounce: function (t) {\n\t\t\t\tif (t < 1 / 2) return easingEffects.easeInBounce(t * 2) * 0.5;\n\t\t\t\treturn easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;\n\t\t\t}\n\t\t},\n\t\t//Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/\n\t\trequestAnimFrame = helpers.requestAnimFrame = (function(){\n\t\t\treturn window.requestAnimationFrame ||\n\t\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\t\twindow.oRequestAnimationFrame ||\n\t\t\t\twindow.msRequestAnimationFrame ||\n\t\t\t\tfunction(callback) {\n\t\t\t\t\treturn window.setTimeout(callback, 1000 / 60);\n\t\t\t\t};\n\t\t})(),\n\t\tcancelAnimFrame = helpers.cancelAnimFrame = (function(){\n\t\t\treturn window.cancelAnimationFrame ||\n\t\t\t\twindow.webkitCancelAnimationFrame ||\n\t\t\t\twindow.mozCancelAnimationFrame ||\n\t\t\t\twindow.oCancelAnimationFrame ||\n\t\t\t\twindow.msCancelAnimationFrame ||\n\t\t\t\tfunction(callback) {\n\t\t\t\t\treturn window.clearTimeout(callback, 1000 / 60);\n\t\t\t\t};\n\t\t})(),\n\t\tanimationLoop = helpers.animationLoop = function(callback,totalSteps,easingString,onProgress,onComplete,chartInstance){\n\n\t\t\tvar currentStep = 0,\n\t\t\t\teasingFunction = easingEffects[easingString] || easingEffects.linear;\n\n\t\t\tvar animationFrame = function(){\n\t\t\t\tcurrentStep++;\n\t\t\t\tvar stepDecimal = currentStep/totalSteps;\n\t\t\t\tvar easeDecimal = easingFunction(stepDecimal);\n\n\t\t\t\tcallback.call(chartInstance,easeDecimal,stepDecimal, currentStep);\n\t\t\t\tonProgress.call(chartInstance,easeDecimal,stepDecimal);\n\t\t\t\tif (currentStep < totalSteps){\n\t\t\t\t\tchartInstance.animationFrame = requestAnimFrame(animationFrame);\n\t\t\t\t} else{\n\t\t\t\t\tonComplete.apply(chartInstance);\n\t\t\t\t}\n\t\t\t};\n\t\t\trequestAnimFrame(animationFrame);\n\t\t},\n\t\t//-- DOM methods\n\t\tgetRelativePosition = helpers.getRelativePosition = function(evt){\n\t\t\tvar mouseX, mouseY;\n\t\t\tvar e = evt.originalEvent || evt,\n\t\t\t\tcanvas = evt.currentTarget || evt.srcElement,\n\t\t\t\tboundingRect = canvas.getBoundingClientRect();\n\n\t\t\tif (e.touches){\n\t\t\t\tmouseX = e.touches[0].clientX - boundingRect.left;\n\t\t\t\tmouseY = e.touches[0].clientY - boundingRect.top;\n\n\t\t\t}\n\t\t\telse{\n\t\t\t\tmouseX = e.clientX - boundingRect.left;\n\t\t\t\tmouseY = e.clientY - boundingRect.top;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tx : mouseX,\n\t\t\t\ty : mouseY\n\t\t\t};\n\n\t\t},\n\t\taddEvent = helpers.addEvent = function(node,eventType,method){\n\t\t\tif (node.addEventListener){\n\t\t\t\tnode.addEventListener(eventType,method);\n\t\t\t} else if (node.attachEvent){\n\t\t\t\tnode.attachEvent(\"on\"+eventType, method);\n\t\t\t} else {\n\t\t\t\tnode[\"on\"+eventType] = method;\n\t\t\t}\n\t\t},\n\t\tremoveEvent = helpers.removeEvent = function(node, eventType, handler){\n\t\t\tif (node.removeEventListener){\n\t\t\t\tnode.removeEventListener(eventType, handler, false);\n\t\t\t} else if (node.detachEvent){\n\t\t\t\tnode.detachEvent(\"on\"+eventType,handler);\n\t\t\t} else{\n\t\t\t\tnode[\"on\" + eventType] = noop;\n\t\t\t}\n\t\t},\n\t\tbindEvents = helpers.bindEvents = function(chartInstance, arrayOfEvents, handler){\n\t\t\t// Create the events object if it's not already present\n\t\t\tif (!chartInstance.events) chartInstance.events = {};\n\n\t\t\teach(arrayOfEvents,function(eventName){\n\t\t\t\tchartInstance.events[eventName] = function(){\n\t\t\t\t\thandler.apply(chartInstance, arguments);\n\t\t\t\t};\n\t\t\t\taddEvent(chartInstance.chart.canvas,eventName,chartInstance.events[eventName]);\n\t\t\t});\n\t\t},\n\t\tunbindEvents = helpers.unbindEvents = function (chartInstance, arrayOfEvents) {\n\t\t\teach(arrayOfEvents, function(handler,eventName){\n\t\t\t\tremoveEvent(chartInstance.chart.canvas, eventName, handler);\n\t\t\t});\n\t\t},\n\t\tgetMaximumWidth = helpers.getMaximumWidth = function(domNode){\n\t\t\tvar container = domNode.parentNode;\n\t\t\t// TODO = check cross browser stuff with this.\n\t\t\treturn container.clientWidth;\n\t\t},\n\t\tgetMaximumHeight = helpers.getMaximumHeight = function(domNode){\n\t\t\tvar container = domNode.parentNode;\n\t\t\t// TODO = check cross browser stuff with this.\n\t\t\treturn container.clientHeight;\n\t\t},\n\t\tgetMaximumSize = helpers.getMaximumSize = helpers.getMaximumWidth, // legacy support\n\t\tretinaScale = helpers.retinaScale = function(chart){\n\t\t\tvar ctx = chart.ctx,\n\t\t\t\twidth = chart.canvas.width,\n\t\t\t\theight = chart.canvas.height;\n\n\t\t\tif (window.devicePixelRatio) {\n\t\t\t\tctx.canvas.style.width = width + \"px\";\n\t\t\t\tctx.canvas.style.height = height + \"px\";\n\t\t\t\tctx.canvas.height = height * window.devicePixelRatio;\n\t\t\t\tctx.canvas.width = width * window.devicePixelRatio;\n\t\t\t\tctx.scale(window.devicePixelRatio, window.devicePixelRatio);\n\t\t\t}\n\t\t},\n\t\t//-- Canvas methods\n\t\tclear = helpers.clear = function(chart){\n\t\t\tchart.ctx.clearRect(0,0,chart.width,chart.height);\n\t\t},\n\t\tfontString = helpers.fontString = function(pixelSize,fontStyle,fontFamily){\n\t\t\treturn fontStyle + \" \" + pixelSize+\"px \" + fontFamily;\n\t\t},\n\t\tlongestText = helpers.longestText = function(ctx,font,arrayOfStrings){\n\t\t\tctx.font = font;\n\t\t\tvar longest = 0;\n\t\t\teach(arrayOfStrings,function(string){\n\t\t\t\tvar textWidth = ctx.measureText(string).width;\n\t\t\t\tlongest = (textWidth > longest) ? textWidth : longest;\n\t\t\t});\n\t\t\treturn longest;\n\t\t},\n\t\tdrawRoundedRectangle = helpers.drawRoundedRectangle = function(ctx,x,y,width,height,radius){\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x + radius, y);\n\t\t\tctx.lineTo(x + width - radius, y);\n\t\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n\t\t\tctx.lineTo(x + width, y + height - radius);\n\t\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n\t\t\tctx.lineTo(x + radius, y + height);\n\t\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n\t\t\tctx.lineTo(x, y + radius);\n\t\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t\t\tctx.closePath();\n\t\t};\n\n\n\t//Store a reference to each instance - allowing us to globally resize chart instances on window resize.\n\t//Destroy method on the chart will remove the instance of the chart from this reference.\n\tChart.instances = {};\n\n\tChart.Type = function(data,options,chart){\n\t\tthis.options = options;\n\t\tthis.chart = chart;\n\t\tthis.id = uid();\n\t\t//Add the chart instance to the global namespace\n\t\tChart.instances[this.id] = this;\n\n\t\t// Initialize is always called when a chart type is created\n\t\t// By default it is a no op, but it should be extended\n\t\tif (options.responsive){\n\t\t\tthis.resize();\n\t\t}\n\t\tthis.initialize.call(this,data);\n\t};\n\n\t//Core methods that'll be a part of every chart type\n\textend(Chart.Type.prototype,{\n\t\tinitialize : function(){return this;},\n\t\tclear : function(){\n\t\t\tclear(this.chart);\n\t\t\treturn this;\n\t\t},\n\t\tstop : function(){\n\t\t\t// Stops any current animation loop occuring\n\t\t\tcancelAnimFrame(this.animationFrame);\n\t\t\treturn this;\n\t\t},\n\t\tresize : function(callback){\n\t\t\tthis.stop();\n\t\t\tvar canvas = this.chart.canvas,\n\t\t\t\tnewWidth = getMaximumWidth(this.chart.canvas),\n\t\t\t\tnewHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : getMaximumHeight(this.chart.canvas);\n\n\t\t\tcanvas.width = this.chart.width = newWidth;\n\t\t\tcanvas.height = this.chart.height = newHeight;\n\n\t\t\tretinaScale(this.chart);\n\n\t\t\tif (typeof callback === \"function\"){\n\t\t\t\tcallback.apply(this, Array.prototype.slice.call(arguments, 1));\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\treflow : noop,\n\t\trender : function(reflow){\n\t\t\tif (reflow){\n\t\t\t\tthis.reflow();\n\t\t\t}\n\t\t\tif (this.options.animation && !reflow){\n\t\t\t\thelpers.animationLoop(\n\t\t\t\t\tthis.draw,\n\t\t\t\t\tthis.options.animationSteps,\n\t\t\t\t\tthis.options.animationEasing,\n\t\t\t\t\tthis.options.onAnimationProgress,\n\t\t\t\t\tthis.options.onAnimationComplete,\n\t\t\t\t\tthis\n\t\t\t\t);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tthis.draw();\n\t\t\t\tthis.options.onAnimationComplete.call(this);\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\tgenerateLegend : function(){\n\t\t\treturn template(this.options.legendTemplate,this);\n\t\t},\n\t\tdestroy : function(){\n\t\t\tthis.clear();\n\t\t\tunbindEvents(this, this.events);\n\t\t\tvar canvas = this.chart.canvas;\n\n\t\t\t// Reset canvas height/width attributes starts a fresh with the canvas context\n\t\t\tcanvas.width = this.chart.width;\n\t\t\tcanvas.height = this.chart.height;\n\n\t\t\t// < IE9 doesn't support removeProperty\n\t\t\tif (canvas.style.removeProperty) {\n\t\t\t\tcanvas.style.removeProperty('width');\n\t\t\t\tcanvas.style.removeProperty('height');\n\t\t\t} else {\n\t\t\t\tcanvas.style.removeAttribute('width');\n\t\t\t\tcanvas.style.removeAttribute('height');\n\t\t\t}\n\n\t\t\tdelete Chart.instances[this.id];\n\t\t},\n\t\tshowTooltip : function(ChartElements, forceRedraw){\n\t\t\t// Only redraw the chart if we've actually changed what we're hovering on.\n\t\t\tif (typeof this.activeElements === 'undefined') this.activeElements = [];\n\n\t\t\tvar isChanged = (function(Elements){\n\t\t\t\tvar changed = false;\n\n\t\t\t\tif (Elements.length !== this.activeElements.length){\n\t\t\t\t\tchanged = true;\n\t\t\t\t\treturn changed;\n\t\t\t\t}\n\n\t\t\t\teach(Elements, function(element, index){\n\t\t\t\t\tif (element !== this.activeElements[index]){\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\t\t\t\treturn changed;\n\t\t\t}).call(this, ChartElements);\n\n\t\t\tif (!isChanged && !forceRedraw){\n\t\t\t\treturn;\n\t\t\t}\n\t\t\telse{\n\t\t\t\tthis.activeElements = ChartElements;\n\t\t\t}\n\t\t\tthis.draw();\n\t\t\tif(this.options.customTooltips){\n\t\t\t\tthis.options.customTooltips(false);\n\t\t\t}\n\t\t\tif (ChartElements.length > 0){\n\t\t\t\t// If we have multiple datasets, show a MultiTooltip for all of the data points at that index\n\t\t\t\tif (this.datasets && this.datasets.length > 1) {\n\t\t\t\t\tvar dataArray,\n\t\t\t\t\t\tdataIndex;\n\n\t\t\t\t\tfor (var i = this.datasets.length - 1; i >= 0; i--) {\n\t\t\t\t\t\tdataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments;\n\t\t\t\t\t\tdataIndex = indexOf(dataArray, ChartElements[0]);\n\t\t\t\t\t\tif (dataIndex !== -1){\n\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\tvar tooltipLabels = [],\n\t\t\t\t\t\ttooltipColors = [],\n\t\t\t\t\t\tmedianPosition = (function(index) {\n\n\t\t\t\t\t\t\t// Get all the points at that particular index\n\t\t\t\t\t\t\tvar Elements = [],\n\t\t\t\t\t\t\t\tdataCollection,\n\t\t\t\t\t\t\t\txPositions = [],\n\t\t\t\t\t\t\t\tyPositions = [],\n\t\t\t\t\t\t\t\txMax,\n\t\t\t\t\t\t\t\tyMax,\n\t\t\t\t\t\t\t\txMin,\n\t\t\t\t\t\t\t\tyMin;\n\t\t\t\t\t\t\thelpers.each(this.datasets, function(dataset){\n\t\t\t\t\t\t\t\tdataCollection = dataset.points || dataset.bars || dataset.segments;\n\t\t\t\t\t\t\t\tif (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){\n\t\t\t\t\t\t\t\t\tElements.push(dataCollection[dataIndex]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\thelpers.each(Elements, function(element) {\n\t\t\t\t\t\t\t\txPositions.push(element.x);\n\t\t\t\t\t\t\t\tyPositions.push(element.y);\n\n\n\t\t\t\t\t\t\t\t//Include any colour information about the element\n\t\t\t\t\t\t\t\ttooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));\n\t\t\t\t\t\t\t\ttooltipColors.push({\n\t\t\t\t\t\t\t\t\tfill: element._saved.fillColor || element.fillColor,\n\t\t\t\t\t\t\t\t\tstroke: element._saved.strokeColor || element.strokeColor\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t}, this);\n\n\t\t\t\t\t\t\tyMin = min(yPositions);\n\t\t\t\t\t\t\tyMax = max(yPositions);\n\n\t\t\t\t\t\t\txMin = min(xPositions);\n\t\t\t\t\t\t\txMax = max(xPositions);\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tx: (xMin > this.chart.width/2) ? xMin : xMax,\n\t\t\t\t\t\t\t\ty: (yMin + yMax)/2\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}).call(this, dataIndex);\n\n\t\t\t\t\tnew Chart.MultiTooltip({\n\t\t\t\t\t\tx: medianPosition.x,\n\t\t\t\t\t\ty: medianPosition.y,\n\t\t\t\t\t\txPadding: this.options.tooltipXPadding,\n\t\t\t\t\t\tyPadding: this.options.tooltipYPadding,\n\t\t\t\t\t\txOffset: this.options.tooltipXOffset,\n\t\t\t\t\t\tfillColor: this.options.tooltipFillColor,\n\t\t\t\t\t\ttextColor: this.options.tooltipFontColor,\n\t\t\t\t\t\tfontFamily: this.options.tooltipFontFamily,\n\t\t\t\t\t\tfontStyle: this.options.tooltipFontStyle,\n\t\t\t\t\t\tfontSize: this.options.tooltipFontSize,\n\t\t\t\t\t\ttitleTextColor: this.options.tooltipTitleFontColor,\n\t\t\t\t\t\ttitleFontFamily: this.options.tooltipTitleFontFamily,\n\t\t\t\t\t\ttitleFontStyle: this.options.tooltipTitleFontStyle,\n\t\t\t\t\t\ttitleFontSize: this.options.tooltipTitleFontSize,\n\t\t\t\t\t\tcornerRadius: this.options.tooltipCornerRadius,\n\t\t\t\t\t\tlabels: tooltipLabels,\n\t\t\t\t\t\tlegendColors: tooltipColors,\n\t\t\t\t\t\tlegendColorBackground : this.options.multiTooltipKeyBackground,\n\t\t\t\t\t\ttitle: ChartElements[0].label,\n\t\t\t\t\t\tchart: this.chart,\n\t\t\t\t\t\tctx: this.chart.ctx,\n\t\t\t\t\t\tcustom: this.options.customTooltips\n\t\t\t\t\t}).draw();\n\n\t\t\t\t} else {\n\t\t\t\t\teach(ChartElements, function(Element) {\n\t\t\t\t\t\tvar tooltipPosition = Element.tooltipPosition();\n\t\t\t\t\t\tnew Chart.Tooltip({\n\t\t\t\t\t\t\tx: Math.round(tooltipPosition.x),\n\t\t\t\t\t\t\ty: Math.round(tooltipPosition.y),\n\t\t\t\t\t\t\txPadding: this.options.tooltipXPadding,\n\t\t\t\t\t\t\tyPadding: this.options.tooltipYPadding,\n\t\t\t\t\t\t\tfillColor: this.options.tooltipFillColor,\n\t\t\t\t\t\t\ttextColor: this.options.tooltipFontColor,\n\t\t\t\t\t\t\tfontFamily: this.options.tooltipFontFamily,\n\t\t\t\t\t\t\tfontStyle: this.options.tooltipFontStyle,\n\t\t\t\t\t\t\tfontSize: this.options.tooltipFontSize,\n\t\t\t\t\t\t\tcaretHeight: this.options.tooltipCaretSize,\n\t\t\t\t\t\t\tcornerRadius: this.options.tooltipCornerRadius,\n\t\t\t\t\t\t\ttext: template(this.options.tooltipTemplate, Element),\n\t\t\t\t\t\t\tchart: this.chart,\n\t\t\t\t\t\t\tcustom: this.options.customTooltips\n\t\t\t\t\t\t}).draw();\n\t\t\t\t\t}, this);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\ttoBase64Image : function(){\n\t\t\treturn this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);\n\t\t}\n\t});\n\n\tChart.Type.extend = function(extensions){\n\n\t\tvar parent = this;\n\n\t\tvar ChartType = function(){\n\t\t\treturn parent.apply(this,arguments);\n\t\t};\n\n\t\t//Copy the prototype object of the this class\n\t\tChartType.prototype = clone(parent.prototype);\n\t\t//Now overwrite some of the properties in the base class with the new extensions\n\t\textend(ChartType.prototype, extensions);\n\n\t\tChartType.extend = Chart.Type.extend;\n\n\t\tif (extensions.name || parent.prototype.name){\n\n\t\t\tvar chartName = extensions.name || parent.prototype.name;\n\t\t\t//Assign any potential default values of the new chart type\n\n\t\t\t//If none are defined, we'll use a clone of the chart type this is being extended from.\n\t\t\t//I.e. if we extend a line chart, we'll use the defaults from the line chart if our new chart\n\t\t\t//doesn't define some defaults of their own.\n\n\t\t\tvar baseDefaults = (Chart.defaults[parent.prototype.name]) ? clone(Chart.defaults[parent.prototype.name]) : {};\n\n\t\t\tChart.defaults[chartName] = extend(baseDefaults,extensions.defaults);\n\n\t\t\tChart.types[chartName] = ChartType;\n\n\t\t\t//Register this new chart type in the Chart prototype\n\t\t\tChart.prototype[chartName] = function(data,options){\n\t\t\t\tvar config = merge(Chart.defaults.global, Chart.defaults[chartName], options || {});\n\t\t\t\treturn new ChartType(data,config,this);\n\t\t\t};\n\t\t} else{\n\t\t\twarn(\"Name not provided for this chart, so it hasn't been registered\");\n\t\t}\n\t\treturn parent;\n\t};\n\n\tChart.Element = function(configuration){\n\t\textend(this,configuration);\n\t\tthis.initialize.apply(this,arguments);\n\t\tthis.save();\n\t};\n\textend(Chart.Element.prototype,{\n\t\tinitialize : function(){},\n\t\trestore : function(props){\n\t\t\tif (!props){\n\t\t\t\textend(this,this._saved);\n\t\t\t} else {\n\t\t\t\teach(props,function(key){\n\t\t\t\t\tthis[key] = this._saved[key];\n\t\t\t\t},this);\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\tsave : function(){\n\t\t\tthis._saved = clone(this);\n\t\t\tdelete this._saved._saved;\n\t\t\treturn this;\n\t\t},\n\t\tupdate : function(newProps){\n\t\t\teach(newProps,function(value,key){\n\t\t\t\tthis._saved[key] = this[key];\n\t\t\t\tthis[key] = value;\n\t\t\t},this);\n\t\t\treturn this;\n\t\t},\n\t\ttransition : function(props,ease){\n\t\t\teach(props,function(value,key){\n\t\t\t\tthis[key] = ((value - this._saved[key]) * ease) + this._saved[key];\n\t\t\t},this);\n\t\t\treturn this;\n\t\t},\n\t\ttooltipPosition : function(){\n\t\t\treturn {\n\t\t\t\tx : this.x,\n\t\t\t\ty : this.y\n\t\t\t};\n\t\t},\n\t\thasValue: function(){\n\t\t\treturn isNumber(this.value);\n\t\t}\n\t});\n\n\tChart.Element.extend = inherits;\n\n\n\tChart.Point = Chart.Element.extend({\n\t\tdisplay: true,\n\t\tinRange: function(chartX,chartY){\n\t\t\tvar hitDetectionRange = this.hitDetectionRadius + this.radius;\n\t\t\treturn ((Math.pow(chartX-this.x, 2)+Math.pow(chartY-this.y, 2)) < Math.pow(hitDetectionRange,2));\n\t\t},\n\t\tdraw : function(){\n\t\t\tif (this.display){\n\t\t\t\tvar ctx = this.ctx;\n\t\t\t\tctx.beginPath();\n\n\t\t\t\tctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);\n\t\t\t\tctx.closePath();\n\n\t\t\t\tctx.strokeStyle = this.strokeColor;\n\t\t\t\tctx.lineWidth = this.strokeWidth;\n\n\t\t\t\tctx.fillStyle = this.fillColor;\n\n\t\t\t\tctx.fill();\n\t\t\t\tctx.stroke();\n\t\t\t}\n\n\n\t\t\t//Quick debug for bezier curve splining\n\t\t\t//Highlights control points and the line between them.\n\t\t\t//Handy for dev - stripped in the min version.\n\n\t\t\t// ctx.save();\n\t\t\t// ctx.fillStyle = \"black\";\n\t\t\t// ctx.strokeStyle = \"black\"\n\t\t\t// ctx.beginPath();\n\t\t\t// ctx.arc(this.controlPoints.inner.x,this.controlPoints.inner.y, 2, 0, Math.PI*2);\n\t\t\t// ctx.fill();\n\n\t\t\t// ctx.beginPath();\n\t\t\t// ctx.arc(this.controlPoints.outer.x,this.controlPoints.outer.y, 2, 0, Math.PI*2);\n\t\t\t// ctx.fill();\n\n\t\t\t// ctx.moveTo(this.controlPoints.inner.x,this.controlPoints.inner.y);\n\t\t\t// ctx.lineTo(this.x, this.y);\n\t\t\t// ctx.lineTo(this.controlPoints.outer.x,this.controlPoints.outer.y);\n\t\t\t// ctx.stroke();\n\n\t\t\t// ctx.restore();\n\n\n\n\t\t}\n\t});\n\n\tChart.Arc = Chart.Element.extend({\n\t\tinRange : function(chartX,chartY){\n\n\t\t\tvar pointRelativePosition = helpers.getAngleFromPoint(this, {\n\t\t\t\tx: chartX,\n\t\t\t\ty: chartY\n\t\t\t});\n\n\t\t\t//Check if within the range of the open/close angle\n\t\t\tvar betweenAngles = (pointRelativePosition.angle >= this.startAngle && pointRelativePosition.angle <= this.endAngle),\n\t\t\t\twithinRadius = (pointRelativePosition.distance >= this.innerRadius && pointRelativePosition.distance <= this.outerRadius);\n\n\t\t\treturn (betweenAngles && withinRadius);\n\t\t\t//Ensure within the outside of the arc centre, but inside arc outer\n\t\t},\n\t\ttooltipPosition : function(){\n\t\t\tvar centreAngle = this.startAngle + ((this.endAngle - this.startAngle) / 2),\n\t\t\t\trangeFromCentre = (this.outerRadius - this.innerRadius) / 2 + this.innerRadius;\n\t\t\treturn {\n\t\t\t\tx : this.x + (Math.cos(centreAngle) * rangeFromCentre),\n\t\t\t\ty : this.y + (Math.sin(centreAngle) * rangeFromCentre)\n\t\t\t};\n\t\t},\n\t\tdraw : function(animationPercent){\n\n\t\t\tvar easingDecimal = animationPercent || 1;\n\n\t\t\tvar ctx = this.ctx;\n\n\t\t\tctx.beginPath();\n\n\t\t\tctx.arc(this.x, this.y, this.outerRadius, this.startAngle, this.endAngle);\n\n\t\t\tctx.arc(this.x, this.y, this.innerRadius, this.endAngle, this.startAngle, true);\n\n\t\t\tctx.closePath();\n\t\t\tctx.strokeStyle = this.strokeColor;\n\t\t\tctx.lineWidth = this.strokeWidth;\n\n\t\t\tctx.fillStyle = this.fillColor;\n\n\t\t\tctx.fill();\n\t\t\tctx.lineJoin = 'bevel';\n\n\t\t\tif (this.showStroke){\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t}\n\t});\n\n\tChart.Rectangle = Chart.Element.extend({\n\t\tdraw : function(){\n\t\t\tvar ctx = this.ctx,\n\t\t\t\thalfWidth = this.width/2,\n\t\t\t\tleftX = this.x - halfWidth,\n\t\t\t\trightX = this.x + halfWidth,\n\t\t\t\ttop = this.base - (this.base - this.y),\n\t\t\t\thalfStroke = this.strokeWidth / 2;\n\n\t\t\t// Canvas doesn't allow us to stroke inside the width so we can\n\t\t\t// adjust the sizes to fit if we're setting a stroke on the line\n\t\t\tif (this.showStroke){\n\t\t\t\tleftX += halfStroke;\n\t\t\t\trightX -= halfStroke;\n\t\t\t\ttop += halfStroke;\n\t\t\t}\n\n\t\t\tctx.beginPath();\n\n\t\t\tctx.fillStyle = this.fillColor;\n\t\t\tctx.strokeStyle = this.strokeColor;\n\t\t\tctx.lineWidth = this.strokeWidth;\n\n\t\t\t// It'd be nice to keep this class totally generic to any rectangle\n\t\t\t// and simply specify which border to miss out.\n\t\t\tctx.moveTo(leftX, this.base);\n\t\t\tctx.lineTo(leftX, top);\n\t\t\tctx.lineTo(rightX, top);\n\t\t\tctx.lineTo(rightX, this.base);\n\t\t\tctx.fill();\n\t\t\tif (this.showStroke){\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t},\n\t\theight : function(){\n\t\t\treturn this.base - this.y;\n\t\t},\n\t\tinRange : function(chartX,chartY){\n\t\t\treturn (chartX >= this.x - this.width/2 && chartX <= this.x + this.width/2) && (chartY >= this.y && chartY <= this.base);\n\t\t}\n\t});\n\n\tChart.Tooltip = Chart.Element.extend({\n\t\tdraw : function(){\n\n\t\t\tvar ctx = this.chart.ctx;\n\n\t\t\tctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);\n\n\t\t\tthis.xAlign = \"center\";\n\t\t\tthis.yAlign = \"above\";\n\n\t\t\t//Distance between the actual element.y position and the start of the tooltip caret\n\t\t\tvar caretPadding = this.caretPadding = 2;\n\n\t\t\tvar tooltipWidth = ctx.measureText(this.text).width + 2*this.xPadding,\n\t\t\t\ttooltipRectHeight = this.fontSize + 2*this.yPadding,\n\t\t\t\ttooltipHeight = tooltipRectHeight + this.caretHeight + caretPadding;\n\n\t\t\tif (this.x + tooltipWidth/2 >this.chart.width){\n\t\t\t\tthis.xAlign = \"left\";\n\t\t\t} else if (this.x - tooltipWidth/2 < 0){\n\t\t\t\tthis.xAlign = \"right\";\n\t\t\t}\n\n\t\t\tif (this.y - tooltipHeight < 0){\n\t\t\t\tthis.yAlign = \"below\";\n\t\t\t}\n\n\n\t\t\tvar tooltipX = this.x - tooltipWidth/2,\n\t\t\t\ttooltipY = this.y - tooltipHeight;\n\n\t\t\tctx.fillStyle = this.fillColor;\n\n\t\t\t// Custom Tooltips\n\t\t\tif(this.custom){\n\t\t\t\tthis.custom(this);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tswitch(this.yAlign)\n\t\t\t\t{\n\t\t\t\tcase \"above\":\n\t\t\t\t\t//Draw a caret above the x/y\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(this.x,this.y - caretPadding);\n\t\t\t\t\tctx.lineTo(this.x + this.caretHeight, this.y - (caretPadding + this.caretHeight));\n\t\t\t\t\tctx.lineTo(this.x - this.caretHeight, this.y - (caretPadding + this.caretHeight));\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tctx.fill();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"below\":\n\t\t\t\t\ttooltipY = this.y + caretPadding + this.caretHeight;\n\t\t\t\t\t//Draw a caret below the x/y\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(this.x, this.y + caretPadding);\n\t\t\t\t\tctx.lineTo(this.x + this.caretHeight, this.y + caretPadding + this.caretHeight);\n\t\t\t\t\tctx.lineTo(this.x - this.caretHeight, this.y + caretPadding + this.caretHeight);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tctx.fill();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tswitch(this.xAlign)\n\t\t\t\t{\n\t\t\t\tcase \"left\":\n\t\t\t\t\ttooltipX = this.x - tooltipWidth + (this.cornerRadius + this.caretHeight);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"right\":\n\t\t\t\t\ttooltipX = this.x - (this.cornerRadius + this.caretHeight);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdrawRoundedRectangle(ctx,tooltipX,tooltipY,tooltipWidth,tooltipRectHeight,this.cornerRadius);\n\n\t\t\t\tctx.fill();\n\n\t\t\t\tctx.fillStyle = this.textColor;\n\t\t\t\tctx.textAlign = \"center\";\n\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\tctx.fillText(this.text, tooltipX + tooltipWidth/2, tooltipY + tooltipRectHeight/2);\n\t\t\t}\n\t\t}\n\t});\n\n\tChart.MultiTooltip = Chart.Element.extend({\n\t\tinitialize : function(){\n\t\t\tthis.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);\n\n\t\t\tthis.titleFont = fontString(this.titleFontSize,this.titleFontStyle,this.titleFontFamily);\n\n\t\t\tthis.height = (this.labels.length * this.fontSize) + ((this.labels.length-1) * (this.fontSize/2)) + (this.yPadding*2) + this.titleFontSize *1.5;\n\n\t\t\tthis.ctx.font = this.titleFont;\n\n\t\t\tvar titleWidth = this.ctx.measureText(this.title).width,\n\t\t\t\t//Label has a legend square as well so account for this.\n\t\t\t\tlabelWidth = longestText(this.ctx,this.font,this.labels) + this.fontSize + 3,\n\t\t\t\tlongestTextWidth = max([labelWidth,titleWidth]);\n\n\t\t\tthis.width = longestTextWidth + (this.xPadding*2);\n\n\n\t\t\tvar halfHeight = this.height/2;\n\n\t\t\t//Check to ensure the height will fit on the canvas\n\t\t\tif (this.y - halfHeight < 0 ){\n\t\t\t\tthis.y = halfHeight;\n\t\t\t} else if (this.y + halfHeight > this.chart.height){\n\t\t\t\tthis.y = this.chart.height - halfHeight;\n\t\t\t}\n\n\t\t\t//Decide whether to align left or right based on position on canvas\n\t\t\tif (this.x > this.chart.width/2){\n\t\t\t\tthis.x -= this.xOffset + this.width;\n\t\t\t} else {\n\t\t\t\tthis.x += this.xOffset;\n\t\t\t}\n\n\n\t\t},\n\t\tgetLineHeight : function(index){\n\t\t\tvar baseLineHeight = this.y - (this.height/2) + this.yPadding,\n\t\t\t\tafterTitleIndex = index-1;\n\n\t\t\t//If the index is zero, we're getting the title\n\t\t\tif (index === 0){\n\t\t\t\treturn baseLineHeight + this.titleFontSize/2;\n\t\t\t} else{\n\t\t\t\treturn baseLineHeight + ((this.fontSize*1.5*afterTitleIndex) + this.fontSize/2) + this.titleFontSize * 1.5;\n\t\t\t}\n\n\t\t},\n\t\tdraw : function(){\n\t\t\t// Custom Tooltips\n\t\t\tif(this.custom){\n\t\t\t\tthis.custom(this);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tdrawRoundedRectangle(this.ctx,this.x,this.y - this.height/2,this.width,this.height,this.cornerRadius);\n\t\t\t\tvar ctx = this.ctx;\n\t\t\t\tctx.fillStyle = this.fillColor;\n\t\t\t\tctx.fill();\n\t\t\t\tctx.closePath();\n\n\t\t\t\tctx.textAlign = \"left\";\n\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\tctx.fillStyle = this.titleTextColor;\n\t\t\t\tctx.font = this.titleFont;\n\n\t\t\t\tctx.fillText(this.title,this.x + this.xPadding, this.getLineHeight(0));\n\n\t\t\t\tctx.font = this.font;\n\t\t\t\thelpers.each(this.labels,function(label,index){\n\t\t\t\t\tctx.fillStyle = this.textColor;\n\t\t\t\t\tctx.fillText(label,this.x + this.xPadding + this.fontSize + 3, this.getLineHeight(index + 1));\n\n\t\t\t\t\t//A bit gnarly, but clearing this rectangle breaks when using explorercanvas (clears whole canvas)\n\t\t\t\t\t//ctx.clearRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);\n\t\t\t\t\t//Instead we'll make a white filled block to put the legendColour palette over.\n\n\t\t\t\t\tctx.fillStyle = this.legendColorBackground;\n\t\t\t\t\tctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);\n\n\t\t\t\t\tctx.fillStyle = this.legendColors[index].fill;\n\t\t\t\t\tctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);\n\n\n\t\t\t\t},this);\n\t\t\t}\n\t\t}\n\t});\n\n\tChart.Scale = Chart.Element.extend({\n\t\tinitialize : function(){\n\t\t\tthis.fit();\n\t\t},\n\t\tbuildYLabels : function(){\n\t\t\tthis.yLabels = [];\n\n\t\t\tvar stepDecimalPlaces = getDecimalPlaces(this.stepValue);\n\n\t\t\tfor (var i=0; i<=this.steps; i++){\n\t\t\t\tthis.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));\n\t\t\t}\n\t\t\tthis.yLabelWidth = (this.display && this.showLabels) ? longestText(this.ctx,this.font,this.yLabels) : 0;\n\t\t},\n\t\taddXLabel : function(label){\n\t\t\tthis.xLabels.push(label);\n\t\t\tthis.valuesCount++;\n\t\t\tthis.fit();\n\t\t},\n\t\tremoveXLabel : function(){\n\t\t\tthis.xLabels.shift();\n\t\t\tthis.valuesCount--;\n\t\t\tthis.fit();\n\t\t},\n\t\t// Fitting loop to rotate x Labels and figure out what fits there, and also calculate how many Y steps to use\n\t\tfit: function(){\n\t\t\t// First we need the width of the yLabels, assuming the xLabels aren't rotated\n\n\t\t\t// To do that we need the base line at the top and base of the chart, assuming there is no x label rotation\n\t\t\tthis.startPoint = (this.display) ? this.fontSize : 0;\n\t\t\tthis.endPoint = (this.display) ? this.height - (this.fontSize * 1.5) - 5 : this.height; // -5 to pad labels\n\n\t\t\t// Apply padding settings to the start and end point.\n\t\t\tthis.startPoint += this.padding;\n\t\t\tthis.endPoint -= this.padding;\n\n\t\t\t// Cache the starting height, so can determine if we need to recalculate the scale yAxis\n\t\t\tvar cachedHeight = this.endPoint - this.startPoint,\n\t\t\t\tcachedYLabelWidth;\n\n\t\t\t// Build the current yLabels so we have an idea of what size they'll be to start\n\t\t\t/*\n\t\t\t *\tThis sets what is returned from calculateScaleRange as static properties of this class:\n\t\t\t *\n\t\t\t\tthis.steps;\n\t\t\t\tthis.stepValue;\n\t\t\t\tthis.min;\n\t\t\t\tthis.max;\n\t\t\t *\n\t\t\t */\n\t\t\tthis.calculateYRange(cachedHeight);\n\n\t\t\t// With these properties set we can now build the array of yLabels\n\t\t\t// and also the width of the largest yLabel\n\t\t\tthis.buildYLabels();\n\n\t\t\tthis.calculateXLabelRotation();\n\n\t\t\twhile((cachedHeight > this.endPoint - this.startPoint)){\n\t\t\t\tcachedHeight = this.endPoint - this.startPoint;\n\t\t\t\tcachedYLabelWidth = this.yLabelWidth;\n\n\t\t\t\tthis.calculateYRange(cachedHeight);\n\t\t\t\tthis.buildYLabels();\n\n\t\t\t\t// Only go through the xLabel loop again if the yLabel width has changed\n\t\t\t\tif (cachedYLabelWidth < this.yLabelWidth){\n\t\t\t\t\tthis.calculateXLabelRotation();\n\t\t\t\t}\n\t\t\t}\n\n\t\t},\n\t\tcalculateXLabelRotation : function(){\n\t\t\t//Get the width of each grid by calculating the difference\n\t\t\t//between x offsets between 0 and 1.\n\n\t\t\tthis.ctx.font = this.font;\n\n\t\t\tvar firstWidth = this.ctx.measureText(this.xLabels[0]).width,\n\t\t\t\tlastWidth = this.ctx.measureText(this.xLabels[this.xLabels.length - 1]).width,\n\t\t\t\tfirstRotated,\n\t\t\t\tlastRotated;\n\n\n\t\t\tthis.xScalePaddingRight = lastWidth/2 + 3;\n\t\t\tthis.xScalePaddingLeft = (firstWidth/2 > this.yLabelWidth + 10) ? firstWidth/2 : this.yLabelWidth + 10;\n\n\t\t\tthis.xLabelRotation = 0;\n\t\t\tif (this.display){\n\t\t\t\tvar originalLabelWidth = longestText(this.ctx,this.font,this.xLabels),\n\t\t\t\t\tcosRotation,\n\t\t\t\t\tfirstRotatedWidth;\n\t\t\t\tthis.xLabelWidth = originalLabelWidth;\n\t\t\t\t//Allow 3 pixels x2 padding either side for label readability\n\t\t\t\tvar xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6;\n\n\t\t\t\t//Max label rotate should be 90 - also act as a loop counter\n\t\t\t\twhile ((this.xLabelWidth > xGridWidth && this.xLabelRotation === 0) || (this.xLabelWidth > xGridWidth && this.xLabelRotation <= 90 && this.xLabelRotation > 0)){\n\t\t\t\t\tcosRotation = Math.cos(toRadians(this.xLabelRotation));\n\n\t\t\t\t\tfirstRotated = cosRotation * firstWidth;\n\t\t\t\t\tlastRotated = cosRotation * lastWidth;\n\n\t\t\t\t\t// We're right aligning the text now.\n\t\t\t\t\tif (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8){\n\t\t\t\t\t\tthis.xScalePaddingLeft = firstRotated + this.fontSize / 2;\n\t\t\t\t\t}\n\t\t\t\t\tthis.xScalePaddingRight = this.fontSize/2;\n\n\n\t\t\t\t\tthis.xLabelRotation++;\n\t\t\t\t\tthis.xLabelWidth = cosRotation * originalLabelWidth;\n\n\t\t\t\t}\n\t\t\t\tif (this.xLabelRotation > 0){\n\t\t\t\t\tthis.endPoint -= Math.sin(toRadians(this.xLabelRotation))*originalLabelWidth + 3;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse{\n\t\t\t\tthis.xLabelWidth = 0;\n\t\t\t\tthis.xScalePaddingRight = this.padding;\n\t\t\t\tthis.xScalePaddingLeft = this.padding;\n\t\t\t}\n\n\t\t},\n\t\t// Needs to be overidden in each Chart type\n\t\t// Otherwise we need to pass all the data into the scale class\n\t\tcalculateYRange: noop,\n\t\tdrawingArea: function(){\n\t\t\treturn this.startPoint - this.endPoint;\n\t\t},\n\t\tcalculateY : function(value){\n\t\t\tvar scalingFactor = this.drawingArea() / (this.min - this.max);\n\t\t\treturn this.endPoint - (scalingFactor * (value - this.min));\n\t\t},\n\t\tcalculateX : function(index){\n\t\t\tvar isRotated = (this.xLabelRotation > 0),\n\t\t\t\t// innerWidth = (this.offsetGridLines) ? this.width - offsetLeft - this.padding : this.width - (offsetLeft + halfLabelWidth * 2) - this.padding,\n\t\t\t\tinnerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight),\n\t\t\t\tvalueWidth = innerWidth/Math.max((this.valuesCount - ((this.offsetGridLines) ? 0 : 1)), 1),\n\t\t\t\tvalueOffset = (valueWidth * index) + this.xScalePaddingLeft;\n\n\t\t\tif (this.offsetGridLines){\n\t\t\t\tvalueOffset += (valueWidth/2);\n\t\t\t}\n\n\t\t\treturn Math.round(valueOffset);\n\t\t},\n\t\tupdate : function(newProps){\n\t\t\thelpers.extend(this, newProps);\n\t\t\tthis.fit();\n\t\t},\n\t\tdraw : function(){\n\t\t\tvar ctx = this.ctx,\n\t\t\t\tyLabelGap = (this.endPoint - this.startPoint) / this.steps,\n\t\t\t\txStart = Math.round(this.xScalePaddingLeft);\n\t\t\tif (this.display){\n\t\t\t\tctx.fillStyle = this.textColor;\n\t\t\t\tctx.font = this.font;\n\t\t\t\teach(this.yLabels,function(labelString,index){\n\t\t\t\t\tvar yLabelCenter = this.endPoint - (yLabelGap * index),\n\t\t\t\t\t\tlinePositionY = Math.round(yLabelCenter),\n\t\t\t\t\t\tdrawHorizontalLine = this.showHorizontalLines;\n\n\t\t\t\t\tctx.textAlign = \"right\";\n\t\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\t\tif (this.showLabels){\n\t\t\t\t\t\tctx.fillText(labelString,xStart - 10,yLabelCenter);\n\t\t\t\t\t}\n\n\t\t\t\t\t// This is X axis, so draw it\n\t\t\t\t\tif (index === 0 && !drawHorizontalLine){\n\t\t\t\t\t\tdrawHorizontalLine = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawHorizontalLine){\n\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (index > 0){\n\t\t\t\t\t\t// This is a grid line in the centre, so drop that\n\t\t\t\t\t\tctx.lineWidth = this.gridLineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.gridLineColor;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// This is the first line on the scale\n\t\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\t}\n\n\t\t\t\t\tlinePositionY += helpers.aliasPixel(ctx.lineWidth);\n\n\t\t\t\t\tif(drawHorizontalLine){\n\t\t\t\t\t\tctx.moveTo(xStart, linePositionY);\n\t\t\t\t\t\tctx.lineTo(this.width, linePositionY);\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(xStart - 5, linePositionY);\n\t\t\t\t\tctx.lineTo(xStart, linePositionY);\n\t\t\t\t\tctx.stroke();\n\t\t\t\t\tctx.closePath();\n\n\t\t\t\t},this);\n\n\t\t\t\teach(this.xLabels,function(label,index){\n\t\t\t\t\tvar xPos = this.calculateX(index) + aliasPixel(this.lineWidth),\n\t\t\t\t\t\t// Check to see if line/bar here and decide where to place the line\n\t\t\t\t\t\tlinePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth),\n\t\t\t\t\t\tisRotated = (this.xLabelRotation > 0),\n\t\t\t\t\t\tdrawVerticalLine = this.showVerticalLines;\n\n\t\t\t\t\t// This is Y axis, so draw it\n\t\t\t\t\tif (index === 0 && !drawVerticalLine){\n\t\t\t\t\t\tdrawVerticalLine = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawVerticalLine){\n\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (index > 0){\n\t\t\t\t\t\t// This is a grid line in the centre, so drop that\n\t\t\t\t\t\tctx.lineWidth = this.gridLineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.gridLineColor;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// This is the first line on the scale\n\t\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawVerticalLine){\n\t\t\t\t\t\tctx.moveTo(linePos,this.endPoint);\n\t\t\t\t\t\tctx.lineTo(linePos,this.startPoint - 3);\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t}\n\n\n\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\n\n\t\t\t\t\t// Small lines at the bottom of the base grid line\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(linePos,this.endPoint);\n\t\t\t\t\tctx.lineTo(linePos,this.endPoint + 5);\n\t\t\t\t\tctx.stroke();\n\t\t\t\t\tctx.closePath();\n\n\t\t\t\t\tctx.save();\n\t\t\t\t\tctx.translate(xPos,(isRotated) ? this.endPoint + 12 : this.endPoint + 8);\n\t\t\t\t\tctx.rotate(toRadians(this.xLabelRotation)*-1);\n\t\t\t\t\tctx.font = this.font;\n\t\t\t\t\tctx.textAlign = (isRotated) ? \"right\" : \"center\";\n\t\t\t\t\tctx.textBaseline = (isRotated) ? \"middle\" : \"top\";\n\t\t\t\t\tctx.fillText(label, 0, 0);\n\t\t\t\t\tctx.restore();\n\t\t\t\t},this);\n\n\t\t\t}\n\t\t}\n\n\t});\n\n\tChart.RadialScale = Chart.Element.extend({\n\t\tinitialize: function(){\n\t\t\tthis.size = min([this.height, this.width]);\n\t\t\tthis.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);\n\t\t},\n\t\tcalculateCenterOffset: function(value){\n\t\t\t// Take into account half font size + the yPadding of the top value\n\t\t\tvar scalingFactor = this.drawingArea / (this.max - this.min);\n\n\t\t\treturn (value - this.min) * scalingFactor;\n\t\t},\n\t\tupdate : function(){\n\t\t\tif (!this.lineArc){\n\t\t\t\tthis.setScaleSize();\n\t\t\t} else {\n\t\t\t\tthis.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);\n\t\t\t}\n\t\t\tthis.buildYLabels();\n\t\t},\n\t\tbuildYLabels: function(){\n\t\t\tthis.yLabels = [];\n\n\t\t\tvar stepDecimalPlaces = getDecimalPlaces(this.stepValue);\n\n\t\t\tfor (var i=0; i<=this.steps; i++){\n\t\t\t\tthis.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));\n\t\t\t}\n\t\t},\n\t\tgetCircumference : function(){\n\t\t\treturn ((Math.PI*2) / this.valuesCount);\n\t\t},\n\t\tsetScaleSize: function(){\n\t\t\t/*\n\t\t\t * Right, this is really confusing and there is a lot of maths going on here\n\t\t\t * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9\n\t\t\t *\n\t\t\t * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif\n\t\t\t *\n\t\t\t * Solution:\n\t\t\t *\n\t\t\t * We assume the radius of the polygon is half the size of the canvas at first\n\t\t\t * at each index we check if the text overlaps.\n\t\t\t *\n\t\t\t * Where it does, we store that angle and that index.\n\t\t\t *\n\t\t\t * After finding the largest index and angle we calculate how much we need to remove\n\t\t\t * from the shape radius to move the point inwards by that x.\n\t\t\t *\n\t\t\t * We average the left and right distances to get the maximum shape radius that can fit in the box\n\t\t\t * along with labels.\n\t\t\t *\n\t\t\t * Once we have that, we can find the centre point for the chart, by taking the x text protrusion\n\t\t\t * on each side, removing that from the size, halving it and adding the left x protrusion width.\n\t\t\t *\n\t\t\t * This will mean we have a shape fitted to the canvas, as large as it can be with the labels\n\t\t\t * and position it in the most space efficient manner\n\t\t\t *\n\t\t\t * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif\n\t\t\t */\n\n\n\t\t\t// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.\n\t\t\t// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points\n\t\t\tvar largestPossibleRadius = min([(this.height/2 - this.pointLabelFontSize - 5), this.width/2]),\n\t\t\t\tpointPosition,\n\t\t\t\ti,\n\t\t\t\ttextWidth,\n\t\t\t\thalfTextWidth,\n\t\t\t\tfurthestRight = this.width,\n\t\t\t\tfurthestRightIndex,\n\t\t\t\tfurthestRightAngle,\n\t\t\t\tfurthestLeft = 0,\n\t\t\t\tfurthestLeftIndex,\n\t\t\t\tfurthestLeftAngle,\n\t\t\t\txProtrusionLeft,\n\t\t\t\txProtrusionRight,\n\t\t\t\tradiusReductionRight,\n\t\t\t\tradiusReductionLeft,\n\t\t\t\tmaxWidthRadius;\n\t\t\tthis.ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);\n\t\t\tfor (i=0;i<this.valuesCount;i++){\n\t\t\t\t// 5px to space the text slightly out - similar to what we do in the draw function.\n\t\t\t\tpointPosition = this.getPointPosition(i, largestPossibleRadius);\n\t\t\t\ttextWidth = this.ctx.measureText(template(this.templateString, { value: this.labels[i] })).width + 5;\n\t\t\t\tif (i === 0 || i === this.valuesCount/2){\n\t\t\t\t\t// If we're at index zero, or exactly the middle, we're at exactly the top/bottom\n\t\t\t\t\t// of the radar chart, so text will be aligned centrally, so we'll half it and compare\n\t\t\t\t\t// w/left and right text sizes\n\t\t\t\t\thalfTextWidth = textWidth/2;\n\t\t\t\t\tif (pointPosition.x + halfTextWidth > furthestRight) {\n\t\t\t\t\t\tfurthestRight = pointPosition.x + halfTextWidth;\n\t\t\t\t\t\tfurthestRightIndex = i;\n\t\t\t\t\t}\n\t\t\t\t\tif (pointPosition.x - halfTextWidth < furthestLeft) {\n\t\t\t\t\t\tfurthestLeft = pointPosition.x - halfTextWidth;\n\t\t\t\t\t\tfurthestLeftIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (i < this.valuesCount/2) {\n\t\t\t\t\t// Less than half the values means we'll left align the text\n\t\t\t\t\tif (pointPosition.x + textWidth > furthestRight) {\n\t\t\t\t\t\tfurthestRight = pointPosition.x + textWidth;\n\t\t\t\t\t\tfurthestRightIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (i > this.valuesCount/2){\n\t\t\t\t\t// More than half the values means we'll right align the text\n\t\t\t\t\tif (pointPosition.x - textWidth < furthestLeft) {\n\t\t\t\t\t\tfurthestLeft = pointPosition.x - textWidth;\n\t\t\t\t\t\tfurthestLeftIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\txProtrusionLeft = furthestLeft;\n\n\t\t\txProtrusionRight = Math.ceil(furthestRight - this.width);\n\n\t\t\tfurthestRightAngle = this.getIndexAngle(furthestRightIndex);\n\n\t\t\tfurthestLeftAngle = this.getIndexAngle(furthestLeftIndex);\n\n\t\t\tradiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI/2);\n\n\t\t\tradiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI/2);\n\n\t\t\t// Ensure we actually need to reduce the size of the chart\n\t\t\tradiusReductionRight = (isNumber(radiusReductionRight)) ? radiusReductionRight : 0;\n\t\t\tradiusReductionLeft = (isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;\n\n\t\t\tthis.drawingArea = largestPossibleRadius - (radiusReductionLeft + radiusReductionRight)/2;\n\n\t\t\t//this.drawingArea = min([maxWidthRadius, (this.height - (2 * (this.pointLabelFontSize + 5)))/2])\n\t\t\tthis.setCenterPoint(radiusReductionLeft, radiusReductionRight);\n\n\t\t},\n\t\tsetCenterPoint: function(leftMovement, rightMovement){\n\n\t\t\tvar maxRight = this.width - rightMovement - this.drawingArea,\n\t\t\t\tmaxLeft = leftMovement + this.drawingArea;\n\n\t\t\tthis.xCenter = (maxLeft + maxRight)/2;\n\t\t\t// Always vertically in the centre as the text height doesn't change\n\t\t\tthis.yCenter = (this.height/2);\n\t\t},\n\n\t\tgetIndexAngle : function(index){\n\t\t\tvar angleMultiplier = (Math.PI * 2) / this.valuesCount;\n\t\t\t// Start from the top instead of right, so remove a quarter of the circle\n\n\t\t\treturn index * angleMultiplier - (Math.PI/2);\n\t\t},\n\t\tgetPointPosition : function(index, distanceFromCenter){\n\t\t\tvar thisAngle = this.getIndexAngle(index);\n\t\t\treturn {\n\t\t\t\tx : (Math.cos(thisAngle) * distanceFromCenter) + this.xCenter,\n\t\t\t\ty : (Math.sin(thisAngle) * distanceFromCenter) + this.yCenter\n\t\t\t};\n\t\t},\n\t\tdraw: function(){\n\t\t\tif (this.display){\n\t\t\t\tvar ctx = this.ctx;\n\t\t\t\teach(this.yLabels, function(label, index){\n\t\t\t\t\t// Don't draw a centre value\n\t\t\t\t\tif (index > 0){\n\t\t\t\t\t\tvar yCenterOffset = index * (this.drawingArea/this.steps),\n\t\t\t\t\t\t\tyHeight = this.yCenter - yCenterOffset,\n\t\t\t\t\t\t\tpointPosition;\n\n\t\t\t\t\t\t// Draw circular lines around the scale\n\t\t\t\t\t\tif (this.lineWidth > 0){\n\t\t\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\n\t\t\t\t\t\t\tif(this.lineArc){\n\t\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\t\tctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI*2);\n\t\t\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\t\t} else{\n\t\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\t\tfor (var i=0;i<this.valuesCount;i++)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tpointPosition = this.getPointPosition(i, this.calculateCenterOffset(this.min + (index * this.stepValue)));\n\t\t\t\t\t\t\t\t\tif (i === 0){\n\t\t\t\t\t\t\t\t\t\tctx.moveTo(pointPosition.x, pointPosition.y);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tctx.lineTo(pointPosition.x, pointPosition.y);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(this.showLabels){\n\t\t\t\t\t\t\tctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);\n\t\t\t\t\t\t\tif (this.showLabelBackdrop){\n\t\t\t\t\t\t\t\tvar labelWidth = ctx.measureText(label).width;\n\t\t\t\t\t\t\t\tctx.fillStyle = this.backdropColor;\n\t\t\t\t\t\t\t\tctx.fillRect(\n\t\t\t\t\t\t\t\t\tthis.xCenter - labelWidth/2 - this.backdropPaddingX,\n\t\t\t\t\t\t\t\t\tyHeight - this.fontSize/2 - this.backdropPaddingY,\n\t\t\t\t\t\t\t\t\tlabelWidth + this.backdropPaddingX*2,\n\t\t\t\t\t\t\t\t\tthis.fontSize + this.backdropPaddingY*2\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\t\t\t\tctx.fillStyle = this.fontColor;\n\t\t\t\t\t\t\tctx.fillText(label, this.xCenter, yHeight);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\n\t\t\t\tif (!this.lineArc){\n\t\t\t\t\tctx.lineWidth = this.angleLineWidth;\n\t\t\t\t\tctx.strokeStyle = this.angleLineColor;\n\t\t\t\t\tfor (var i = this.valuesCount - 1; i >= 0; i--) {\n\t\t\t\t\t\tif (this.angleLineWidth > 0){\n\t\t\t\t\t\t\tvar outerPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max));\n\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\tctx.moveTo(this.xCenter, this.yCenter);\n\t\t\t\t\t\t\tctx.lineTo(outerPosition.x, outerPosition.y);\n\t\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Extra 3px out for some label spacing\n\t\t\t\t\t\tvar pointLabelPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max) + 5);\n\t\t\t\t\t\tctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);\n\t\t\t\t\t\tctx.fillStyle = this.pointLabelFontColor;\n\n\t\t\t\t\t\tvar labelsCount = this.labels.length,\n\t\t\t\t\t\t\thalfLabelsCount = this.labels.length/2,\n\t\t\t\t\t\t\tquarterLabelsCount = halfLabelsCount/2,\n\t\t\t\t\t\t\tupperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),\n\t\t\t\t\t\t\texactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);\n\t\t\t\t\t\tif (i === 0){\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t} else if(i === halfLabelsCount){\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t} else if (i < halfLabelsCount){\n\t\t\t\t\t\t\tctx.textAlign = 'left';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tctx.textAlign = 'right';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Set the correct text baseline based on outer positioning\n\t\t\t\t\t\tif (exactQuarter){\n\t\t\t\t\t\t\tctx.textBaseline = 'middle';\n\t\t\t\t\t\t} else if (upperHalf){\n\t\t\t\t\t\t\tctx.textBaseline = 'bottom';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tctx.textBaseline = 'top';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tctx.fillText(this.labels[i], pointLabelPosition.x, pointLabelPosition.y);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\t// Attach global event to resize each chart instance when the browser resizes\n\thelpers.addEvent(window, \"resize\", (function(){\n\t\t// Basic debounce of resize function so it doesn't hurt performance when resizing browser.\n\t\tvar timeout;\n\t\treturn function(){\n\t\t\tclearTimeout(timeout);\n\t\t\ttimeout = setTimeout(function(){\n\t\t\t\teach(Chart.instances,function(instance){\n\t\t\t\t\t// If the responsive flag is set in the chart instance config\n\t\t\t\t\t// Cascade the resize event down to the chart.\n\t\t\t\t\tif (instance.options.responsive){\n\t\t\t\t\t\tinstance.resize(instance.render, true);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}, 50);\n\t\t};\n\t})());\n\n\n\tif (amd) {\n\t\tdefine(function(){\n\t\t\treturn Chart;\n\t\t});\n\t} else if (typeof module === 'object' && module.exports) {\n\t\tmodule.exports = Chart;\n\t}\n\n\troot.Chart = Chart;\n\n\tChart.noConflict = function(){\n\t\troot.Chart = previous;\n\t\treturn Chart;\n\t};\n\n}).call(this);\n"
  },
  {
    "path": "static/assets/plugins/Chart.js/src/Chart.Doughnut.js",
    "content": "(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\t//Cache a local reference to Chart.helpers\n\t\thelpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\t//Boolean - Whether we should show a stroke on each segment\n\t\tsegmentShowStroke : true,\n\n\t\t//String - The colour of each segment stroke\n\t\tsegmentStrokeColor : \"#fff\",\n\n\t\t//Number - The width of each segment stroke\n\t\tsegmentStrokeWidth : 2,\n\n\t\t//The percentage of the chart that we cut out of the middle.\n\t\tpercentageInnerCutout : 50,\n\n\t\t//Number - Amount of animation steps\n\t\tanimationSteps : 100,\n\n\t\t//String - Animation easing effect\n\t\tanimationEasing : \"easeOutBounce\",\n\n\t\t//Boolean - Whether we animate the rotation of the Doughnut\n\t\tanimateRotate : true,\n\n\t\t//Boolean - Whether we animate scaling the Doughnut from the centre\n\t\tanimateScale : false,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<segments.length; i++){%><li><span style=\\\"background-color:<%=segments[i].fillColor%>\\\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>\"\n\n\t};\n\n\n\tChart.Type.extend({\n\t\t//Passing in a name registers this chart in the Chart namespace\n\t\tname: \"Doughnut\",\n\t\t//Providing a defaults will also register the deafults in the chart namespace\n\t\tdefaults : defaultConfig,\n\t\t//Initialize is fired when the chart is initialized - Data is passed in as a parameter\n\t\t//Config is automatically merged by the core of Chart.js, and is available at this.options\n\t\tinitialize:  function(data){\n\n\t\t\t//Declare segments as a static property to prevent inheriting across the Chart type prototype\n\t\t\tthis.segments = [];\n\t\t\tthis.outerRadius = (helpers.min([this.chart.width,this.chart.height]) -\tthis.options.segmentStrokeWidth/2)/2;\n\n\t\t\tthis.SegmentArc = Chart.Arc.extend({\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];\n\n\t\t\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\t\t\tsegment.restore([\"fillColor\"]);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activeSegments,function(activeSegment){\n\t\t\t\t\t\tactiveSegment.fillColor = activeSegment.highlightColor;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activeSegments);\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.calculateTotal(data);\n\n\t\t\thelpers.each(data,function(datapoint, index){\n\t\t\t\tthis.addData(datapoint, index, true);\n\t\t\t},this);\n\n\t\t\tthis.render();\n\t\t},\n\t\tgetSegmentsAtEvent : function(e){\n\t\t\tvar segmentsArray = [];\n\n\t\t\tvar location = helpers.getRelativePosition(e);\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tif (segment.inRange(location.x,location.y)) segmentsArray.push(segment);\n\t\t\t},this);\n\t\t\treturn segmentsArray;\n\t\t},\n\t\taddData : function(segment, atIndex, silent){\n\t\t\tvar index = atIndex || this.segments.length;\n\t\t\tthis.segments.splice(index, 0, new this.SegmentArc({\n\t\t\t\tvalue : segment.value,\n\t\t\t\touterRadius : (this.options.animateScale) ? 0 : this.outerRadius,\n\t\t\t\tinnerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout,\n\t\t\t\tfillColor : segment.color,\n\t\t\t\thighlightColor : segment.highlight || segment.color,\n\t\t\t\tshowStroke : this.options.segmentShowStroke,\n\t\t\t\tstrokeWidth : this.options.segmentStrokeWidth,\n\t\t\t\tstrokeColor : this.options.segmentStrokeColor,\n\t\t\t\tstartAngle : Math.PI * 1.5,\n\t\t\t\tcircumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value),\n\t\t\t\tlabel : segment.label\n\t\t\t}));\n\t\t\tif (!silent){\n\t\t\t\tthis.reflow();\n\t\t\t\tthis.update();\n\t\t\t}\n\t\t},\n\t\tcalculateCircumference : function(value){\n\t\t\treturn (Math.PI*2)*(Math.abs(value) / this.total);\n\t\t},\n\t\tcalculateTotal : function(data){\n\t\t\tthis.total = 0;\n\t\t\thelpers.each(data,function(segment){\n\t\t\t\tthis.total += Math.abs(segment.value);\n\t\t\t},this);\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.calculateTotal(this.segments);\n\n\t\t\t// Reset any highlight colours before updating.\n\t\t\thelpers.each(this.activeElements, function(activeElement){\n\t\t\t\tactiveElement.restore(['fillColor']);\n\t\t\t});\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tsegment.save();\n\t\t\t});\n\t\t\tthis.render();\n\t\t},\n\n\t\tremoveData: function(atIndex){\n\t\t\tvar indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;\n\t\t\tthis.segments.splice(indexToDelete, 1);\n\t\t\tthis.reflow();\n\t\t\tthis.update();\n\t\t},\n\n\t\treflow : function(){\n\t\t\thelpers.extend(this.SegmentArc.prototype,{\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\t\t\tthis.outerRadius = (helpers.min([this.chart.width,this.chart.height]) -\tthis.options.segmentStrokeWidth/2)/2;\n\t\t\thelpers.each(this.segments, function(segment){\n\t\t\t\tsegment.update({\n\t\t\t\t\touterRadius : this.outerRadius,\n\t\t\t\t\tinnerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout\n\t\t\t\t});\n\t\t\t}, this);\n\t\t},\n\t\tdraw : function(easeDecimal){\n\t\t\tvar animDecimal = (easeDecimal) ? easeDecimal : 1;\n\t\t\tthis.clear();\n\t\t\thelpers.each(this.segments,function(segment,index){\n\t\t\t\tsegment.transition({\n\t\t\t\t\tcircumference : this.calculateCircumference(segment.value),\n\t\t\t\t\touterRadius : this.outerRadius,\n\t\t\t\t\tinnerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout\n\t\t\t\t},animDecimal);\n\n\t\t\t\tsegment.endAngle = segment.startAngle + segment.circumference;\n\n\t\t\t\tsegment.draw();\n\t\t\t\tif (index === 0){\n\t\t\t\t\tsegment.startAngle = Math.PI * 1.5;\n\t\t\t\t}\n\t\t\t\t//Check to see if it's the last segment, if not get the next and update the start angle\n\t\t\t\tif (index < this.segments.length-1){\n\t\t\t\t\tthis.segments[index+1].startAngle = segment.endAngle;\n\t\t\t\t}\n\t\t\t},this);\n\n\t\t}\n\t});\n\n\tChart.types.Doughnut.extend({\n\t\tname : \"Pie\",\n\t\tdefaults : helpers.merge(defaultConfig,{percentageInnerCutout : 0})\n\t});\n\n}).call(this);"
  },
  {
    "path": "static/assets/plugins/Chart.js/src/Chart.Line.js",
    "content": "(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\thelpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\n\t\t///Boolean - Whether grid lines are shown across the chart\n\t\tscaleShowGridLines : true,\n\n\t\t//String - Colour of the grid lines\n\t\tscaleGridLineColor : \"rgba(0,0,0,.05)\",\n\n\t\t//Number - Width of the grid lines\n\t\tscaleGridLineWidth : 1,\n\n\t\t//Boolean - Whether to show horizontal lines (except X axis)\n\t\tscaleShowHorizontalLines: true,\n\n\t\t//Boolean - Whether to show vertical lines (except Y axis)\n\t\tscaleShowVerticalLines: true,\n\n\t\t//Boolean - Whether the line is curved between points\n\t\tbezierCurve : true,\n\n\t\t//Number - Tension of the bezier curve between points\n\t\tbezierCurveTension : 0.4,\n\n\t\t//Boolean - Whether to show a dot for each point\n\t\tpointDot : true,\n\n\t\t//Number - Radius of each point dot in pixels\n\t\tpointDotRadius : 4,\n\n\t\t//Number - Pixel width of point dot stroke\n\t\tpointDotStrokeWidth : 1,\n\n\t\t//Number - amount extra to add to the radius to cater for hit detection outside the drawn point\n\t\tpointHitDetectionRadius : 20,\n\n\t\t//Boolean - Whether to show a stroke for datasets\n\t\tdatasetStroke : true,\n\n\t\t//Number - Pixel width of dataset stroke\n\t\tdatasetStrokeWidth : 2,\n\n\t\t//Boolean - Whether to fill the dataset with a colour\n\t\tdatasetFill : true,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\\\"background-color:<%=datasets[i].strokeColor%>\\\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>\"\n\n\t};\n\n\n\tChart.Type.extend({\n\t\tname: \"Line\",\n\t\tdefaults : defaultConfig,\n\t\tinitialize:  function(data){\n\t\t\t//Declare the extension of the default point, to cater for the options passed in to the constructor\n\t\t\tthis.PointClass = Chart.Point.extend({\n\t\t\t\tstrokeWidth : this.options.pointDotStrokeWidth,\n\t\t\t\tradius : this.options.pointDotRadius,\n\t\t\t\tdisplay: this.options.pointDot,\n\t\t\t\thitDetectionRadius : this.options.pointHitDetectionRadius,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\tinRange : function(mouseX){\n\t\t\t\t\treturn (Math.pow(mouseX-this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius,2));\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.datasets = [];\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];\n\t\t\t\t\tthis.eachPoints(function(point){\n\t\t\t\t\t\tpoint.restore(['fillColor', 'strokeColor']);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activePoints, function(activePoint){\n\t\t\t\t\t\tactivePoint.fillColor = activePoint.highlightFill;\n\t\t\t\t\t\tactivePoint.strokeColor = activePoint.highlightStroke;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activePoints);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t//Iterate through each of the datasets, and build this into a property of the chart\n\t\t\thelpers.each(data.datasets,function(dataset){\n\n\t\t\t\tvar datasetObject = {\n\t\t\t\t\tlabel : dataset.label || null,\n\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\tpointColor : dataset.pointColor,\n\t\t\t\t\tpointStrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\tpoints : []\n\t\t\t\t};\n\n\t\t\t\tthis.datasets.push(datasetObject);\n\n\n\t\t\t\thelpers.each(dataset.data,function(dataPoint,index){\n\t\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\t\tdatasetObject.points.push(new this.PointClass({\n\t\t\t\t\t\tvalue : dataPoint,\n\t\t\t\t\t\tlabel : data.labels[index],\n\t\t\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\t\t\tstrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\t\tfillColor : dataset.pointColor,\n\t\t\t\t\t\thighlightFill : dataset.pointHighlightFill || dataset.pointColor,\n\t\t\t\t\t\thighlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor\n\t\t\t\t\t}));\n\t\t\t\t},this);\n\n\t\t\t\tthis.buildScale(data.labels);\n\n\n\t\t\t\tthis.eachPoints(function(point, index){\n\t\t\t\t\thelpers.extend(point, {\n\t\t\t\t\t\tx: this.scale.calculateX(index),\n\t\t\t\t\t\ty: this.scale.endPoint\n\t\t\t\t\t});\n\t\t\t\t\tpoint.save();\n\t\t\t\t}, this);\n\n\t\t\t},this);\n\n\n\t\t\tthis.render();\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.scale.update();\n\t\t\t// Reset any highlight colours before updating.\n\t\t\thelpers.each(this.activeElements, function(activeElement){\n\t\t\t\tactiveElement.restore(['fillColor', 'strokeColor']);\n\t\t\t});\n\t\t\tthis.eachPoints(function(point){\n\t\t\t\tpoint.save();\n\t\t\t});\n\t\t\tthis.render();\n\t\t},\n\t\teachPoints : function(callback){\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\thelpers.each(dataset.points,callback,this);\n\t\t\t},this);\n\t\t},\n\t\tgetPointsAtEvent : function(e){\n\t\t\tvar pointsArray = [],\n\t\t\t\teventPosition = helpers.getRelativePosition(e);\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\thelpers.each(dataset.points,function(point){\n\t\t\t\t\tif (point.inRange(eventPosition.x,eventPosition.y)) pointsArray.push(point);\n\t\t\t\t});\n\t\t\t},this);\n\t\t\treturn pointsArray;\n\t\t},\n\t\tbuildScale : function(labels){\n\t\t\tvar self = this;\n\n\t\t\tvar dataTotal = function(){\n\t\t\t\tvar values = [];\n\t\t\t\tself.eachPoints(function(point){\n\t\t\t\t\tvalues.push(point.value);\n\t\t\t\t});\n\n\t\t\t\treturn values;\n\t\t\t};\n\n\t\t\tvar scaleOptions = {\n\t\t\t\ttemplateString : this.options.scaleLabel,\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttextColor : this.options.scaleFontColor,\n\t\t\t\tfontSize : this.options.scaleFontSize,\n\t\t\t\tfontStyle : this.options.scaleFontStyle,\n\t\t\t\tfontFamily : this.options.scaleFontFamily,\n\t\t\t\tvaluesCount : labels.length,\n\t\t\t\tbeginAtZero : this.options.scaleBeginAtZero,\n\t\t\t\tintegersOnly : this.options.scaleIntegersOnly,\n\t\t\t\tcalculateYRange : function(currentHeight){\n\t\t\t\t\tvar updatedRanges = helpers.calculateScaleRange(\n\t\t\t\t\t\tdataTotal(),\n\t\t\t\t\t\tcurrentHeight,\n\t\t\t\t\t\tthis.fontSize,\n\t\t\t\t\t\tthis.beginAtZero,\n\t\t\t\t\t\tthis.integersOnly\n\t\t\t\t\t);\n\t\t\t\t\thelpers.extend(this, updatedRanges);\n\t\t\t\t},\n\t\t\t\txLabels : labels,\n\t\t\t\tfont : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),\n\t\t\t\tlineWidth : this.options.scaleLineWidth,\n\t\t\t\tlineColor : this.options.scaleLineColor,\n\t\t\t\tshowHorizontalLines : this.options.scaleShowHorizontalLines,\n\t\t\t\tshowVerticalLines : this.options.scaleShowVerticalLines,\n\t\t\t\tgridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,\n\t\t\t\tgridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : \"rgba(0,0,0,0)\",\n\t\t\t\tpadding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,\n\t\t\t\tshowLabels : this.options.scaleShowLabels,\n\t\t\t\tdisplay : this.options.showScale\n\t\t\t};\n\n\t\t\tif (this.options.scaleOverride){\n\t\t\t\thelpers.extend(scaleOptions, {\n\t\t\t\t\tcalculateYRange: helpers.noop,\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t});\n\t\t\t}\n\n\n\t\t\tthis.scale = new Chart.Scale(scaleOptions);\n\t\t},\n\t\taddData : function(valuesArray,label){\n\t\t\t//Map the values array for each of the datasets\n\n\t\t\thelpers.each(valuesArray,function(value,datasetIndex){\n\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\tthis.datasets[datasetIndex].points.push(new this.PointClass({\n\t\t\t\t\tvalue : value,\n\t\t\t\t\tlabel : label,\n\t\t\t\t\tx: this.scale.calculateX(this.scale.valuesCount+1),\n\t\t\t\t\ty: this.scale.endPoint,\n\t\t\t\t\tstrokeColor : this.datasets[datasetIndex].pointStrokeColor,\n\t\t\t\t\tfillColor : this.datasets[datasetIndex].pointColor\n\t\t\t\t}));\n\t\t\t},this);\n\n\t\t\tthis.scale.addXLabel(label);\n\t\t\t//Then re-render the chart.\n\t\t\tthis.update();\n\t\t},\n\t\tremoveData : function(){\n\t\t\tthis.scale.removeXLabel();\n\t\t\t//Then re-render the chart.\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tdataset.points.shift();\n\t\t\t},this);\n\t\t\tthis.update();\n\t\t},\n\t\treflow : function(){\n\t\t\tvar newScaleProps = helpers.extend({\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width\n\t\t\t});\n\t\t\tthis.scale.update(newScaleProps);\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easingDecimal = ease || 1;\n\t\t\tthis.clear();\n\n\t\t\tvar ctx = this.chart.ctx;\n\n\t\t\t// Some helper methods for getting the next/prev points\n\t\t\tvar hasValue = function(item){\n\t\t\t\treturn item.value !== null;\n\t\t\t},\n\t\t\tnextPoint = function(point, collection, index){\n\t\t\t\treturn helpers.findNextWhere(collection, hasValue, index) || point;\n\t\t\t},\n\t\t\tpreviousPoint = function(point, collection, index){\n\t\t\t\treturn helpers.findPreviousWhere(collection, hasValue, index) || point;\n\t\t\t};\n\n\t\t\tthis.scale.draw(easingDecimal);\n\n\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tvar pointsWithValues = helpers.where(dataset.points, hasValue);\n\n\t\t\t\t//Transition each point first so that the line and point drawing isn't out of sync\n\t\t\t\t//We can use this extra loop to calculate the control points of this dataset also in this loop\n\n\t\t\t\thelpers.each(dataset.points, function(point, index){\n\t\t\t\t\tif (point.hasValue()){\n\t\t\t\t\t\tpoint.transition({\n\t\t\t\t\t\t\ty : this.scale.calculateY(point.value),\n\t\t\t\t\t\t\tx : this.scale.calculateX(index)\n\t\t\t\t\t\t}, easingDecimal);\n\t\t\t\t\t}\n\t\t\t\t},this);\n\n\n\t\t\t\t// Control points need to be calculated in a seperate loop, because we need to know the current x/y of the point\n\t\t\t\t// This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed\n\t\t\t\tif (this.options.bezierCurve){\n\t\t\t\t\thelpers.each(pointsWithValues, function(point, index){\n\t\t\t\t\t\tvar tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0;\n\t\t\t\t\t\tpoint.controlPoints = helpers.splineCurve(\n\t\t\t\t\t\t\tpreviousPoint(point, pointsWithValues, index),\n\t\t\t\t\t\t\tpoint,\n\t\t\t\t\t\t\tnextPoint(point, pointsWithValues, index),\n\t\t\t\t\t\t\ttension\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// Prevent the bezier going outside of the bounds of the graph\n\n\t\t\t\t\t\t// Cap puter bezier handles to the upper/lower scale bounds\n\t\t\t\t\t\tif (point.controlPoints.outer.y > this.scale.endPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.outer.y = this.scale.endPoint;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (point.controlPoints.outer.y < this.scale.startPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.outer.y = this.scale.startPoint;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Cap inner bezier handles to the upper/lower scale bounds\n\t\t\t\t\t\tif (point.controlPoints.inner.y > this.scale.endPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.inner.y = this.scale.endPoint;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (point.controlPoints.inner.y < this.scale.startPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.inner.y = this.scale.startPoint;\n\t\t\t\t\t\t}\n\t\t\t\t\t},this);\n\t\t\t\t}\n\n\n\t\t\t\t//Draw the line between all the points\n\t\t\t\tctx.lineWidth = this.options.datasetStrokeWidth;\n\t\t\t\tctx.strokeStyle = dataset.strokeColor;\n\t\t\t\tctx.beginPath();\n\n\t\t\t\thelpers.each(pointsWithValues, function(point, index){\n\t\t\t\t\tif (index === 0){\n\t\t\t\t\t\tctx.moveTo(point.x, point.y);\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\tif(this.options.bezierCurve){\n\t\t\t\t\t\t\tvar previous = previousPoint(point, pointsWithValues, index);\n\n\t\t\t\t\t\t\tctx.bezierCurveTo(\n\t\t\t\t\t\t\t\tprevious.controlPoints.outer.x,\n\t\t\t\t\t\t\t\tprevious.controlPoints.outer.y,\n\t\t\t\t\t\t\t\tpoint.controlPoints.inner.x,\n\t\t\t\t\t\t\t\tpoint.controlPoints.inner.y,\n\t\t\t\t\t\t\t\tpoint.x,\n\t\t\t\t\t\t\t\tpoint.y\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\tctx.lineTo(point.x,point.y);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\n\t\t\t\tctx.stroke();\n\n\t\t\t\tif (this.options.datasetFill && pointsWithValues.length > 0){\n\t\t\t\t\t//Round off the line by going to the base of the chart, back to the start, then fill.\n\t\t\t\t\tctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint);\n\t\t\t\t\tctx.lineTo(pointsWithValues[0].x, this.scale.endPoint);\n\t\t\t\t\tctx.fillStyle = dataset.fillColor;\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tctx.fill();\n\t\t\t\t}\n\n\t\t\t\t//Now draw the points over the line\n\t\t\t\t//A little inefficient double looping, but better than the line\n\t\t\t\t//lagging behind the point positions\n\t\t\t\thelpers.each(pointsWithValues,function(point){\n\t\t\t\t\tpoint.draw();\n\t\t\t\t});\n\t\t\t},this);\n\t\t}\n\t});\n\n\n}).call(this);\n"
  },
  {
    "path": "static/assets/plugins/Chart.js/src/Chart.PolarArea.js",
    "content": "(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\t//Cache a local reference to Chart.helpers\n\t\thelpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\t//Boolean - Show a backdrop to the scale label\n\t\tscaleShowLabelBackdrop : true,\n\n\t\t//String - The colour of the label backdrop\n\t\tscaleBackdropColor : \"rgba(255,255,255,0.75)\",\n\n\t\t// Boolean - Whether the scale should begin at zero\n\t\tscaleBeginAtZero : true,\n\n\t\t//Number - The backdrop padding above & below the label in pixels\n\t\tscaleBackdropPaddingY : 2,\n\n\t\t//Number - The backdrop padding to the side of the label in pixels\n\t\tscaleBackdropPaddingX : 2,\n\n\t\t//Boolean - Show line for each value in the scale\n\t\tscaleShowLine : true,\n\n\t\t//Boolean - Stroke a line around each segment in the chart\n\t\tsegmentShowStroke : true,\n\n\t\t//String - The colour of the stroke on each segement.\n\t\tsegmentStrokeColor : \"#fff\",\n\n\t\t//Number - The width of the stroke value in pixels\n\t\tsegmentStrokeWidth : 2,\n\n\t\t//Number - Amount of animation steps\n\t\tanimationSteps : 100,\n\n\t\t//String - Animation easing effect.\n\t\tanimationEasing : \"easeOutBounce\",\n\n\t\t//Boolean - Whether to animate the rotation of the chart\n\t\tanimateRotate : true,\n\n\t\t//Boolean - Whether to animate scaling the chart from the centre\n\t\tanimateScale : false,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<segments.length; i++){%><li><span style=\\\"background-color:<%=segments[i].fillColor%>\\\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>\"\n\t};\n\n\n\tChart.Type.extend({\n\t\t//Passing in a name registers this chart in the Chart namespace\n\t\tname: \"PolarArea\",\n\t\t//Providing a defaults will also register the deafults in the chart namespace\n\t\tdefaults : defaultConfig,\n\t\t//Initialize is fired when the chart is initialized - Data is passed in as a parameter\n\t\t//Config is automatically merged by the core of Chart.js, and is available at this.options\n\t\tinitialize:  function(data){\n\t\t\tthis.segments = [];\n\t\t\t//Declare segment class as a chart instance specific class, so it can share props for this instance\n\t\t\tthis.SegmentArc = Chart.Arc.extend({\n\t\t\t\tshowStroke : this.options.segmentShowStroke,\n\t\t\t\tstrokeWidth : this.options.segmentStrokeWidth,\n\t\t\t\tstrokeColor : this.options.segmentStrokeColor,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\tinnerRadius : 0,\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\t\t\tthis.scale = new Chart.RadialScale({\n\t\t\t\tdisplay: this.options.showScale,\n\t\t\t\tfontStyle: this.options.scaleFontStyle,\n\t\t\t\tfontSize: this.options.scaleFontSize,\n\t\t\t\tfontFamily: this.options.scaleFontFamily,\n\t\t\t\tfontColor: this.options.scaleFontColor,\n\t\t\t\tshowLabels: this.options.scaleShowLabels,\n\t\t\t\tshowLabelBackdrop: this.options.scaleShowLabelBackdrop,\n\t\t\t\tbackdropColor: this.options.scaleBackdropColor,\n\t\t\t\tbackdropPaddingY : this.options.scaleBackdropPaddingY,\n\t\t\t\tbackdropPaddingX: this.options.scaleBackdropPaddingX,\n\t\t\t\tlineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,\n\t\t\t\tlineColor: this.options.scaleLineColor,\n\t\t\t\tlineArc: true,\n\t\t\t\twidth: this.chart.width,\n\t\t\t\theight: this.chart.height,\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttemplateString: this.options.scaleLabel,\n\t\t\t\tvaluesCount: data.length\n\t\t\t});\n\n\t\t\tthis.updateScaleRange(data);\n\n\t\t\tthis.scale.update();\n\n\t\t\thelpers.each(data,function(segment,index){\n\t\t\t\tthis.addData(segment,index,true);\n\t\t\t},this);\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];\n\t\t\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\t\t\tsegment.restore([\"fillColor\"]);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activeSegments,function(activeSegment){\n\t\t\t\t\t\tactiveSegment.fillColor = activeSegment.highlightColor;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activeSegments);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.render();\n\t\t},\n\t\tgetSegmentsAtEvent : function(e){\n\t\t\tvar segmentsArray = [];\n\n\t\t\tvar location = helpers.getRelativePosition(e);\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tif (segment.inRange(location.x,location.y)) segmentsArray.push(segment);\n\t\t\t},this);\n\t\t\treturn segmentsArray;\n\t\t},\n\t\taddData : function(segment, atIndex, silent){\n\t\t\tvar index = atIndex || this.segments.length;\n\n\t\t\tthis.segments.splice(index, 0, new this.SegmentArc({\n\t\t\t\tfillColor: segment.color,\n\t\t\t\thighlightColor: segment.highlight || segment.color,\n\t\t\t\tlabel: segment.label,\n\t\t\t\tvalue: segment.value,\n\t\t\t\touterRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),\n\t\t\t\tcircumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),\n\t\t\t\tstartAngle: Math.PI * 1.5\n\t\t\t}));\n\t\t\tif (!silent){\n\t\t\t\tthis.reflow();\n\t\t\t\tthis.update();\n\t\t\t}\n\t\t},\n\t\tremoveData: function(atIndex){\n\t\t\tvar indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;\n\t\t\tthis.segments.splice(indexToDelete, 1);\n\t\t\tthis.reflow();\n\t\t\tthis.update();\n\t\t},\n\t\tcalculateTotal: function(data){\n\t\t\tthis.total = 0;\n\t\t\thelpers.each(data,function(segment){\n\t\t\t\tthis.total += segment.value;\n\t\t\t},this);\n\t\t\tthis.scale.valuesCount = this.segments.length;\n\t\t},\n\t\tupdateScaleRange: function(datapoints){\n\t\t\tvar valuesArray = [];\n\t\t\thelpers.each(datapoints,function(segment){\n\t\t\t\tvaluesArray.push(segment.value);\n\t\t\t});\n\n\t\t\tvar scaleSizes = (this.options.scaleOverride) ?\n\t\t\t\t{\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t} :\n\t\t\t\thelpers.calculateScaleRange(\n\t\t\t\t\tvaluesArray,\n\t\t\t\t\thelpers.min([this.chart.width, this.chart.height])/2,\n\t\t\t\t\tthis.options.scaleFontSize,\n\t\t\t\t\tthis.options.scaleBeginAtZero,\n\t\t\t\t\tthis.options.scaleIntegersOnly\n\t\t\t\t);\n\n\t\t\thelpers.extend(\n\t\t\t\tthis.scale,\n\t\t\t\tscaleSizes,\n\t\t\t\t{\n\t\t\t\t\tsize: helpers.min([this.chart.width, this.chart.height]),\n\t\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\t\tyCenter: this.chart.height/2\n\t\t\t\t}\n\t\t\t);\n\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.calculateTotal(this.segments);\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tsegment.save();\n\t\t\t});\n\t\t\t\n\t\t\tthis.reflow();\n\t\t\tthis.render();\n\t\t},\n\t\treflow : function(){\n\t\t\thelpers.extend(this.SegmentArc.prototype,{\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\t\t\tthis.updateScaleRange(this.segments);\n\t\t\tthis.scale.update();\n\n\t\t\thelpers.extend(this.scale,{\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2\n\t\t\t});\n\n\t\t\thelpers.each(this.segments, function(segment){\n\t\t\t\tsegment.update({\n\t\t\t\t\touterRadius : this.scale.calculateCenterOffset(segment.value)\n\t\t\t\t});\n\t\t\t}, this);\n\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easingDecimal = ease || 1;\n\t\t\t//Clear & draw the canvas\n\t\t\tthis.clear();\n\t\t\thelpers.each(this.segments,function(segment, index){\n\t\t\t\tsegment.transition({\n\t\t\t\t\tcircumference : this.scale.getCircumference(),\n\t\t\t\t\touterRadius : this.scale.calculateCenterOffset(segment.value)\n\t\t\t\t},easingDecimal);\n\n\t\t\t\tsegment.endAngle = segment.startAngle + segment.circumference;\n\n\t\t\t\t// If we've removed the first segment we need to set the first one to\n\t\t\t\t// start at the top.\n\t\t\t\tif (index === 0){\n\t\t\t\t\tsegment.startAngle = Math.PI * 1.5;\n\t\t\t\t}\n\n\t\t\t\t//Check to see if it's the last segment, if not get the next and update the start angle\n\t\t\t\tif (index < this.segments.length - 1){\n\t\t\t\t\tthis.segments[index+1].startAngle = segment.endAngle;\n\t\t\t\t}\n\t\t\t\tsegment.draw();\n\t\t\t}, this);\n\t\t\tthis.scale.draw();\n\t\t}\n\t});\n\n}).call(this);"
  },
  {
    "path": "static/assets/plugins/Chart.js/src/Chart.Radar.js",
    "content": "(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\thelpers = Chart.helpers;\n\n\n\n\tChart.Type.extend({\n\t\tname: \"Radar\",\n\t\tdefaults:{\n\t\t\t//Boolean - Whether to show lines for each scale point\n\t\t\tscaleShowLine : true,\n\n\t\t\t//Boolean - Whether we show the angle lines out of the radar\n\t\t\tangleShowLineOut : true,\n\n\t\t\t//Boolean - Whether to show labels on the scale\n\t\t\tscaleShowLabels : false,\n\n\t\t\t// Boolean - Whether the scale should begin at zero\n\t\t\tscaleBeginAtZero : true,\n\n\t\t\t//String - Colour of the angle line\n\t\t\tangleLineColor : \"rgba(0,0,0,.1)\",\n\n\t\t\t//Number - Pixel width of the angle line\n\t\t\tangleLineWidth : 1,\n\n\t\t\t//String - Point label font declaration\n\t\t\tpointLabelFontFamily : \"'Arial'\",\n\n\t\t\t//String - Point label font weight\n\t\t\tpointLabelFontStyle : \"normal\",\n\n\t\t\t//Number - Point label font size in pixels\n\t\t\tpointLabelFontSize : 10,\n\n\t\t\t//String - Point label font colour\n\t\t\tpointLabelFontColor : \"#666\",\n\n\t\t\t//Boolean - Whether to show a dot for each point\n\t\t\tpointDot : true,\n\n\t\t\t//Number - Radius of each point dot in pixels\n\t\t\tpointDotRadius : 3,\n\n\t\t\t//Number - Pixel width of point dot stroke\n\t\t\tpointDotStrokeWidth : 1,\n\n\t\t\t//Number - amount extra to add to the radius to cater for hit detection outside the drawn point\n\t\t\tpointHitDetectionRadius : 20,\n\n\t\t\t//Boolean - Whether to show a stroke for datasets\n\t\t\tdatasetStroke : true,\n\n\t\t\t//Number - Pixel width of dataset stroke\n\t\t\tdatasetStrokeWidth : 2,\n\n\t\t\t//Boolean - Whether to fill the dataset with a colour\n\t\t\tdatasetFill : true,\n\n\t\t\t//String - A legend template\n\t\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\\\"background-color:<%=datasets[i].strokeColor%>\\\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>\"\n\n\t\t},\n\n\t\tinitialize: function(data){\n\t\t\tthis.PointClass = Chart.Point.extend({\n\t\t\t\tstrokeWidth : this.options.pointDotStrokeWidth,\n\t\t\t\tradius : this.options.pointDotRadius,\n\t\t\t\tdisplay: this.options.pointDot,\n\t\t\t\thitDetectionRadius : this.options.pointHitDetectionRadius,\n\t\t\t\tctx : this.chart.ctx\n\t\t\t});\n\n\t\t\tthis.datasets = [];\n\n\t\t\tthis.buildScale(data);\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activePointsCollection = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];\n\n\t\t\t\t\tthis.eachPoints(function(point){\n\t\t\t\t\t\tpoint.restore(['fillColor', 'strokeColor']);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activePointsCollection, function(activePoint){\n\t\t\t\t\t\tactivePoint.fillColor = activePoint.highlightFill;\n\t\t\t\t\t\tactivePoint.strokeColor = activePoint.highlightStroke;\n\t\t\t\t\t});\n\n\t\t\t\t\tthis.showTooltip(activePointsCollection);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t//Iterate through each of the datasets, and build this into a property of the chart\n\t\t\thelpers.each(data.datasets,function(dataset){\n\n\t\t\t\tvar datasetObject = {\n\t\t\t\t\tlabel: dataset.label || null,\n\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\tpointColor : dataset.pointColor,\n\t\t\t\t\tpointStrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\tpoints : []\n\t\t\t\t};\n\n\t\t\t\tthis.datasets.push(datasetObject);\n\n\t\t\t\thelpers.each(dataset.data,function(dataPoint,index){\n\t\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\t\tvar pointPosition;\n\t\t\t\t\tif (!this.scale.animation){\n\t\t\t\t\t\tpointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint));\n\t\t\t\t\t}\n\t\t\t\t\tdatasetObject.points.push(new this.PointClass({\n\t\t\t\t\t\tvalue : dataPoint,\n\t\t\t\t\t\tlabel : data.labels[index],\n\t\t\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\t\t\tx: (this.options.animation) ? this.scale.xCenter : pointPosition.x,\n\t\t\t\t\t\ty: (this.options.animation) ? this.scale.yCenter : pointPosition.y,\n\t\t\t\t\t\tstrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\t\tfillColor : dataset.pointColor,\n\t\t\t\t\t\thighlightFill : dataset.pointHighlightFill || dataset.pointColor,\n\t\t\t\t\t\thighlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor\n\t\t\t\t\t}));\n\t\t\t\t},this);\n\n\t\t\t},this);\n\n\t\t\tthis.render();\n\t\t},\n\t\teachPoints : function(callback){\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\thelpers.each(dataset.points,callback,this);\n\t\t\t},this);\n\t\t},\n\n\t\tgetPointsAtEvent : function(evt){\n\t\t\tvar mousePosition = helpers.getRelativePosition(evt),\n\t\t\t\tfromCenter = helpers.getAngleFromPoint({\n\t\t\t\t\tx: this.scale.xCenter,\n\t\t\t\t\ty: this.scale.yCenter\n\t\t\t\t}, mousePosition);\n\n\t\t\tvar anglePerIndex = (Math.PI * 2) /this.scale.valuesCount,\n\t\t\t\tpointIndex = Math.round((fromCenter.angle - Math.PI * 1.5) / anglePerIndex),\n\t\t\t\tactivePointsCollection = [];\n\n\t\t\t// If we're at the top, make the pointIndex 0 to get the first of the array.\n\t\t\tif (pointIndex >= this.scale.valuesCount || pointIndex < 0){\n\t\t\t\tpointIndex = 0;\n\t\t\t}\n\n\t\t\tif (fromCenter.distance <= this.scale.drawingArea){\n\t\t\t\thelpers.each(this.datasets, function(dataset){\n\t\t\t\t\tactivePointsCollection.push(dataset.points[pointIndex]);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn activePointsCollection;\n\t\t},\n\n\t\tbuildScale : function(data){\n\t\t\tthis.scale = new Chart.RadialScale({\n\t\t\t\tdisplay: this.options.showScale,\n\t\t\t\tfontStyle: this.options.scaleFontStyle,\n\t\t\t\tfontSize: this.options.scaleFontSize,\n\t\t\t\tfontFamily: this.options.scaleFontFamily,\n\t\t\t\tfontColor: this.options.scaleFontColor,\n\t\t\t\tshowLabels: this.options.scaleShowLabels,\n\t\t\t\tshowLabelBackdrop: this.options.scaleShowLabelBackdrop,\n\t\t\t\tbackdropColor: this.options.scaleBackdropColor,\n\t\t\t\tbackdropPaddingY : this.options.scaleBackdropPaddingY,\n\t\t\t\tbackdropPaddingX: this.options.scaleBackdropPaddingX,\n\t\t\t\tlineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,\n\t\t\t\tlineColor: this.options.scaleLineColor,\n\t\t\t\tangleLineColor : this.options.angleLineColor,\n\t\t\t\tangleLineWidth : (this.options.angleShowLineOut) ? this.options.angleLineWidth : 0,\n\t\t\t\t// Point labels at the edge of each line\n\t\t\t\tpointLabelFontColor : this.options.pointLabelFontColor,\n\t\t\t\tpointLabelFontSize : this.options.pointLabelFontSize,\n\t\t\t\tpointLabelFontFamily : this.options.pointLabelFontFamily,\n\t\t\t\tpointLabelFontStyle : this.options.pointLabelFontStyle,\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth: this.chart.width,\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttemplateString: this.options.scaleLabel,\n\t\t\t\tlabels: data.labels,\n\t\t\t\tvaluesCount: data.datasets[0].data.length\n\t\t\t});\n\n\t\t\tthis.scale.setScaleSize();\n\t\t\tthis.updateScaleRange(data.datasets);\n\t\t\tthis.scale.buildYLabels();\n\t\t},\n\t\tupdateScaleRange: function(datasets){\n\t\t\tvar valuesArray = (function(){\n\t\t\t\tvar totalDataArray = [];\n\t\t\t\thelpers.each(datasets,function(dataset){\n\t\t\t\t\tif (dataset.data){\n\t\t\t\t\t\ttotalDataArray = totalDataArray.concat(dataset.data);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\thelpers.each(dataset.points, function(point){\n\t\t\t\t\t\t\ttotalDataArray.push(point.value);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn totalDataArray;\n\t\t\t})();\n\n\n\t\t\tvar scaleSizes = (this.options.scaleOverride) ?\n\t\t\t\t{\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t} :\n\t\t\t\thelpers.calculateScaleRange(\n\t\t\t\t\tvaluesArray,\n\t\t\t\t\thelpers.min([this.chart.width, this.chart.height])/2,\n\t\t\t\t\tthis.options.scaleFontSize,\n\t\t\t\t\tthis.options.scaleBeginAtZero,\n\t\t\t\t\tthis.options.scaleIntegersOnly\n\t\t\t\t);\n\n\t\t\thelpers.extend(\n\t\t\t\tthis.scale,\n\t\t\t\tscaleSizes\n\t\t\t);\n\n\t\t},\n\t\taddData : function(valuesArray,label){\n\t\t\t//Map the values array for each of the datasets\n\t\t\tthis.scale.valuesCount++;\n\t\t\thelpers.each(valuesArray,function(value,datasetIndex){\n\t\t\t\tvar pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value));\n\t\t\t\tthis.datasets[datasetIndex].points.push(new this.PointClass({\n\t\t\t\t\tvalue : value,\n\t\t\t\t\tlabel : label,\n\t\t\t\t\tx: pointPosition.x,\n\t\t\t\t\ty: pointPosition.y,\n\t\t\t\t\tstrokeColor : this.datasets[datasetIndex].pointStrokeColor,\n\t\t\t\t\tfillColor : this.datasets[datasetIndex].pointColor\n\t\t\t\t}));\n\t\t\t},this);\n\n\t\t\tthis.scale.labels.push(label);\n\n\t\t\tthis.reflow();\n\n\t\t\tthis.update();\n\t\t},\n\t\tremoveData : function(){\n\t\t\tthis.scale.valuesCount--;\n\t\t\tthis.scale.labels.shift();\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tdataset.points.shift();\n\t\t\t},this);\n\t\t\tthis.reflow();\n\t\t\tthis.update();\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.eachPoints(function(point){\n\t\t\t\tpoint.save();\n\t\t\t});\n\t\t\tthis.reflow();\n\t\t\tthis.render();\n\t\t},\n\t\treflow: function(){\n\t\t\thelpers.extend(this.scale, {\n\t\t\t\twidth : this.chart.width,\n\t\t\t\theight: this.chart.height,\n\t\t\t\tsize : helpers.min([this.chart.width, this.chart.height]),\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2\n\t\t\t});\n\t\t\tthis.updateScaleRange(this.datasets);\n\t\t\tthis.scale.setScaleSize();\n\t\t\tthis.scale.buildYLabels();\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easeDecimal = ease || 1,\n\t\t\t\tctx = this.chart.ctx;\n\t\t\tthis.clear();\n\t\t\tthis.scale.draw();\n\n\t\t\thelpers.each(this.datasets,function(dataset){\n\n\t\t\t\t//Transition each point first so that the line and point drawing isn't out of sync\n\t\t\t\thelpers.each(dataset.points,function(point,index){\n\t\t\t\t\tif (point.hasValue()){\n\t\t\t\t\t\tpoint.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);\n\t\t\t\t\t}\n\t\t\t\t},this);\n\n\n\n\t\t\t\t//Draw the line between all the points\n\t\t\t\tctx.lineWidth = this.options.datasetStrokeWidth;\n\t\t\t\tctx.strokeStyle = dataset.strokeColor;\n\t\t\t\tctx.beginPath();\n\t\t\t\thelpers.each(dataset.points,function(point,index){\n\t\t\t\t\tif (index === 0){\n\t\t\t\t\t\tctx.moveTo(point.x,point.y);\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\tctx.lineTo(point.x,point.y);\n\t\t\t\t\t}\n\t\t\t\t},this);\n\t\t\t\tctx.closePath();\n\t\t\t\tctx.stroke();\n\n\t\t\t\tctx.fillStyle = dataset.fillColor;\n\t\t\t\tctx.fill();\n\n\t\t\t\t//Now draw the points over the line\n\t\t\t\t//A little inefficient double looping, but better than the line\n\t\t\t\t//lagging behind the point positions\n\t\t\t\thelpers.each(dataset.points,function(point){\n\t\t\t\t\tif (point.hasValue()){\n\t\t\t\t\t\tpoint.draw();\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t},this);\n\n\t\t}\n\n\t});\n\n\n\n\n\n}).call(this);"
  },
  {
    "path": "static/assets/plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker.css",
    "content": "/*!\n * Datepicker for Bootstrap v1.4.1 (https://github.com/eternicode/bootstrap-datepicker)\n *\n * Copyright 2012 Stefan Petre\n * Improvements by Andrew Rowls\n * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)\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 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 #ccc;\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-top:before {\n  top: -7px;\n}\n.datepicker-dropdown.datepicker-orient-top:after {\n  top: -6px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:before {\n  bottom: -7px;\n  border-bottom: 0;\n  border-top: 7px solid #999;\n}\n.datepicker-dropdown.datepicker-orient-bottom:after {\n  bottom: -6px;\n  border-bottom: 0;\n  border-top: 6px solid #ffffff;\n}\n.datepicker > div {\n  display: none;\n}\n.datepicker.days .datepicker-days,\n.datepicker.months .datepicker-months,\n.datepicker.years .datepicker-years {\n  display: block;\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.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(top, #fdd49a, #fdf59a);\n  background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));\n  background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);\n  background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);\n  background-image: linear-gradient(top, #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(top, #f3c17a, #f3e97a);\n  background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));\n  background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a);\n  background-image: -o-linear-gradient(top, #f3c17a, #f3e97a);\n  background-image: linear-gradient(top, #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(top, #b3b3b3, #808080);\n  background-image: -ms-linear-gradient(top, #b3b3b3, #808080);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));\n  background-image: -webkit-linear-gradient(top, #b3b3b3, #808080);\n  background-image: -o-linear-gradient(top, #b3b3b3, #808080);\n  background-image: linear-gradient(top, #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(top, #0088cc, #0044cc);\n  background-image: -ms-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(top, #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  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(top, #0088cc, #0044cc);\n  background-image: -ms-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(top, #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 thead tr:first-child th,\n.datepicker tfoot tr th {\n  cursor: pointer;\n}\n.datepicker thead tr:first-child th:hover,\n.datepicker tfoot tr th:hover {\n  background: #eeeeee;\n}\n.datepicker .cw {\n  font-size: 10px;\n  width: 12px;\n  padding: 0 2px 0 5px;\n  vertical-align: middle;\n}\n.datepicker thead tr:first-child .cw {\n  cursor: default;\n  background-color: transparent;\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"
  },
  {
    "path": "static/assets/plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker.standalone.css",
    "content": "/*!\n * Datepicker for Bootstrap v1.4.1 (https://github.com/eternicode/bootstrap-datepicker)\n *\n * Copyright 2012 Stefan Petre\n * Improvements by Andrew Rowls\n * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)\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 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 #ccc;\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-top:before {\n  top: -7px;\n}\n.datepicker-dropdown.datepicker-orient-top:after {\n  top: -6px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:before {\n  bottom: -7px;\n  border-bottom: 0;\n  border-top: 7px solid #999;\n}\n.datepicker-dropdown.datepicker-orient-bottom:after {\n  bottom: -6px;\n  border-bottom: 0;\n  border-top: 6px solid #ffffff;\n}\n.datepicker > div {\n  display: none;\n}\n.datepicker.days .datepicker-days,\n.datepicker.months .datepicker-months,\n.datepicker.years .datepicker-years {\n  display: block;\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.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(top, #fdd49a, #fdf59a);\n  background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));\n  background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);\n  background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);\n  background-image: linear-gradient(top, #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(top, #f3c17a, #f3e97a);\n  background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));\n  background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a);\n  background-image: -o-linear-gradient(top, #f3c17a, #f3e97a);\n  background-image: linear-gradient(top, #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(top, #b3b3b3, #808080);\n  background-image: -ms-linear-gradient(top, #b3b3b3, #808080);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));\n  background-image: -webkit-linear-gradient(top, #b3b3b3, #808080);\n  background-image: -o-linear-gradient(top, #b3b3b3, #808080);\n  background-image: linear-gradient(top, #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(top, #0088cc, #0044cc);\n  background-image: -ms-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(top, #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  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(top, #0088cc, #0044cc);\n  background-image: -ms-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(top, #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 thead tr:first-child th,\n.datepicker tfoot tr th {\n  cursor: pointer;\n}\n.datepicker thead tr:first-child th:hover,\n.datepicker tfoot tr th:hover {\n  background: #eeeeee;\n}\n.datepicker .cw {\n  font-size: 10px;\n  width: 12px;\n  padding: 0 2px 0 5px;\n  vertical-align: middle;\n}\n.datepicker thead tr:first-child .cw {\n  cursor: default;\n  background-color: transparent;\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: 20px;\n  padding: 4px 5px;\n  font-weight: normal;\n  line-height: 20px;\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.datepicker.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  float: left;\n  display: none;\n  min-width: 160px;\n  list-style: none;\n  background-color: #ffffff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  border-radius: 5px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  -webkit-background-clip: padding-box;\n  -moz-background-clip: padding;\n  background-clip: padding-box;\n  *border-right-width: 2px;\n  *border-bottom-width: 2px;\n  color: #333333;\n  font-size: 13px;\n  line-height: 20px;\n}\n.datepicker.dropdown-menu th,\n.datepicker.datepicker-inline th,\n.datepicker.dropdown-menu td,\n.datepicker.datepicker-inline td {\n  padding: 4px 5px;\n}\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker3.css",
    "content": "/*!\n * Datepicker for Bootstrap v1.4.1 (https://github.com/eternicode/bootstrap-datepicker)\n *\n * Copyright 2012 Stefan Petre\n * Improvements by Andrew Rowls\n * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)\n */\n.datepicker {\n  padding: 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 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 #ccc;\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 #fff;\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-top:before {\n  top: -7px;\n}\n.datepicker-dropdown.datepicker-orient-top:after {\n  top: -6px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:before {\n  bottom: -7px;\n  border-bottom: 0;\n  border-top: 7px solid #999;\n}\n.datepicker-dropdown.datepicker-orient-bottom:after {\n  bottom: -6px;\n  border-bottom: 0;\n  border-top: 6px solid #fff;\n}\n.datepicker > div {\n  display: none;\n}\n.datepicker.days .datepicker-days,\n.datepicker.months .datepicker-months,\n.datepicker.years .datepicker-years {\n  display: block;\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 table tr td,\n.datepicker table tr th {\n  text-align: center;\n  width: 30px;\n  height: 30px;\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.today,\n.datepicker table tr td.today:hover,\n.datepicker table tr td.today.disabled,\n.datepicker table tr td.today.disabled:hover {\n  color: #000000;\n  background-color: #ffdb99;\n  border-color: #ffb733;\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:focus,\n.datepicker table tr td.today:hover:focus,\n.datepicker table tr td.today.disabled:focus,\n.datepicker table tr td.today.disabled:hover:focus,\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.open .dropdown-toggle.datepicker table tr td.today,\n.open .dropdown-toggle.datepicker table tr td.today:hover,\n.open .dropdown-toggle.datepicker table tr td.today.disabled,\n.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {\n  color: #000000;\n  background-color: #ffcd70;\n  border-color: #f59e00;\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.open .dropdown-toggle.datepicker table tr td.today,\n.open .dropdown-toggle.datepicker table tr td.today:hover,\n.open .dropdown-toggle.datepicker table tr td.today.disabled,\n.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {\n  background-image: none;\n}\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],\nfieldset[disabled] .datepicker table tr td.today,\nfieldset[disabled] .datepicker table tr td.today:hover,\nfieldset[disabled] .datepicker table tr td.today.disabled,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover,\n.datepicker table tr td.today.disabled:hover,\n.datepicker table tr td.today:hover.disabled:hover,\n.datepicker table tr td.today.disabled.disabled:hover,\n.datepicker table tr td.today.disabled:hover.disabled:hover,\n.datepicker table tr td.today[disabled]:hover,\n.datepicker table tr td.today:hover[disabled]:hover,\n.datepicker table tr td.today.disabled[disabled]:hover,\n.datepicker table tr td.today.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.today:hover,\nfieldset[disabled] .datepicker table tr td.today:hover:hover,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover:hover,\n.datepicker table tr td.today.disabled:focus,\n.datepicker table tr td.today:hover.disabled:focus,\n.datepicker table tr td.today.disabled.disabled:focus,\n.datepicker table tr td.today.disabled:hover.disabled:focus,\n.datepicker table tr td.today[disabled]:focus,\n.datepicker table tr td.today:hover[disabled]:focus,\n.datepicker table tr td.today.disabled[disabled]:focus,\n.datepicker table tr td.today.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.today:focus,\nfieldset[disabled] .datepicker table tr td.today:hover:focus,\nfieldset[disabled] .datepicker table tr td.today.disabled:focus,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover:focus,\n.datepicker table tr td.today.disabled:active,\n.datepicker table tr td.today:hover.disabled:active,\n.datepicker table tr td.today.disabled.disabled:active,\n.datepicker table tr td.today.disabled:hover.disabled:active,\n.datepicker table tr td.today[disabled]:active,\n.datepicker table tr td.today:hover[disabled]:active,\n.datepicker table tr td.today.disabled[disabled]:active,\n.datepicker table tr td.today.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td.today:active,\nfieldset[disabled] .datepicker table tr td.today:hover:active,\nfieldset[disabled] .datepicker table tr td.today.disabled:active,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover:active,\n.datepicker table tr td.today.disabled.active,\n.datepicker table tr td.today:hover.disabled.active,\n.datepicker table tr td.today.disabled.disabled.active,\n.datepicker table tr td.today.disabled:hover.disabled.active,\n.datepicker table tr td.today[disabled].active,\n.datepicker table tr td.today:hover[disabled].active,\n.datepicker table tr td.today.disabled[disabled].active,\n.datepicker table tr td.today.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td.today.active,\nfieldset[disabled] .datepicker table tr td.today:hover.active,\nfieldset[disabled] .datepicker table tr td.today.disabled.active,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover.active {\n  background-color: #ffdb99;\n  border-color: #ffb733;\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  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  color: #000000;\n  background-color: #f7ca77;\n  border-color: #f1a417;\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:focus,\n.datepicker table tr td.range.today:hover:focus,\n.datepicker table tr td.range.today.disabled:focus,\n.datepicker table tr td.range.today.disabled:hover:focus,\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.open .dropdown-toggle.datepicker table tr td.range.today,\n.open .dropdown-toggle.datepicker table tr td.range.today:hover,\n.open .dropdown-toggle.datepicker table tr td.range.today.disabled,\n.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {\n  color: #000000;\n  background-color: #f4bb51;\n  border-color: #bf800c;\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.open .dropdown-toggle.datepicker table tr td.range.today,\n.open .dropdown-toggle.datepicker table tr td.range.today:hover,\n.open .dropdown-toggle.datepicker table tr td.range.today.disabled,\n.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {\n  background-image: none;\n}\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],\nfieldset[disabled] .datepicker table tr td.range.today,\nfieldset[disabled] .datepicker table tr td.range.today:hover,\nfieldset[disabled] .datepicker table tr td.range.today.disabled,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover,\n.datepicker table tr td.range.today.disabled:hover,\n.datepicker table tr td.range.today:hover.disabled:hover,\n.datepicker table tr td.range.today.disabled.disabled:hover,\n.datepicker table tr td.range.today.disabled:hover.disabled:hover,\n.datepicker table tr td.range.today[disabled]:hover,\n.datepicker table tr td.range.today:hover[disabled]:hover,\n.datepicker table tr td.range.today.disabled[disabled]:hover,\n.datepicker table tr td.range.today.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.range.today:hover,\nfieldset[disabled] .datepicker table tr td.range.today:hover:hover,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover,\n.datepicker table tr td.range.today.disabled:focus,\n.datepicker table tr td.range.today:hover.disabled:focus,\n.datepicker table tr td.range.today.disabled.disabled:focus,\n.datepicker table tr td.range.today.disabled:hover.disabled:focus,\n.datepicker table tr td.range.today[disabled]:focus,\n.datepicker table tr td.range.today:hover[disabled]:focus,\n.datepicker table tr td.range.today.disabled[disabled]:focus,\n.datepicker table tr td.range.today.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.range.today:focus,\nfieldset[disabled] .datepicker table tr td.range.today:hover:focus,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:focus,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus,\n.datepicker table tr td.range.today.disabled:active,\n.datepicker table tr td.range.today:hover.disabled:active,\n.datepicker table tr td.range.today.disabled.disabled:active,\n.datepicker table tr td.range.today.disabled:hover.disabled:active,\n.datepicker table tr td.range.today[disabled]:active,\n.datepicker table tr td.range.today:hover[disabled]:active,\n.datepicker table tr td.range.today.disabled[disabled]:active,\n.datepicker table tr td.range.today.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td.range.today:active,\nfieldset[disabled] .datepicker table tr td.range.today:hover:active,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:active,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover:active,\n.datepicker table tr td.range.today.disabled.active,\n.datepicker table tr td.range.today:hover.disabled.active,\n.datepicker table tr td.range.today.disabled.disabled.active,\n.datepicker table tr td.range.today.disabled:hover.disabled.active,\n.datepicker table tr td.range.today[disabled].active,\n.datepicker table tr td.range.today:hover[disabled].active,\n.datepicker table tr td.range.today.disabled[disabled].active,\n.datepicker table tr td.range.today.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td.range.today.active,\nfieldset[disabled] .datepicker table tr td.range.today:hover.active,\nfieldset[disabled] .datepicker table tr td.range.today.disabled.active,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active {\n  background-color: #f7ca77;\n  border-color: #f1a417;\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  color: #ffffff;\n  background-color: #999999;\n  border-color: #555555;\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:focus,\n.datepicker table tr td.selected:hover:focus,\n.datepicker table tr td.selected.disabled:focus,\n.datepicker table tr td.selected.disabled:hover:focus,\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.open .dropdown-toggle.datepicker table tr td.selected,\n.open .dropdown-toggle.datepicker table tr td.selected:hover,\n.open .dropdown-toggle.datepicker table tr td.selected.disabled,\n.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {\n  color: #ffffff;\n  background-color: #858585;\n  border-color: #373737;\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.open .dropdown-toggle.datepicker table tr td.selected,\n.open .dropdown-toggle.datepicker table tr td.selected:hover,\n.open .dropdown-toggle.datepicker table tr td.selected.disabled,\n.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {\n  background-image: none;\n}\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],\nfieldset[disabled] .datepicker table tr td.selected,\nfieldset[disabled] .datepicker table tr td.selected:hover,\nfieldset[disabled] .datepicker table tr td.selected.disabled,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover,\n.datepicker table tr td.selected.disabled:hover,\n.datepicker table tr td.selected:hover.disabled:hover,\n.datepicker table tr td.selected.disabled.disabled:hover,\n.datepicker table tr td.selected.disabled:hover.disabled:hover,\n.datepicker table tr td.selected[disabled]:hover,\n.datepicker table tr td.selected:hover[disabled]:hover,\n.datepicker table tr td.selected.disabled[disabled]:hover,\n.datepicker table tr td.selected.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.selected:hover,\nfieldset[disabled] .datepicker table tr td.selected:hover:hover,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover,\n.datepicker table tr td.selected.disabled:focus,\n.datepicker table tr td.selected:hover.disabled:focus,\n.datepicker table tr td.selected.disabled.disabled:focus,\n.datepicker table tr td.selected.disabled:hover.disabled:focus,\n.datepicker table tr td.selected[disabled]:focus,\n.datepicker table tr td.selected:hover[disabled]:focus,\n.datepicker table tr td.selected.disabled[disabled]:focus,\n.datepicker table tr td.selected.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.selected:focus,\nfieldset[disabled] .datepicker table tr td.selected:hover:focus,\nfieldset[disabled] .datepicker table tr td.selected.disabled:focus,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus,\n.datepicker table tr td.selected.disabled:active,\n.datepicker table tr td.selected:hover.disabled:active,\n.datepicker table tr td.selected.disabled.disabled:active,\n.datepicker table tr td.selected.disabled:hover.disabled:active,\n.datepicker table tr td.selected[disabled]:active,\n.datepicker table tr td.selected:hover[disabled]:active,\n.datepicker table tr td.selected.disabled[disabled]:active,\n.datepicker table tr td.selected.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td.selected:active,\nfieldset[disabled] .datepicker table tr td.selected:hover:active,\nfieldset[disabled] .datepicker table tr td.selected.disabled:active,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover:active,\n.datepicker table tr td.selected.disabled.active,\n.datepicker table tr td.selected:hover.disabled.active,\n.datepicker table tr td.selected.disabled.disabled.active,\n.datepicker table tr td.selected.disabled:hover.disabled.active,\n.datepicker table tr td.selected[disabled].active,\n.datepicker table tr td.selected:hover[disabled].active,\n.datepicker table tr td.selected.disabled[disabled].active,\n.datepicker table tr td.selected.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td.selected.active,\nfieldset[disabled] .datepicker table tr td.selected:hover.active,\nfieldset[disabled] .datepicker table tr td.selected.disabled.active,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover.active {\n  background-color: #999999;\n  border-color: #555555;\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  color: #ffffff;\n  background-color: #428bca;\n  border-color: #357ebd;\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:focus,\n.datepicker table tr td.active:hover:focus,\n.datepicker table tr td.active.disabled:focus,\n.datepicker table tr td.active.disabled:hover:focus,\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.open .dropdown-toggle.datepicker table tr td.active,\n.open .dropdown-toggle.datepicker table tr td.active:hover,\n.open .dropdown-toggle.datepicker table tr td.active.disabled,\n.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {\n  color: #ffffff;\n  background-color: #3276b1;\n  border-color: #285e8e;\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.open .dropdown-toggle.datepicker table tr td.active,\n.open .dropdown-toggle.datepicker table tr td.active:hover,\n.open .dropdown-toggle.datepicker table tr td.active.disabled,\n.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {\n  background-image: none;\n}\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],\nfieldset[disabled] .datepicker table tr td.active,\nfieldset[disabled] .datepicker table tr td.active:hover,\nfieldset[disabled] .datepicker table tr td.active.disabled,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover,\n.datepicker table tr td.active.disabled:hover,\n.datepicker table tr td.active:hover.disabled:hover,\n.datepicker table tr td.active.disabled.disabled:hover,\n.datepicker table tr td.active.disabled:hover.disabled:hover,\n.datepicker table tr td.active[disabled]:hover,\n.datepicker table tr td.active:hover[disabled]:hover,\n.datepicker table tr td.active.disabled[disabled]:hover,\n.datepicker table tr td.active.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.active:hover,\nfieldset[disabled] .datepicker table tr td.active:hover:hover,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover:hover,\n.datepicker table tr td.active.disabled:focus,\n.datepicker table tr td.active:hover.disabled:focus,\n.datepicker table tr td.active.disabled.disabled:focus,\n.datepicker table tr td.active.disabled:hover.disabled:focus,\n.datepicker table tr td.active[disabled]:focus,\n.datepicker table tr td.active:hover[disabled]:focus,\n.datepicker table tr td.active.disabled[disabled]:focus,\n.datepicker table tr td.active.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.active:focus,\nfieldset[disabled] .datepicker table tr td.active:hover:focus,\nfieldset[disabled] .datepicker table tr td.active.disabled:focus,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover:focus,\n.datepicker table tr td.active.disabled:active,\n.datepicker table tr td.active:hover.disabled:active,\n.datepicker table tr td.active.disabled.disabled:active,\n.datepicker table tr td.active.disabled:hover.disabled:active,\n.datepicker table tr td.active[disabled]:active,\n.datepicker table tr td.active:hover[disabled]:active,\n.datepicker table tr td.active.disabled[disabled]:active,\n.datepicker table tr td.active.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td.active:active,\nfieldset[disabled] .datepicker table tr td.active:hover:active,\nfieldset[disabled] .datepicker table tr td.active.disabled:active,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover:active,\n.datepicker table tr td.active.disabled.active,\n.datepicker table tr td.active:hover.disabled.active,\n.datepicker table tr td.active.disabled.disabled.active,\n.datepicker table tr td.active.disabled:hover.disabled.active,\n.datepicker table tr td.active[disabled].active,\n.datepicker table tr td.active:hover[disabled].active,\n.datepicker table tr td.active.disabled[disabled].active,\n.datepicker table tr td.active.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td.active.active,\nfieldset[disabled] .datepicker table tr td.active:hover.active,\nfieldset[disabled] .datepicker table tr td.active.disabled.active,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover.active {\n  background-color: #428bca;\n  border-color: #357ebd;\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  border-radius: 4px;\n}\n.datepicker table tr td span:hover {\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  color: #ffffff;\n  background-color: #428bca;\n  border-color: #357ebd;\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:focus,\n.datepicker table tr td span.active:hover:focus,\n.datepicker table tr td span.active.disabled:focus,\n.datepicker table tr td span.active.disabled:hover:focus,\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.open .dropdown-toggle.datepicker table tr td span.active,\n.open .dropdown-toggle.datepicker table tr td span.active:hover,\n.open .dropdown-toggle.datepicker table tr td span.active.disabled,\n.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {\n  color: #ffffff;\n  background-color: #3276b1;\n  border-color: #285e8e;\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.open .dropdown-toggle.datepicker table tr td span.active,\n.open .dropdown-toggle.datepicker table tr td span.active:hover,\n.open .dropdown-toggle.datepicker table tr td span.active.disabled,\n.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {\n  background-image: none;\n}\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],\nfieldset[disabled] .datepicker table tr td span.active,\nfieldset[disabled] .datepicker table tr td span.active:hover,\nfieldset[disabled] .datepicker table tr td span.active.disabled,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active:hover.disabled:hover,\n.datepicker table tr td span.active.disabled.disabled:hover,\n.datepicker table tr td span.active.disabled:hover.disabled:hover,\n.datepicker table tr td span.active[disabled]:hover,\n.datepicker table tr td span.active:hover[disabled]:hover,\n.datepicker table tr td span.active.disabled[disabled]:hover,\n.datepicker table tr td span.active.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td span.active:hover,\nfieldset[disabled] .datepicker table tr td span.active:hover:hover,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover,\n.datepicker table tr td span.active.disabled:focus,\n.datepicker table tr td span.active:hover.disabled:focus,\n.datepicker table tr td span.active.disabled.disabled:focus,\n.datepicker table tr td span.active.disabled:hover.disabled:focus,\n.datepicker table tr td span.active[disabled]:focus,\n.datepicker table tr td span.active:hover[disabled]:focus,\n.datepicker table tr td span.active.disabled[disabled]:focus,\n.datepicker table tr td span.active.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td span.active:focus,\nfieldset[disabled] .datepicker table tr td span.active:hover:focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled:focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus,\n.datepicker table tr td span.active.disabled:active,\n.datepicker table tr td span.active:hover.disabled:active,\n.datepicker table tr td span.active.disabled.disabled:active,\n.datepicker table tr td span.active.disabled:hover.disabled:active,\n.datepicker table tr td span.active[disabled]:active,\n.datepicker table tr td span.active:hover[disabled]:active,\n.datepicker table tr td span.active.disabled[disabled]:active,\n.datepicker table tr td span.active.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td span.active:active,\nfieldset[disabled] .datepicker table tr td span.active:hover:active,\nfieldset[disabled] .datepicker table tr td span.active.disabled:active,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover:active,\n.datepicker table tr td span.active.disabled.active,\n.datepicker table tr td span.active:hover.disabled.active,\n.datepicker table tr td span.active.disabled.disabled.active,\n.datepicker table tr td span.active.disabled:hover.disabled.active,\n.datepicker table tr td span.active[disabled].active,\n.datepicker table tr td span.active:hover[disabled].active,\n.datepicker table tr td span.active.disabled[disabled].active,\n.datepicker table tr td span.active.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td span.active.active,\nfieldset[disabled] .datepicker table tr td span.active:hover.active,\nfieldset[disabled] .datepicker table tr td span.active.disabled.active,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover.active {\n  background-color: #428bca;\n  border-color: #357ebd;\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 thead tr:first-child th,\n.datepicker tfoot tr th {\n  cursor: pointer;\n}\n.datepicker thead tr:first-child th:hover,\n.datepicker tfoot tr th:hover {\n  background: #eeeeee;\n}\n.datepicker .cw {\n  font-size: 10px;\n  width: 12px;\n  padding: 0 2px 0 5px;\n  vertical-align: middle;\n}\n.datepicker thead tr:first-child .cw {\n  cursor: default;\n  background-color: transparent;\n}\n.input-group.date .input-group-addon {\n  cursor: pointer;\n}\n.input-daterange {\n  width: 100%;\n}\n.input-daterange input {\n  text-align: center;\n}\n.input-daterange input:first-child {\n  border-radius: 3px 0 0 3px;\n}\n.input-daterange input:last-child {\n  border-radius: 0 3px 3px 0;\n}\n.input-daterange .input-group-addon {\n  width: auto;\n  min-width: 16px;\n  padding: 4px 5px;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: center;\n  text-shadow: 0 1px 0 #fff;\n  vertical-align: middle;\n  background-color: #eeeeee;\n  border: solid #cccccc;\n  border-width: 1px 0;\n  margin-left: -5px;\n  margin-right: -5px;\n}\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker3.standalone.css",
    "content": "/*!\n * Datepicker for Bootstrap v1.4.1 (https://github.com/eternicode/bootstrap-datepicker)\n *\n * Copyright 2012 Stefan Petre\n * Improvements by Andrew Rowls\n * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)\n */\n.datepicker {\n  padding: 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 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 #ccc;\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 #fff;\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-top:before {\n  top: -7px;\n}\n.datepicker-dropdown.datepicker-orient-top:after {\n  top: -6px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:before {\n  bottom: -7px;\n  border-bottom: 0;\n  border-top: 7px solid #999;\n}\n.datepicker-dropdown.datepicker-orient-bottom:after {\n  bottom: -6px;\n  border-bottom: 0;\n  border-top: 6px solid #fff;\n}\n.datepicker > div {\n  display: none;\n}\n.datepicker.days .datepicker-days,\n.datepicker.months .datepicker-months,\n.datepicker.years .datepicker-years {\n  display: block;\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 table tr td,\n.datepicker table tr th {\n  text-align: center;\n  width: 30px;\n  height: 30px;\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.today,\n.datepicker table tr td.today:hover,\n.datepicker table tr td.today.disabled,\n.datepicker table tr td.today.disabled:hover {\n  color: #000000;\n  background-color: #ffdb99;\n  border-color: #ffb733;\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:focus,\n.datepicker table tr td.today:hover:focus,\n.datepicker table tr td.today.disabled:focus,\n.datepicker table tr td.today.disabled:hover:focus,\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.open .dropdown-toggle.datepicker table tr td.today,\n.open .dropdown-toggle.datepicker table tr td.today:hover,\n.open .dropdown-toggle.datepicker table tr td.today.disabled,\n.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {\n  color: #000000;\n  background-color: #ffcd70;\n  border-color: #f59e00;\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.open .dropdown-toggle.datepicker table tr td.today,\n.open .dropdown-toggle.datepicker table tr td.today:hover,\n.open .dropdown-toggle.datepicker table tr td.today.disabled,\n.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {\n  background-image: none;\n}\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],\nfieldset[disabled] .datepicker table tr td.today,\nfieldset[disabled] .datepicker table tr td.today:hover,\nfieldset[disabled] .datepicker table tr td.today.disabled,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover,\n.datepicker table tr td.today.disabled:hover,\n.datepicker table tr td.today:hover.disabled:hover,\n.datepicker table tr td.today.disabled.disabled:hover,\n.datepicker table tr td.today.disabled:hover.disabled:hover,\n.datepicker table tr td.today[disabled]:hover,\n.datepicker table tr td.today:hover[disabled]:hover,\n.datepicker table tr td.today.disabled[disabled]:hover,\n.datepicker table tr td.today.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.today:hover,\nfieldset[disabled] .datepicker table tr td.today:hover:hover,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover:hover,\n.datepicker table tr td.today.disabled:focus,\n.datepicker table tr td.today:hover.disabled:focus,\n.datepicker table tr td.today.disabled.disabled:focus,\n.datepicker table tr td.today.disabled:hover.disabled:focus,\n.datepicker table tr td.today[disabled]:focus,\n.datepicker table tr td.today:hover[disabled]:focus,\n.datepicker table tr td.today.disabled[disabled]:focus,\n.datepicker table tr td.today.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.today:focus,\nfieldset[disabled] .datepicker table tr td.today:hover:focus,\nfieldset[disabled] .datepicker table tr td.today.disabled:focus,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover:focus,\n.datepicker table tr td.today.disabled:active,\n.datepicker table tr td.today:hover.disabled:active,\n.datepicker table tr td.today.disabled.disabled:active,\n.datepicker table tr td.today.disabled:hover.disabled:active,\n.datepicker table tr td.today[disabled]:active,\n.datepicker table tr td.today:hover[disabled]:active,\n.datepicker table tr td.today.disabled[disabled]:active,\n.datepicker table tr td.today.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td.today:active,\nfieldset[disabled] .datepicker table tr td.today:hover:active,\nfieldset[disabled] .datepicker table tr td.today.disabled:active,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover:active,\n.datepicker table tr td.today.disabled.active,\n.datepicker table tr td.today:hover.disabled.active,\n.datepicker table tr td.today.disabled.disabled.active,\n.datepicker table tr td.today.disabled:hover.disabled.active,\n.datepicker table tr td.today[disabled].active,\n.datepicker table tr td.today:hover[disabled].active,\n.datepicker table tr td.today.disabled[disabled].active,\n.datepicker table tr td.today.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td.today.active,\nfieldset[disabled] .datepicker table tr td.today:hover.active,\nfieldset[disabled] .datepicker table tr td.today.disabled.active,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover.active {\n  background-color: #ffdb99;\n  border-color: #ffb733;\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  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  color: #000000;\n  background-color: #f7ca77;\n  border-color: #f1a417;\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:focus,\n.datepicker table tr td.range.today:hover:focus,\n.datepicker table tr td.range.today.disabled:focus,\n.datepicker table tr td.range.today.disabled:hover:focus,\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.open .dropdown-toggle.datepicker table tr td.range.today,\n.open .dropdown-toggle.datepicker table tr td.range.today:hover,\n.open .dropdown-toggle.datepicker table tr td.range.today.disabled,\n.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {\n  color: #000000;\n  background-color: #f4bb51;\n  border-color: #bf800c;\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.open .dropdown-toggle.datepicker table tr td.range.today,\n.open .dropdown-toggle.datepicker table tr td.range.today:hover,\n.open .dropdown-toggle.datepicker table tr td.range.today.disabled,\n.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {\n  background-image: none;\n}\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],\nfieldset[disabled] .datepicker table tr td.range.today,\nfieldset[disabled] .datepicker table tr td.range.today:hover,\nfieldset[disabled] .datepicker table tr td.range.today.disabled,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover,\n.datepicker table tr td.range.today.disabled:hover,\n.datepicker table tr td.range.today:hover.disabled:hover,\n.datepicker table tr td.range.today.disabled.disabled:hover,\n.datepicker table tr td.range.today.disabled:hover.disabled:hover,\n.datepicker table tr td.range.today[disabled]:hover,\n.datepicker table tr td.range.today:hover[disabled]:hover,\n.datepicker table tr td.range.today.disabled[disabled]:hover,\n.datepicker table tr td.range.today.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.range.today:hover,\nfieldset[disabled] .datepicker table tr td.range.today:hover:hover,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover,\n.datepicker table tr td.range.today.disabled:focus,\n.datepicker table tr td.range.today:hover.disabled:focus,\n.datepicker table tr td.range.today.disabled.disabled:focus,\n.datepicker table tr td.range.today.disabled:hover.disabled:focus,\n.datepicker table tr td.range.today[disabled]:focus,\n.datepicker table tr td.range.today:hover[disabled]:focus,\n.datepicker table tr td.range.today.disabled[disabled]:focus,\n.datepicker table tr td.range.today.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.range.today:focus,\nfieldset[disabled] .datepicker table tr td.range.today:hover:focus,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:focus,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus,\n.datepicker table tr td.range.today.disabled:active,\n.datepicker table tr td.range.today:hover.disabled:active,\n.datepicker table tr td.range.today.disabled.disabled:active,\n.datepicker table tr td.range.today.disabled:hover.disabled:active,\n.datepicker table tr td.range.today[disabled]:active,\n.datepicker table tr td.range.today:hover[disabled]:active,\n.datepicker table tr td.range.today.disabled[disabled]:active,\n.datepicker table tr td.range.today.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td.range.today:active,\nfieldset[disabled] .datepicker table tr td.range.today:hover:active,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:active,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover:active,\n.datepicker table tr td.range.today.disabled.active,\n.datepicker table tr td.range.today:hover.disabled.active,\n.datepicker table tr td.range.today.disabled.disabled.active,\n.datepicker table tr td.range.today.disabled:hover.disabled.active,\n.datepicker table tr td.range.today[disabled].active,\n.datepicker table tr td.range.today:hover[disabled].active,\n.datepicker table tr td.range.today.disabled[disabled].active,\n.datepicker table tr td.range.today.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td.range.today.active,\nfieldset[disabled] .datepicker table tr td.range.today:hover.active,\nfieldset[disabled] .datepicker table tr td.range.today.disabled.active,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active {\n  background-color: #f7ca77;\n  border-color: #f1a417;\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  color: #ffffff;\n  background-color: #999999;\n  border-color: #555555;\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:focus,\n.datepicker table tr td.selected:hover:focus,\n.datepicker table tr td.selected.disabled:focus,\n.datepicker table tr td.selected.disabled:hover:focus,\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.open .dropdown-toggle.datepicker table tr td.selected,\n.open .dropdown-toggle.datepicker table tr td.selected:hover,\n.open .dropdown-toggle.datepicker table tr td.selected.disabled,\n.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {\n  color: #ffffff;\n  background-color: #858585;\n  border-color: #373737;\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.open .dropdown-toggle.datepicker table tr td.selected,\n.open .dropdown-toggle.datepicker table tr td.selected:hover,\n.open .dropdown-toggle.datepicker table tr td.selected.disabled,\n.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {\n  background-image: none;\n}\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],\nfieldset[disabled] .datepicker table tr td.selected,\nfieldset[disabled] .datepicker table tr td.selected:hover,\nfieldset[disabled] .datepicker table tr td.selected.disabled,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover,\n.datepicker table tr td.selected.disabled:hover,\n.datepicker table tr td.selected:hover.disabled:hover,\n.datepicker table tr td.selected.disabled.disabled:hover,\n.datepicker table tr td.selected.disabled:hover.disabled:hover,\n.datepicker table tr td.selected[disabled]:hover,\n.datepicker table tr td.selected:hover[disabled]:hover,\n.datepicker table tr td.selected.disabled[disabled]:hover,\n.datepicker table tr td.selected.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.selected:hover,\nfieldset[disabled] .datepicker table tr td.selected:hover:hover,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover,\n.datepicker table tr td.selected.disabled:focus,\n.datepicker table tr td.selected:hover.disabled:focus,\n.datepicker table tr td.selected.disabled.disabled:focus,\n.datepicker table tr td.selected.disabled:hover.disabled:focus,\n.datepicker table tr td.selected[disabled]:focus,\n.datepicker table tr td.selected:hover[disabled]:focus,\n.datepicker table tr td.selected.disabled[disabled]:focus,\n.datepicker table tr td.selected.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.selected:focus,\nfieldset[disabled] .datepicker table tr td.selected:hover:focus,\nfieldset[disabled] .datepicker table tr td.selected.disabled:focus,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus,\n.datepicker table tr td.selected.disabled:active,\n.datepicker table tr td.selected:hover.disabled:active,\n.datepicker table tr td.selected.disabled.disabled:active,\n.datepicker table tr td.selected.disabled:hover.disabled:active,\n.datepicker table tr td.selected[disabled]:active,\n.datepicker table tr td.selected:hover[disabled]:active,\n.datepicker table tr td.selected.disabled[disabled]:active,\n.datepicker table tr td.selected.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td.selected:active,\nfieldset[disabled] .datepicker table tr td.selected:hover:active,\nfieldset[disabled] .datepicker table tr td.selected.disabled:active,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover:active,\n.datepicker table tr td.selected.disabled.active,\n.datepicker table tr td.selected:hover.disabled.active,\n.datepicker table tr td.selected.disabled.disabled.active,\n.datepicker table tr td.selected.disabled:hover.disabled.active,\n.datepicker table tr td.selected[disabled].active,\n.datepicker table tr td.selected:hover[disabled].active,\n.datepicker table tr td.selected.disabled[disabled].active,\n.datepicker table tr td.selected.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td.selected.active,\nfieldset[disabled] .datepicker table tr td.selected:hover.active,\nfieldset[disabled] .datepicker table tr td.selected.disabled.active,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover.active {\n  background-color: #999999;\n  border-color: #555555;\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  color: #ffffff;\n  background-color: #428bca;\n  border-color: #357ebd;\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:focus,\n.datepicker table tr td.active:hover:focus,\n.datepicker table tr td.active.disabled:focus,\n.datepicker table tr td.active.disabled:hover:focus,\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.open .dropdown-toggle.datepicker table tr td.active,\n.open .dropdown-toggle.datepicker table tr td.active:hover,\n.open .dropdown-toggle.datepicker table tr td.active.disabled,\n.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {\n  color: #ffffff;\n  background-color: #3276b1;\n  border-color: #285e8e;\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.open .dropdown-toggle.datepicker table tr td.active,\n.open .dropdown-toggle.datepicker table tr td.active:hover,\n.open .dropdown-toggle.datepicker table tr td.active.disabled,\n.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {\n  background-image: none;\n}\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],\nfieldset[disabled] .datepicker table tr td.active,\nfieldset[disabled] .datepicker table tr td.active:hover,\nfieldset[disabled] .datepicker table tr td.active.disabled,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover,\n.datepicker table tr td.active.disabled:hover,\n.datepicker table tr td.active:hover.disabled:hover,\n.datepicker table tr td.active.disabled.disabled:hover,\n.datepicker table tr td.active.disabled:hover.disabled:hover,\n.datepicker table tr td.active[disabled]:hover,\n.datepicker table tr td.active:hover[disabled]:hover,\n.datepicker table tr td.active.disabled[disabled]:hover,\n.datepicker table tr td.active.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.active:hover,\nfieldset[disabled] .datepicker table tr td.active:hover:hover,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover:hover,\n.datepicker table tr td.active.disabled:focus,\n.datepicker table tr td.active:hover.disabled:focus,\n.datepicker table tr td.active.disabled.disabled:focus,\n.datepicker table tr td.active.disabled:hover.disabled:focus,\n.datepicker table tr td.active[disabled]:focus,\n.datepicker table tr td.active:hover[disabled]:focus,\n.datepicker table tr td.active.disabled[disabled]:focus,\n.datepicker table tr td.active.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.active:focus,\nfieldset[disabled] .datepicker table tr td.active:hover:focus,\nfieldset[disabled] .datepicker table tr td.active.disabled:focus,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover:focus,\n.datepicker table tr td.active.disabled:active,\n.datepicker table tr td.active:hover.disabled:active,\n.datepicker table tr td.active.disabled.disabled:active,\n.datepicker table tr td.active.disabled:hover.disabled:active,\n.datepicker table tr td.active[disabled]:active,\n.datepicker table tr td.active:hover[disabled]:active,\n.datepicker table tr td.active.disabled[disabled]:active,\n.datepicker table tr td.active.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td.active:active,\nfieldset[disabled] .datepicker table tr td.active:hover:active,\nfieldset[disabled] .datepicker table tr td.active.disabled:active,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover:active,\n.datepicker table tr td.active.disabled.active,\n.datepicker table tr td.active:hover.disabled.active,\n.datepicker table tr td.active.disabled.disabled.active,\n.datepicker table tr td.active.disabled:hover.disabled.active,\n.datepicker table tr td.active[disabled].active,\n.datepicker table tr td.active:hover[disabled].active,\n.datepicker table tr td.active.disabled[disabled].active,\n.datepicker table tr td.active.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td.active.active,\nfieldset[disabled] .datepicker table tr td.active:hover.active,\nfieldset[disabled] .datepicker table tr td.active.disabled.active,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover.active {\n  background-color: #428bca;\n  border-color: #357ebd;\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  border-radius: 4px;\n}\n.datepicker table tr td span:hover {\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  color: #ffffff;\n  background-color: #428bca;\n  border-color: #357ebd;\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:focus,\n.datepicker table tr td span.active:hover:focus,\n.datepicker table tr td span.active.disabled:focus,\n.datepicker table tr td span.active.disabled:hover:focus,\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.open .dropdown-toggle.datepicker table tr td span.active,\n.open .dropdown-toggle.datepicker table tr td span.active:hover,\n.open .dropdown-toggle.datepicker table tr td span.active.disabled,\n.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {\n  color: #ffffff;\n  background-color: #3276b1;\n  border-color: #285e8e;\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.open .dropdown-toggle.datepicker table tr td span.active,\n.open .dropdown-toggle.datepicker table tr td span.active:hover,\n.open .dropdown-toggle.datepicker table tr td span.active.disabled,\n.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {\n  background-image: none;\n}\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],\nfieldset[disabled] .datepicker table tr td span.active,\nfieldset[disabled] .datepicker table tr td span.active:hover,\nfieldset[disabled] .datepicker table tr td span.active.disabled,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active:hover.disabled:hover,\n.datepicker table tr td span.active.disabled.disabled:hover,\n.datepicker table tr td span.active.disabled:hover.disabled:hover,\n.datepicker table tr td span.active[disabled]:hover,\n.datepicker table tr td span.active:hover[disabled]:hover,\n.datepicker table tr td span.active.disabled[disabled]:hover,\n.datepicker table tr td span.active.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td span.active:hover,\nfieldset[disabled] .datepicker table tr td span.active:hover:hover,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover,\n.datepicker table tr td span.active.disabled:focus,\n.datepicker table tr td span.active:hover.disabled:focus,\n.datepicker table tr td span.active.disabled.disabled:focus,\n.datepicker table tr td span.active.disabled:hover.disabled:focus,\n.datepicker table tr td span.active[disabled]:focus,\n.datepicker table tr td span.active:hover[disabled]:focus,\n.datepicker table tr td span.active.disabled[disabled]:focus,\n.datepicker table tr td span.active.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td span.active:focus,\nfieldset[disabled] .datepicker table tr td span.active:hover:focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled:focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus,\n.datepicker table tr td span.active.disabled:active,\n.datepicker table tr td span.active:hover.disabled:active,\n.datepicker table tr td span.active.disabled.disabled:active,\n.datepicker table tr td span.active.disabled:hover.disabled:active,\n.datepicker table tr td span.active[disabled]:active,\n.datepicker table tr td span.active:hover[disabled]:active,\n.datepicker table tr td span.active.disabled[disabled]:active,\n.datepicker table tr td span.active.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td span.active:active,\nfieldset[disabled] .datepicker table tr td span.active:hover:active,\nfieldset[disabled] .datepicker table tr td span.active.disabled:active,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover:active,\n.datepicker table tr td span.active.disabled.active,\n.datepicker table tr td span.active:hover.disabled.active,\n.datepicker table tr td span.active.disabled.disabled.active,\n.datepicker table tr td span.active.disabled:hover.disabled.active,\n.datepicker table tr td span.active[disabled].active,\n.datepicker table tr td span.active:hover[disabled].active,\n.datepicker table tr td span.active.disabled[disabled].active,\n.datepicker table tr td span.active.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td span.active.active,\nfieldset[disabled] .datepicker table tr td span.active:hover.active,\nfieldset[disabled] .datepicker table tr td span.active.disabled.active,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover.active {\n  background-color: #428bca;\n  border-color: #357ebd;\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 thead tr:first-child th,\n.datepicker tfoot tr th {\n  cursor: pointer;\n}\n.datepicker thead tr:first-child th:hover,\n.datepicker tfoot tr th:hover {\n  background: #eeeeee;\n}\n.datepicker .cw {\n  font-size: 10px;\n  width: 12px;\n  padding: 0 2px 0 5px;\n  vertical-align: middle;\n}\n.datepicker thead tr:first-child .cw {\n  cursor: default;\n  background-color: transparent;\n}\n.input-group.date .input-group-addon {\n  cursor: pointer;\n}\n.input-daterange {\n  width: 100%;\n}\n.input-daterange input {\n  text-align: center;\n}\n.input-daterange input:first-child {\n  border-radius: 3px 0 0 3px;\n}\n.input-daterange input:last-child {\n  border-radius: 0 3px 3px 0;\n}\n.input-daterange .input-group-addon {\n  width: auto;\n  min-width: 16px;\n  padding: 4px 5px;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: center;\n  text-shadow: 0 1px 0 #fff;\n  vertical-align: middle;\n  background-color: #eeeeee;\n  border: solid #cccccc;\n  border-width: 1px 0;\n  margin-left: -5px;\n  margin-right: -5px;\n}\n.datepicker.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  float: left;\n  display: none;\n  min-width: 160px;\n  list-style: none;\n  background-color: #ffffff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 5px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  -webkit-background-clip: padding-box;\n  -moz-background-clip: padding;\n  background-clip: padding-box;\n  *border-right-width: 2px;\n  *border-bottom-width: 2px;\n  color: #333333;\n  font-size: 13px;\n  line-height: 1.42857143;\n}\n.datepicker.dropdown-menu th,\n.datepicker.datepicker-inline th,\n.datepicker.dropdown-menu td,\n.datepicker.datepicker-inline td {\n  padding: 0px 5px;\n}\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-datepicker/dist/js/bootstrap-datepicker.js",
    "content": "/*!\n * Datepicker for Bootstrap v1.4.1 (https://github.com/eternicode/bootstrap-datepicker)\n *\n * Copyright 2012 Stefan Petre\n * Improvements by Andrew Rowls\n * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)\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\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\t\t\t\t\tif (this[i].valueOf() === val)\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\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.isInline = false;\n\t\tthis.isInput = this.element.is('input');\n\t\tthis.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;\n\t\tthis.hasInput = this.component && this.element.find('input').length;\n\t\tif (this.component && this.component.length === 0)\n\t\t\tthis.component = false;\n\n\t\tthis.picker = $(DPGlobal.template);\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\tthis.viewMode = this.o.startView;\n\n\t\tif (this.o.calendarWeeks)\n\t\t\tthis.picker.find('tfoot .today, tfoot .clear')\n\t\t\t\t\t\t.attr('colspan', function(i, val){\n\t\t\t\t\t\t\treturn parseInt(val) + 1;\n\t\t\t\t\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.setDatesDisabled(this.o.datesDisabled);\n\n\t\tthis.fillDow();\n\t\tthis.fillMonths();\n\n\t\tthis._allow_update = true;\n\n\t\tthis.update();\n\t\tthis.showMode();\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_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\tswitch (o.startView){\n\t\t\t\tcase 2:\n\t\t\t\tcase 'decade':\n\t\t\t\t\to.startView = 2;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\tcase 'year':\n\t\t\t\t\to.startView = 1;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\to.startView = 0;\n\t\t\t}\n\n\t\t\tswitch (o.minViewMode){\n\t\t\t\tcase 1:\n\t\t\t\tcase 'months':\n\t\t\t\t\to.minViewMode = 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\tcase 'years':\n\t\t\t\t\to.minViewMode = 2;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\to.minViewMode = 0;\n\t\t\t}\n\n\t\t\to.startView = Math.max(o.startView, o.minViewMode);\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);\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);\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 = o.daysOfWeekDisabled||[];\n\t\t\tif (!$.isArray(o.daysOfWeekDisabled))\n\t\t\t\to.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\\s]*/);\n\t\t\to.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){\n\t\t\t\treturn parseInt(d, 10);\n\t\t\t});\n\n\t\t\to.datesDisabled = o.datesDisabled||[];\n\t\t\tif (!$.isArray(o.datesDisabled)) {\n\t\t\t\tvar datesDisabled = [];\n\t\t\t\tdatesDisabled.push(DPGlobal.parseDate(o.datesDisabled, format, o.language));\n\t\t\t\to.datesDisabled = datesDisabled;\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);\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\to.showOnFocus = o.showOnFocus !== undefined ? o.showOnFocus : true;\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}\n\t\t\t\telse 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}\n\t\t\t\telse 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            };\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            else if (this.component && this.hasInput) { // component: input + button\n                this._events = [\n                    // For components that are not readonly, allow keyboard nav\n                    [this.element.find('input'), events],\n                    [this.component, {\n                        click: $.proxy(this.show, this)\n                    }]\n                ];\n            }\n\t\t\telse if (this.element.is('div')){  // inline datepicker\n\t\t\t\tthis.isInline = true;\n\t\t\t}\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}]\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\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[$(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)){\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\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}\n\t\t\t\t\telse 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.element.attr('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)\n\t\t\t\treturn this;\n\t\t\tif (!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.viewMode = this.o.startView;\n\t\t\tthis.showMode();\n\n\t\t\tif (\n\t\t\t\tthis.o.forceParse &&\n\t\t\t\t(\n\t\t\t\t\tthis.isInput && this.element.val() ||\n\t\t\t\t\tthis.hasInput && this.element.find('input').val()\n\t\t\t\t)\n\t\t\t)\n\t\t\t\tthis.setValue();\n\t\t\tthis._trigger('hide');\n\t\t\treturn this;\n\t\t},\n\n\t\tremove: 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\t_utc_to_local: function(utc){\n\t\t\treturn utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000));\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 && new Date(Date.UTC(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 (typeof 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\tvar element;\n\t\t\tif (this.isInput) {\n\t\t\t\telement = this.element;\n\t\t\t} else if (this.component) {\n\t\t\t\telement = this.element.find('input');\n\t\t\t}\n\n\t\t\tif (element) {\n\t\t\t\telement.val('').change();\n\t\t\t}\n\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\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.update.apply(this, $.map(args, this._utc_to_local));\n\t\t\tthis._trigger('changeDate');\n\t\t\tthis.setValue();\n\t\t\treturn this;\n\t\t},\n\n\t\tsetDate: alias('setDates'),\n\t\tsetUTCDate: alias('setUTCDates'),\n\n\t\tsetValue: function(){\n\t\t\tvar formatted = this.getFormattedDate();\n\t\t\tif (!this.isInput){\n\t\t\t\tif (this.component){\n\t\t\t\t\tthis.element.find('input').val(formatted).change();\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.element.val(formatted).change();\n\t\t\t}\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\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\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\tthis.updateNavArrows();\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\tthis.updateNavArrows();\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\twindowWidth = $(this.o.container).width(),\n\t\t\t\twindowHeight = $(this.o.container).height(),\n\t\t\t\tscrollTop = $(this.o.container).scrollTop(),\n\t\t\t\tappendOffset = $(this.o.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) + 10;\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\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 = offset.left + width - calendarWidth;\n\t\t\t\t} else {\n\t\t\t\t\t// Default to left\n\t\t\t\t\tthis.picker.addClass('datepicker-orient-left');\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, bottom_overflow;\n\t\t\tif (yorient === 'auto'){\n\t\t\t\ttop_overflow = -scrollTop + top - calendarHeight;\n\t\t\t\tbottom_overflow = scrollTop + windowHeight - (top + height + calendarHeight);\n\t\t\t\tif (Math.max(top_overflow, bottom_overflow) === bottom_overflow)\n\t\t\t\t\tyorient = 'top';\n\t\t\t\telse\n\t\t\t\t\tyorient = 'bottom';\n\t\t\t}\n\t\t\tthis.picker.addClass('datepicker-orient-' + yorient);\n\t\t\tif (yorient === 'top')\n\t\t\t\ttop += height;\n\t\t\telse\n\t\t\t\ttop -= calendarHeight + parseInt(this.picker.css('padding-top'));\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}\n\t\t\telse {\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.element.find('input').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);\n\t\t\t}, this));\n\t\t\tdates = $.grep(dates, $.proxy(function(date){\n\t\t\t\treturn (\n\t\t\t\t\tdate < this.o.startDate ||\n\t\t\t\t\tdate > this.o.endDate ||\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.dates.length)\n\t\t\t\tthis.viewDate = new Date(this.dates.get(-1));\n\t\t\telse if (this.viewDate < this.o.startDate)\n\t\t\t\tthis.viewDate = new Date(this.o.startDate);\n\t\t\telse if (this.viewDate > this.o.endDate)\n\t\t\t\tthis.viewDate = new Date(this.o.endDate);\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}\n\t\t\telse if (dates.length){\n\t\t\t\t// setting date by typing\n\t\t\t\tif (String(oldDates) !== String(this.dates))\n\t\t\t\t\tthis._trigger('changeDate');\n\t\t\t}\n\t\t\tif (!this.dates.length && oldDates.length)\n\t\t\t\tthis._trigger('clearDate');\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\tthis.picker.find('.datepicker-days thead tr:first-child .datepicker-switch')\n\t\t\t\t\t.attr('colspan', function(i, val){\n\t\t\t\t\t\treturn parseInt(val) + 1;\n\t\t\t\t\t});\n\t\t\t\tvar cell = '<th class=\"cw\">&#160;</th>';\n\t\t\t\thtml += cell;\n\t\t\t}\n\t\t\twhile (dowCnt < this.o.weekStart + 7){\n\t\t\t\thtml += '<th class=\"dow\">'+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\t\t\tvar html = '',\n\t\t\ti = 0;\n\t\t\twhile (i < 12){\n\t\t\t\thtml += '<span class=\"month\">'+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 = new Date();\n\t\t\tif (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){\n\t\t\t\tcls.push('old');\n\t\t\t}\n\t\t\telse 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 local today, not UTC today\n\t\t\tif (this.o.todayHighlight &&\n\t\t\t\tdate.getUTCFullYear() === today.getFullYear() &&\n\t\t\t\tdate.getUTCMonth() === today.getMonth() &&\n\t\t\t\tdate.getUTCDate() === today.getDate()){\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 (date.valueOf() < this.o.startDate || date.valueOf() > this.o.endDate ||\n\t\t\t\t$.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1){\n\t\t\t\tcls.push('disabled');\n\t\t\t}\n\t\t\tif (this.o.datesDisabled.length > 0 &&\n\t\t\t\t$.grep(this.o.datesDisabled, function(d){\n\t\t\t\t\treturn isUTCEquals(date, d); }).length > 0) {\n\t\t\t\tcls.push('disabled', 'disabled-date');\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}\n\t\t\treturn cls;\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\ttooltip;\n\t\t\tif (isNaN(year) || isNaN(month))\n\t\t\t\treturn;\n\t\t\tthis.picker.find('.datepicker-days thead .datepicker-switch')\n\t\t\t\t\t\t.text(dates[this.o.language].months[month]+' '+year);\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.updateNavArrows();\n\t\t\tthis.fillMonths();\n\t\t\tvar prevMonth = UTCDate(year, month-1, 28),\n\t\t\t\tday = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());\n\t\t\tprevMonth.setUTCDate(day);\n\t\t\tprevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);\n\t\t\tvar nextMonth = new Date(prevMonth);\n\t\t\tnextMonth.setUTCDate(nextMonth.getUTCDate() + 42);\n\t\t\tnextMonth = nextMonth.valueOf();\n\t\t\tvar html = [];\n\t\t\tvar clsName;\n\t\t\twhile (prevMonth.valueOf() < nextMonth){\n\t\t\t\tif (prevMonth.getUTCDay() === 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 - prevMonth.getUTCDay() - 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\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\tvar before = 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\tclsName = $.unique(clsName);\n\t\t\t\thtml.push('<td class=\"'+clsName.join(' ')+'\"' + (tooltip ? ' title=\"'+tooltip+'\"' : '') + '>'+prevMonth.getUTCDate() + '</td>');\n\t\t\t\ttooltip = null;\n\t\t\t\tif (prevMonth.getUTCDay() === 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').empty().append(html.join(''));\n\n\t\t\tvar months = this.picker.find('.datepicker-months')\n\t\t\t\t\t\t.find('th:eq(1)')\n\t\t\t\t\t\t\t.text(year)\n\t\t\t\t\t\t\t.end()\n\t\t\t\t\t\t.find('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\t\t\t\t\tif (!$(month).hasClass('disabled')) {\n\t\t\t\t\t\tvar moDate = new Date(year, i, 1);\n\t\t\t\t\t\tvar before = that.o.beforeShowMonth(moDate);\n\t\t\t\t\t\tif (before === false)\n\t\t\t\t\t\t\t$(month).addClass('disabled');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thtml = '';\n\t\t\tyear = parseInt(year/10, 10) * 10;\n\t\t\tvar yearCont = this.picker.find('.datepicker-years')\n\t\t\t\t\t\t\t\t.find('th:eq(1)')\n\t\t\t\t\t\t\t\t\t.text(year + '-' + (year + 9))\n\t\t\t\t\t\t\t\t\t.end()\n\t\t\t\t\t\t\t\t.find('td');\n\t\t\tyear -= 1;\n\t\t\tvar years = $.map(this.dates, function(d){\n\t\t\t\t\treturn d.getUTCFullYear();\n\t\t\t\t}),\n\t\t\t\tclasses;\n\t\t\tfor (var i = -1; i < 11; i++){\n\t\t\t\tclasses = ['year'];\n\t\t\t\tif (i === -1)\n\t\t\t\t\tclasses.push('old');\n\t\t\t\telse if (i === 10)\n\t\t\t\t\tclasses.push('new');\n\t\t\t\tif ($.inArray(year, years) !== -1)\n\t\t\t\t\tclasses.push('active');\n\t\t\t\tif (year < startYear || year > endYear)\n\t\t\t\t\tclasses.push('disabled');\n\t\t\t\thtml += '<span class=\"' + classes.join(' ') + '\">' + year + '</span>';\n\t\t\t\tyear += 1;\n\t\t\t}\n\t\t\tyearCont.html(html);\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\tswitch (this.viewMode){\n\t\t\t\tcase 0:\n\t\t\t\t\tif (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){\n\t\t\t\t\t\tthis.picker.find('.prev').css({visibility: 'hidden'});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.picker.find('.prev').css({visibility: 'visible'});\n\t\t\t\t\t}\n\t\t\t\t\tif (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){\n\t\t\t\t\t\tthis.picker.find('.next').css({visibility: 'hidden'});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.picker.find('.next').css({visibility: 'visible'});\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\t\tif (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear()){\n\t\t\t\t\t\tthis.picker.find('.prev').css({visibility: 'hidden'});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.picker.find('.prev').css({visibility: 'visible'});\n\t\t\t\t\t}\n\t\t\t\t\tif (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear()){\n\t\t\t\t\t\tthis.picker.find('.next').css({visibility: 'hidden'});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.picker.find('.next').css({visibility: 'visible'});\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\n\t\tclick: function(e){\n\t\t\te.preventDefault();\n\t\t\tvar target = $(e.target).closest('span, td, th'),\n\t\t\t\tyear, month, day;\n\t\t\tif (target.length === 1){\n\t\t\t\tswitch (target[0].nodeName.toLowerCase()){\n\t\t\t\t\tcase 'th':\n\t\t\t\t\t\tswitch (target[0].className){\n\t\t\t\t\t\t\tcase 'datepicker-switch':\n\t\t\t\t\t\t\t\tthis.showMode(1);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'prev':\n\t\t\t\t\t\t\tcase 'next':\n\t\t\t\t\t\t\t\tvar dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1);\n\t\t\t\t\t\t\t\tswitch (this.viewMode){\n\t\t\t\t\t\t\t\t\tcase 0:\n\t\t\t\t\t\t\t\t\t\tthis.viewDate = this.moveMonth(this.viewDate, dir);\n\t\t\t\t\t\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t\tthis.viewDate = this.moveYear(this.viewDate, dir);\n\t\t\t\t\t\t\t\t\t\tif (this.viewMode === 1)\n\t\t\t\t\t\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthis.fill();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'today':\n\t\t\t\t\t\t\t\tvar date = new Date();\n\t\t\t\t\t\t\t\tdate = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);\n\n\t\t\t\t\t\t\t\tthis.showMode(-2);\n\t\t\t\t\t\t\t\tvar which = this.o.todayBtn === 'linked' ? null : 'view';\n\t\t\t\t\t\t\t\tthis._setDate(date, which);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'clear':\n\t\t\t\t\t\t\t\tthis.clearDates();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'span':\n\t\t\t\t\t\tif (!target.hasClass('disabled')){\n\t\t\t\t\t\t\tthis.viewDate.setUTCDate(1);\n\t\t\t\t\t\t\tif (target.hasClass('month')){\n\t\t\t\t\t\t\t\tday = 1;\n\t\t\t\t\t\t\t\tmonth = target.parent().find('span').index(target);\n\t\t\t\t\t\t\t\tyear = this.viewDate.getUTCFullYear();\n\t\t\t\t\t\t\t\tthis.viewDate.setUTCMonth(month);\n\t\t\t\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n\t\t\t\t\t\t\t\tif (this.o.minViewMode === 1){\n\t\t\t\t\t\t\t\t\tthis._setDate(UTCDate(year, month, day));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tday = 1;\n\t\t\t\t\t\t\t\tmonth = 0;\n\t\t\t\t\t\t\t\tyear = parseInt(target.text(), 10)||0;\n\t\t\t\t\t\t\t\tthis.viewDate.setUTCFullYear(year);\n\t\t\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n\t\t\t\t\t\t\t\tif (this.o.minViewMode === 2){\n\t\t\t\t\t\t\t\t\tthis._setDate(UTCDate(year, month, day));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.showMode(-1);\n\t\t\t\t\t\t\tthis.fill();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'td':\n\t\t\t\t\t\tif (target.hasClass('day') && !target.hasClass('disabled')){\n\t\t\t\t\t\t\tday = parseInt(target.text(), 10)||1;\n\t\t\t\t\t\t\tyear = this.viewDate.getUTCFullYear();\n\t\t\t\t\t\t\tmonth = this.viewDate.getUTCMonth();\n\t\t\t\t\t\t\tif (target.hasClass('old')){\n\t\t\t\t\t\t\t\tif (month === 0){\n\t\t\t\t\t\t\t\t\tmonth = 11;\n\t\t\t\t\t\t\t\t\tyear -= 1;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tmonth -= 1;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (target.hasClass('new')){\n\t\t\t\t\t\t\t\tif (month === 11){\n\t\t\t\t\t\t\t\t\tmonth = 0;\n\t\t\t\t\t\t\t\t\tyear += 1;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tmonth += 1;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis._setDate(UTCDate(year, month, day));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this.picker.is(':visible') && this._focused_from){\n\t\t\t\t$(this._focused_from).focus();\n\t\t\t}\n\t\t\tdelete this._focused_from;\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 || 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\tvar element;\n\t\t\tif (this.isInput){\n\t\t\t\telement = this.element;\n\t\t\t}\n\t\t\telse if (this.component){\n\t\t\t\telement = this.element.find('input');\n\t\t\t}\n\t\t\tif (element){\n\t\t\t\telement.change();\n\t\t\t}\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\tmoveMonth: function(date, dir){\n\t\t\tif (!date)\n\t\t\t\treturn undefined;\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\tif (new_month < 0 || new_month > 11)\n\t\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\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 === 27) // allow escape to hide and re-show picker\n\t\t\t\t\tthis.show();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar dateChanged = false,\n\t\t\t\tdir, newDate, 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\tbreak;\n\t\t\t\tcase 37: // left\n\t\t\t\tcase 39: // right\n\t\t\t\t\tif (!this.o.keyboardNavigation)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdir = e.keyCode === 37 ? -1 : 1;\n\t\t\t\t\tif (e.ctrlKey){\n\t\t\t\t\t\tnewDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);\n\t\t\t\t\t\tnewViewDate = this.moveYear(focusDate, dir);\n\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n\t\t\t\t\t}\n\t\t\t\t\telse if (e.shiftKey){\n\t\t\t\t\t\tnewDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);\n\t\t\t\t\t\tnewViewDate = this.moveMonth(focusDate, dir);\n\t\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tnewDate = new Date(this.dates.get(-1) || UTCToday());\n\t\t\t\t\t\tnewDate.setUTCDate(newDate.getUTCDate() + dir);\n\t\t\t\t\t\tnewViewDate = new Date(focusDate);\n\t\t\t\t\t\tnewViewDate.setUTCDate(focusDate.getUTCDate() + dir);\n\t\t\t\t\t}\n\t\t\t\t\tif (this.dateWithinRange(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 38: // up\n\t\t\t\tcase 40: // down\n\t\t\t\t\tif (!this.o.keyboardNavigation)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdir = e.keyCode === 38 ? -1 : 1;\n\t\t\t\t\tif (e.ctrlKey){\n\t\t\t\t\t\tnewDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);\n\t\t\t\t\t\tnewViewDate = this.moveYear(focusDate, dir);\n\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n\t\t\t\t\t}\n\t\t\t\t\telse if (e.shiftKey){\n\t\t\t\t\t\tnewDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);\n\t\t\t\t\t\tnewViewDate = this.moveMonth(focusDate, dir);\n\t\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tnewDate = new Date(this.dates.get(-1) || UTCToday());\n\t\t\t\t\t\tnewDate.setUTCDate(newDate.getUTCDate() + dir * 7);\n\t\t\t\t\t\tnewViewDate = new Date(focusDate);\n\t\t\t\t\t\tnewViewDate.setUTCDate(focusDate.getUTCDate() + dir * 7);\n\t\t\t\t\t}\n\t\t\t\t\tif (this.dateWithinRange(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 32: // spacebar\n\t\t\t\t\t// Spacebar is used in manually typing dates in some formats.\n\t\t\t\t\t// As such, its behavior should not be hijacked.\n\t\t\t\t\tbreak;\n\t\t\t\tcase 13: // enter\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\tif (typeof e.stopPropagation === 'function') {\n\t\t\t\t\t\t\te.stopPropagation(); // All modern browsers, IE9+\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\te.cancelBubble = true; // IE6,7,8 ignore \"stopPropagation\"\n\t\t\t\t\t\t}\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\tvar element;\n\t\t\t\tif (this.isInput){\n\t\t\t\t\telement = this.element;\n\t\t\t\t}\n\t\t\t\telse if (this.component){\n\t\t\t\t\telement = this.element.find('input');\n\t\t\t\t}\n\t\t\t\tif (element){\n\t\t\t\t\telement.change();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tshowMode: function(dir){\n\t\t\tif (dir){\n\t\t\t\tthis.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir));\n\t\t\t}\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.modes[this.viewMode].clsName)\n\t\t\t\t\t.css('display', 'block');\n\t\t\tthis.updateNavArrows();\n\t\t}\n\t};\n\n\tvar DateRangePicker = function(element, options){\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\tdatepickerPlugin.call($(this.inputs), options)\n\t\t\t.bind('changeDate', $.proxy(this.dateUpdated, this));\n\n\t\tthis.pickers = $.map(this.inputs, function(i){\n\t\t\treturn $(i).data('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 = $(e.target).data('datepicker'),\n\t\t\t\tnew_date = dp.getUTCDate(),\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())\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}\n\t\t\telse 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\tremove: function(){\n\t\t\t$.map(this.pickers, function(p){ p.remove(); });\n\t\t\tdelete this.element.data().datepicker;\n\t\t}\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\tvar ropts = {\n\t\t\t\t\t\tinputs: opts.inputs || $this.find('input').toArray()\n\t\t\t\t\t};\n\t\t\t\t\t$this.data('datepicker', (data = new DateRangePicker(this, $.extend(opts, ropts))));\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t$this.data('datepicker', (data = new Datepicker(this, opts)));\n\t\t\t\t}\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\tif (internal_return !== undefined)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\tif (internal_return !== undefined)\n\t\t\treturn internal_return;\n\t\telse\n\t\t\treturn this;\n\t};\n\t$.fn.datepicker = datepickerPlugin;\n\n\tvar defaults = $.fn.datepicker.defaults = {\n\t\tautoclose: false,\n\t\tbeforeShowDay: $.noop,\n\t\tbeforeShowMonth: $.noop,\n\t\tcalendarWeeks: false,\n\t\tclearBtn: false,\n\t\ttoggleActive: false,\n\t\tdaysOfWeekDisabled: [],\n\t\tdatesDisabled: [],\n\t\tendDate: Infinity,\n\t\tforceParse: true,\n\t\tformat: 'mm/dd/yyyy',\n\t\tkeyboardNavigation: true,\n\t\tlanguage: 'en',\n\t\tminViewMode: 0,\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\tweekStart: 0,\n\t\tdisableTouchKeyboard: false,\n        enableOnReadonly: true,\n\t\tcontainer: 'body'\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\", \"Sunday\"],\n\t\t\tdaysShort: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"],\n\t\t\tdaysMin: [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\", \"Su\"],\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}\n\t};\n\n\tvar DPGlobal = {\n\t\tmodes: [\n\t\t\t{\n\t\t\t\tclsName: 'days',\n\t\t\t\tnavFnc: 'Month',\n\t\t\t\tnavStep: 1\n\t\t\t},\n\t\t\t{\n\t\t\t\tclsName: 'months',\n\t\t\t\tnavFnc: 'FullYear',\n\t\t\t\tnavStep: 1\n\t\t\t},\n\t\t\t{\n\t\t\t\tclsName: 'years',\n\t\t\t\tnavFnc: 'FullYear',\n\t\t\t\tnavStep: 10\n\t\t}],\n\t\tisLeapYear: function(year){\n\t\t\treturn (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));\n\t\t},\n\t\tgetDaysInMonth: function(year, month){\n\t\t\treturn [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];\n\t\t},\n\t\tvalidParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,\n\t\tnonpunctuation: /[^ -\\/:-@\\[\\u3400-\\u9fff-`{-~\\t\\n\\r]+/g,\n\t\tparseFormat: function(format){\n\t\t\t// 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){\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\tvar part_re = /([\\-+]\\d+)([dmwy])/,\n\t\t\t\tparts = date.match(/([\\-+]\\d+)([dmwy])/g),\n\t\t\t\tpart, dir, i;\n\t\t\tif (/^[\\-+]\\d+[dmwy]([\\s,]+[\\-+]\\d+[dmwy])*$/.test(date)){\n\t\t\t\tdate = new Date();\n\t\t\t\tfor (i=0; i < parts.length; i++){\n\t\t\t\t\tpart = part_re.exec(parts[i]);\n\t\t\t\t\tdir = parseInt(part[1]);\n\t\t\t\t\tswitch (part[2]){\n\t\t\t\t\t\tcase 'd':\n\t\t\t\t\t\t\tdate.setUTCDate(date.getUTCDate() + dir);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'm':\n\t\t\t\t\t\t\tdate = Datepicker.prototype.moveMonth.call(Datepicker.prototype, date, dir);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'w':\n\t\t\t\t\t\t\tdate.setUTCDate(date.getUTCDate() + dir * 7);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'y':\n\t\t\t\t\t\t\tdate = Datepicker.prototype.moveYear.call(Datepicker.prototype, date, dir);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0);\n\t\t\t}\n\t\t\tparts = date && date.match(this.nonpunctuation) || [];\n\t\t\tdate = new Date();\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(v);\n\t\t\t\t\t},\n\t\t\t\t\tyy: function(d,v){\n\t\t\t\t\t\treturn d.setUTCFullYear(2000+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['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];\n\t\t\tsetters_map['dd'] = setters_map['d'];\n\t\t\tdate = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);\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\tvar 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\t\t\t\t'<tr>'+\n\t\t\t\t\t\t\t\t'<th class=\"prev\">&#171;</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\">&#187;</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'</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.4.1\";\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}(window.jQuery));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/css/bootstrap-select.css",
    "content": ".bootstrap-select {\n  width: 220px \\0;\n  /*IE9 and below*/\n}\n.bootstrap-select > .dropdown-toggle {\n  width: 100%;\n  padding-right: 25px;\n}\n.has-error .bootstrap-select .dropdown-toggle,\n.error .bootstrap-select .dropdown-toggle {\n  border-color: #b94a48;\n}\n.bootstrap-select.fit-width {\n  width: auto !important;\n}\n.bootstrap-select:not([class*=\"col-\"]):not([class*=\"form-control\"]):not(.input-group-btn) {\n  width: 220px;\n}\n.bootstrap-select .dropdown-toggle:focus {\n  outline: thin dotted #333333 !important;\n  outline: 5px auto -webkit-focus-ring-color !important;\n  outline-offset: -2px;\n}\n.bootstrap-select.form-control {\n  margin-bottom: 0;\n  padding: 0;\n  border: none;\n}\n.bootstrap-select.form-control:not([class*=\"col-\"]) {\n  width: 100%;\n}\n.bootstrap-select.form-control.input-group-btn {\n  z-index: auto;\n}\n.bootstrap-select.btn-group:not(.input-group-btn),\n.bootstrap-select.btn-group[class*=\"col-\"] {\n  float: none;\n  display: inline-block;\n  margin-left: 0;\n}\n.bootstrap-select.btn-group.dropdown-menu-right,\n.bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right,\n.row .bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right {\n  float: right;\n}\n.form-inline .bootstrap-select.btn-group,\n.form-horizontal .bootstrap-select.btn-group,\n.form-group .bootstrap-select.btn-group {\n  margin-bottom: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control,\n.form-group-sm .bootstrap-select.btn-group.form-control {\n  padding: 0;\n}\n.form-inline .bootstrap-select.btn-group .form-control {\n  width: 100%;\n}\n.bootstrap-select.btn-group.disabled,\n.bootstrap-select.btn-group > .disabled {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group.disabled:focus,\n.bootstrap-select.btn-group > .disabled:focus {\n  outline: none !important;\n}\n.bootstrap-select.btn-group .dropdown-toggle .filter-option {\n  display: inline-block;\n  overflow: hidden;\n  width: 100%;\n  text-align: left;\n}\n.bootstrap-select.btn-group .dropdown-toggle .caret {\n  position: absolute;\n  top: 50%;\n  right: 12px;\n  margin-top: -2px;\n  vertical-align: middle;\n}\n.bootstrap-select.btn-group[class*=\"col-\"] .dropdown-toggle {\n  width: 100%;\n}\n.bootstrap-select.btn-group .dropdown-menu {\n  min-width: 100%;\n  z-index: 1035;\n  box-sizing: border-box;\n}\n.bootstrap-select.btn-group .dropdown-menu.inner {\n  position: static;\n  float: none;\n  border: 0;\n  padding: 0;\n  margin: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li {\n  position: relative;\n}\n.bootstrap-select.btn-group .dropdown-menu li.active small {\n  color: #fff;\n}\n.bootstrap-select.btn-group .dropdown-menu li.disabled a {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group .dropdown-menu li a {\n  cursor: pointer;\n}\n.bootstrap-select.btn-group .dropdown-menu li a.opt {\n  position: relative;\n  padding-left: 2.25em;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.check-mark {\n  display: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.text {\n  display: inline-block;\n}\n.bootstrap-select.btn-group .dropdown-menu li small {\n  padding-left: 0.5em;\n}\n.bootstrap-select.btn-group .dropdown-menu .notify {\n  position: absolute;\n  bottom: 5px;\n  width: 96%;\n  margin: 0 2%;\n  min-height: 26px;\n  padding: 3px 5px;\n  background: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  pointer-events: none;\n  opacity: 0.9;\n  box-sizing: border-box;\n}\n.bootstrap-select.btn-group .no-results {\n  padding: 3px;\n  background: #f5f5f5;\n  margin: 0 5px;\n  white-space: nowrap;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .filter-option {\n  position: static;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .caret {\n  position: static;\n  top: auto;\n  margin-top: -1px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark {\n  position: absolute;\n  display: inline-block;\n  right: 15px;\n  margin-top: 5px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text {\n  margin-right: 34px;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle {\n  z-index: 1036;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:before {\n  content: '';\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid rgba(204, 204, 204, 0.2);\n  position: absolute;\n  bottom: -4px;\n  left: 9px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:after {\n  content: '';\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid white;\n  position: absolute;\n  bottom: -4px;\n  left: 10px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before {\n  bottom: auto;\n  top: -3px;\n  border-top: 7px solid rgba(204, 204, 204, 0.2);\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after {\n  bottom: auto;\n  top: -3px;\n  border-top: 6px solid white;\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before {\n  right: 12px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after {\n  right: 13px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:before,\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:after {\n  display: block;\n}\n.bs-searchbox,\n.bs-actionsbox,\n.bs-donebutton {\n  padding: 4px 8px;\n}\n.bs-actionsbox {\n  float: left;\n  width: 100%;\n  box-sizing: border-box;\n}\n.bs-actionsbox .btn-group button {\n  width: 50%;\n}\n.bs-donebutton {\n  float: left;\n  width: 100%;\n  box-sizing: border-box;\n}\n.bs-donebutton .btn-group button {\n  width: 100%;\n}\n.bs-searchbox + .bs-actionsbox {\n  padding: 0 8px 4px;\n}\n.bs-searchbox .form-control {\n  margin-bottom: 0;\n  width: 100%;\n}\nselect.bs-select-hidden,\nselect.selectpicker {\n  display: none !important;\n}\nselect.mobile-device {\n  position: absolute !important;\n  top: 0;\n  left: 0;\n  display: block !important;\n  width: 100%;\n  height: 100% !important;\n  opacity: 0;\n}\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/css/variables.css",
    "content": ""
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/css/bootstrap-select.css",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n.bootstrap-select {\n  width: 220px \\0;\n  /*IE9 and below*/\n}\n.bootstrap-select > .dropdown-toggle {\n  width: 100%;\n  padding-right: 25px;\n}\n.has-error .bootstrap-select .dropdown-toggle,\n.error .bootstrap-select .dropdown-toggle {\n  border-color: #b94a48;\n}\n.bootstrap-select.fit-width {\n  width: auto !important;\n}\n.bootstrap-select:not([class*=\"col-\"]):not([class*=\"form-control\"]):not(.input-group-btn) {\n  width: 220px;\n}\n.bootstrap-select .dropdown-toggle:focus {\n  outline: thin dotted #333333 !important;\n  outline: 5px auto -webkit-focus-ring-color !important;\n  outline-offset: -2px;\n}\n.bootstrap-select.form-control {\n  margin-bottom: 0;\n  padding: 0;\n  border: none;\n}\n.bootstrap-select.form-control:not([class*=\"col-\"]) {\n  width: 100%;\n}\n.bootstrap-select.form-control.input-group-btn {\n  z-index: auto;\n}\n.bootstrap-select.btn-group:not(.input-group-btn),\n.bootstrap-select.btn-group[class*=\"col-\"] {\n  float: none;\n  display: inline-block;\n  margin-left: 0;\n}\n.bootstrap-select.btn-group.dropdown-menu-right,\n.bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right,\n.row .bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right {\n  float: right;\n}\n.form-inline .bootstrap-select.btn-group,\n.form-horizontal .bootstrap-select.btn-group,\n.form-group .bootstrap-select.btn-group {\n  margin-bottom: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control,\n.form-group-sm .bootstrap-select.btn-group.form-control {\n  padding: 0;\n}\n.form-inline .bootstrap-select.btn-group .form-control {\n  width: 100%;\n}\n.bootstrap-select.btn-group.disabled,\n.bootstrap-select.btn-group > .disabled {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group.disabled:focus,\n.bootstrap-select.btn-group > .disabled:focus {\n  outline: none !important;\n}\n.bootstrap-select.btn-group .dropdown-toggle .filter-option {\n  display: inline-block;\n  overflow: hidden;\n  width: 100%;\n  text-align: left;\n}\n.bootstrap-select.btn-group .dropdown-toggle .caret {\n  position: absolute;\n  top: 50%;\n  right: 12px;\n  margin-top: -2px;\n  vertical-align: middle;\n}\n.bootstrap-select.btn-group[class*=\"col-\"] .dropdown-toggle {\n  width: 100%;\n}\n.bootstrap-select.btn-group .dropdown-menu {\n  min-width: 100%;\n  z-index: 1035;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .dropdown-menu.inner {\n  position: static;\n  float: none;\n  border: 0;\n  padding: 0;\n  margin: 0;\n  border-radius: 0;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li {\n  position: relative;\n}\n.bootstrap-select.btn-group .dropdown-menu li.active small {\n  color: #fff;\n}\n.bootstrap-select.btn-group .dropdown-menu li.disabled a {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group .dropdown-menu li a {\n  cursor: pointer;\n}\n.bootstrap-select.btn-group .dropdown-menu li a.opt {\n  position: relative;\n  padding-left: 2.25em;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.check-mark {\n  display: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.text {\n  display: inline-block;\n}\n.bootstrap-select.btn-group .dropdown-menu li small {\n  padding-left: 0.5em;\n}\n.bootstrap-select.btn-group .dropdown-menu .notify {\n  position: absolute;\n  bottom: 5px;\n  width: 96%;\n  margin: 0 2%;\n  min-height: 26px;\n  padding: 3px 5px;\n  background: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  pointer-events: none;\n  opacity: 0.9;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .no-results {\n  padding: 3px;\n  background: #f5f5f5;\n  margin: 0 5px;\n  white-space: nowrap;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .filter-option {\n  position: static;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .caret {\n  position: static;\n  top: auto;\n  margin-top: -1px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark {\n  position: absolute;\n  display: inline-block;\n  right: 15px;\n  margin-top: 5px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text {\n  margin-right: 34px;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle {\n  z-index: 1036;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:before {\n  content: '';\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid rgba(204, 204, 204, 0.2);\n  position: absolute;\n  bottom: -4px;\n  left: 9px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:after {\n  content: '';\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid white;\n  position: absolute;\n  bottom: -4px;\n  left: 10px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before {\n  bottom: auto;\n  top: -3px;\n  border-top: 7px solid rgba(204, 204, 204, 0.2);\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after {\n  bottom: auto;\n  top: -3px;\n  border-top: 6px solid white;\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before {\n  right: 12px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after {\n  right: 13px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:before,\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:after {\n  display: block;\n}\n.bs-searchbox,\n.bs-actionsbox,\n.bs-donebutton {\n  padding: 4px 8px;\n}\n.bs-actionsbox {\n  float: left;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-actionsbox .btn-group button {\n  width: 50%;\n}\n.bs-donebutton {\n  float: left;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-donebutton .btn-group button {\n  width: 100%;\n}\n.bs-searchbox + .bs-actionsbox {\n  padding: 0 8px 4px;\n}\n.bs-searchbox .form-control {\n  margin-bottom: 0;\n  width: 100%;\n}\nselect.bs-select-hidden,\nselect.selectpicker {\n  display: none !important;\n}\nselect.mobile-device {\n  position: absolute !important;\n  top: 0;\n  left: 0;\n  display: block !important;\n  width: 100%;\n  height: 100% !important;\n  opacity: 0;\n}\n/*# sourceMappingURL=bootstrap-select.css.map */"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/bootstrap-select.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  'use strict';\n\n  //<editor-fold desc=\"Shims\">\n  if (!String.prototype.includes) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var toString = {}.toString;\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var indexOf = ''.indexOf;\n      var includes = function (search) {\n        if (this == null) {\n          throw TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        return indexOf.call(string, searchString, pos) != -1;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'includes', {\n          'value': includes,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.includes = includes;\n      }\n    }());\n  }\n\n  if (!String.prototype.startsWith) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var toString = {}.toString;\n      var startsWith = function (search) {\n        if (this == null) {\n          throw TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        var index = -1;\n        while (++index < searchLength) {\n          if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {\n            return false;\n          }\n        }\n        return true;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'startsWith', {\n          'value': startsWith,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.startsWith = startsWith;\n      }\n    }());\n  }\n\n  if (!Object.keys) {\n    Object.keys = function (\n      o, // object\n      k, // key\n      r  // result array\n      ){\n      // initialize object and result\n      r=[];\n      // iterate over object keys\n      for (k in o) \n          // fill result array with non-prototypical keys\n        r.hasOwnProperty.call(o, k) && r.push(k);\n      // return result\n      return r\n    };\n  }\n\n  $.fn.triggerNative = function (eventName) {\n    var el = this[0],\n        event;\n\n    if (el.dispatchEvent) {\n      if (typeof Event === 'function') {\n        // For modern browsers\n        event = new Event(eventName, {\n          bubbles: true\n        });\n      } else {\n        // For IE since it doesn't support Event constructor\n        event = document.createEvent('Event');\n        event.initEvent(eventName, true, false);\n      }\n\n      el.dispatchEvent(event);\n    } else {\n      if (el.fireEvent) {\n        event = document.createEventObject();\n        event.eventType = eventName;\n        el.fireEvent('on' + eventName, event);\n      }\n\n      this.trigger(eventName);\n    }\n  };\n  //</editor-fold>\n\n  // Case insensitive contains search\n  $.expr[':'].icontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case insensitive begins search\n  $.expr[':'].ibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive contains search\n  $.expr[':'].aicontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive begins search\n  $.expr[':'].aibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  /**\n   * Remove all diatrics from the given text.\n   * @access private\n   * @param {String} text\n   * @returns {String}\n   */\n  function normalizeToBase(text) {\n    var rExps = [\n      {re: /[\\xC0-\\xC6]/g, ch: \"A\"},\n      {re: /[\\xE0-\\xE6]/g, ch: \"a\"},\n      {re: /[\\xC8-\\xCB]/g, ch: \"E\"},\n      {re: /[\\xE8-\\xEB]/g, ch: \"e\"},\n      {re: /[\\xCC-\\xCF]/g, ch: \"I\"},\n      {re: /[\\xEC-\\xEF]/g, ch: \"i\"},\n      {re: /[\\xD2-\\xD6]/g, ch: \"O\"},\n      {re: /[\\xF2-\\xF6]/g, ch: \"o\"},\n      {re: /[\\xD9-\\xDC]/g, ch: \"U\"},\n      {re: /[\\xF9-\\xFC]/g, ch: \"u\"},\n      {re: /[\\xC7-\\xE7]/g, ch: \"c\"},\n      {re: /[\\xD1]/g, ch: \"N\"},\n      {re: /[\\xF1]/g, ch: \"n\"}\n    ];\n    $.each(rExps, function () {\n      text = text.replace(this.re, this.ch);\n    });\n    return text;\n  }\n\n\n  function htmlEscape(html) {\n    var escapeMap = {\n      '&': '&amp;',\n      '<': '&lt;',\n      '>': '&gt;',\n      '\"': '&quot;',\n      \"'\": '&#x27;',\n      '`': '&#x60;'\n    };\n    var source = '(?:' + Object.keys(escapeMap).join('|') + ')',\n        testRegexp = new RegExp(source),\n        replaceRegexp = new RegExp(source, 'g'),\n        string = html == null ? '' : '' + html;\n    return testRegexp.test(string) ? string.replace(replaceRegexp, function (match) {\n      return escapeMap[match];\n    }) : string;\n  }\n\n  var Selectpicker = function (element, options, e) {\n    if (e) {\n      e.stopPropagation();\n      e.preventDefault();\n    }\n\n    this.$element = $(element);\n    this.$newElement = null;\n    this.$button = null;\n    this.$menu = null;\n    this.$lis = null;\n    this.options = options;\n\n    // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a\n    // data-attribute)\n    if (this.options.title === null) {\n      this.options.title = this.$element.attr('title');\n    }\n\n    //Expose public methods\n    this.val = Selectpicker.prototype.val;\n    this.render = Selectpicker.prototype.render;\n    this.refresh = Selectpicker.prototype.refresh;\n    this.setStyle = Selectpicker.prototype.setStyle;\n    this.selectAll = Selectpicker.prototype.selectAll;\n    this.deselectAll = Selectpicker.prototype.deselectAll;\n    this.destroy = Selectpicker.prototype.remove;\n    this.remove = Selectpicker.prototype.remove;\n    this.show = Selectpicker.prototype.show;\n    this.hide = Selectpicker.prototype.hide;\n\n    this.init();\n  };\n\n  Selectpicker.VERSION = '1.7.2';\n\n  // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.\n  Selectpicker.DEFAULTS = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results matched {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    doneButton: false,\n    doneButtonText: 'Close',\n    multipleSeparator: ', ',\n    styleBase: 'btn',\n    style: 'btn-default',\n    size: 'auto',\n    title: null,\n    selectedTextFormat: 'values',\n    width: false,\n    container: false,\n    hideDisabled: false,\n    showSubtext: false,\n    showIcon: true,\n    showContent: true,\n    dropupAuto: true,\n    header: false,\n    liveSearch: false,\n    liveSearchPlaceholder: null,\n    liveSearchNormalize: false,\n    liveSearchStyle: 'contains',\n    actionsBox: false,\n    iconBase: 'glyphicon',\n    tickIcon: 'glyphicon-ok',\n    maxOptions: false,\n    mobile: false,\n    selectOnTab: false,\n    dropdownAlignRight: false\n  };\n\n  Selectpicker.prototype = {\n\n    constructor: Selectpicker,\n\n    init: function () {\n      var that = this,\n          id = this.$element.attr('id');\n\n      this.$element.addClass('bs-select-hidden');\n      // store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility\n      // allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index=\"' + index + '\"]')\n      this.liObj = {};\n      this.multiple = this.$element.prop('multiple');\n      this.autofocus = this.$element.prop('autofocus');\n      this.$newElement = this.createView();\n      this.$element.after(this.$newElement);\n      this.$button = this.$newElement.children('button');\n      this.$menu = this.$newElement.children('.dropdown-menu');\n      this.$menuInner = this.$menu.children('.inner');\n      this.$searchbox = this.$menu.find('input');\n\n      if (this.options.dropdownAlignRight)\n        this.$menu.addClass('dropdown-menu-right');\n\n      if (typeof id !== 'undefined') {\n        this.$button.attr('data-id', id);\n        $('label[for=\"' + id + '\"]').click(function (e) {\n          e.preventDefault();\n          that.$button.focus();\n        });\n      }\n\n      this.checkDisabled();\n      this.clickListener();\n      if (this.options.liveSearch) this.liveSearchListener();\n      this.render();\n      this.setStyle();\n      this.setWidth();\n      if (this.options.container) this.selectPosition();\n      this.$menu.data('this', this);\n      this.$newElement.data('this', this);\n      if (this.options.mobile) this.mobile();\n\n      this.$newElement.on('hide.bs.dropdown', function (e) {\n        that.$element.trigger('hide.bs.select', e);\n      });\n      \n      this.$newElement.on('hidden.bs.dropdown', function (e) {\n        that.$element.trigger('hidden.bs.select', e);\n      });\n      \n      this.$newElement.on('show.bs.dropdown', function (e) {\n        that.$element.trigger('show.bs.select', e);\n      });\n      \n      this.$newElement.on('shown.bs.dropdown', function (e) {\n        that.$element.trigger('shown.bs.select', e);\n      });\n\n      setTimeout(function () {\n        that.$element.trigger('loaded.bs.select');\n      });\n    },\n\n    createDropdown: function () {\n      // Options\n      // If we are multiple, then add the show-tick class by default\n      var multiple = this.multiple ? ' show-tick' : '',\n          inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',\n          autofocus = this.autofocus ? ' autofocus' : '';\n      // Elements\n      var header = this.options.header ? '<div class=\"popover-title\"><button type=\"button\" class=\"close\" aria-hidden=\"true\">&times;</button>' + this.options.header + '</div>' : '';\n      var searchbox = this.options.liveSearch ?\n      '<div class=\"bs-searchbox\">' +\n      '<input type=\"text\" class=\"form-control\" autocomplete=\"off\"' +\n      (null === this.options.liveSearchPlaceholder ? '' : ' placeholder=\"' + htmlEscape(this.options.liveSearchPlaceholder) + '\"') + '>' +\n      '</div>'\n          : '';\n      var actionsbox = this.multiple && this.options.actionsBox ?\n      '<div class=\"bs-actionsbox\">' +\n      '<div class=\"btn-group btn-group-sm btn-block\">' +\n      '<button type=\"button\" class=\"actions-btn bs-select-all btn btn-default\">' +\n      this.options.selectAllText +\n      '</button>' +\n      '<button type=\"button\" class=\"actions-btn bs-deselect-all btn btn-default\">' +\n      this.options.deselectAllText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var donebutton = this.multiple && this.options.doneButton ?\n      '<div class=\"bs-donebutton\">' +\n      '<div class=\"btn-group btn-block\">' +\n      '<button type=\"button\" class=\"btn btn-sm btn-default\">' +\n      this.options.doneButtonText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var drop =\n          '<div class=\"btn-group bootstrap-select' + multiple + inputGroup + '\">' +\n          '<button type=\"button\" class=\"' + this.options.styleBase + ' dropdown-toggle\" data-toggle=\"dropdown\"' + autofocus + '>' +\n          '<span class=\"filter-option pull-left\"></span>&nbsp;' +\n          '<span class=\"caret\"></span>' +\n          '</button>' +\n          '<div class=\"dropdown-menu open\">' +\n          header +\n          searchbox +\n          actionsbox +\n          '<ul class=\"dropdown-menu inner\" role=\"menu\">' +\n          '</ul>' +\n          donebutton +\n          '</div>' +\n          '</div>';\n\n      return $(drop);\n    },\n\n    createView: function () {\n      var $drop = this.createDropdown(),\n          li = this.createLi();\n\n      $drop.find('ul')[0].innerHTML = li;\n      return $drop;\n    },\n\n    reloadLi: function () {\n      //Remove all children.\n      this.destroyLi();\n      //Re build\n      var li = this.createLi();\n      this.$menuInner[0].innerHTML = li;\n    },\n\n    destroyLi: function () {\n      this.$menu.find('li').remove();\n    },\n\n    createLi: function () {\n      var that = this,\n          _li = [],\n          optID = 0,\n          titleOption = document.createElement('option'),\n          liIndex = -1; // increment liIndex whenever a new <li> element is created to ensure liObj is correct\n\n      // Helper functions\n      /**\n       * @param content\n       * @param [index]\n       * @param [classes]\n       * @param [optgroup]\n       * @returns {string}\n       */\n      var generateLI = function (content, index, classes, optgroup) {\n        return '<li' +\n            ((typeof classes !== 'undefined' & '' !== classes) ? ' class=\"' + classes + '\"' : '') +\n            ((typeof index !== 'undefined' & null !== index) ? ' data-original-index=\"' + index + '\"' : '') +\n            ((typeof optgroup !== 'undefined' & null !== optgroup) ? 'data-optgroup=\"' + optgroup + '\"' : '') +\n            '>' + content + '</li>';\n      };\n\n      /**\n       * @param text\n       * @param [classes]\n       * @param [inline]\n       * @param [tokens]\n       * @returns {string}\n       */\n      var generateA = function (text, classes, inline, tokens) {\n        return '<a tabindex=\"0\"' +\n            (typeof classes !== 'undefined' ? ' class=\"' + classes + '\"' : '') +\n            (typeof inline !== 'undefined' ? ' style=\"' + inline + '\"' : '') +\n            (that.options.liveSearchNormalize ? ' data-normalized-text=\"' + normalizeToBase(htmlEscape(text)) + '\"' : '') +\n            (typeof tokens !== 'undefined' || tokens !== null ? ' data-tokens=\"' + tokens + '\"' : '') +\n            '>' + text +\n            '<span class=\"' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark\"></span>' +\n            '</a>';\n      };\n\n      if (this.options.title && !this.multiple) {\n        // this option doesn't create a new <li> element, but does add a new option, so liIndex is decreased\n        // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended\n        liIndex--;\n\n        if (!this.$element.find('.bs-title-option').length) {\n          // Use native JS to prepend option (faster)\n          var element = this.$element[0];\n          titleOption.className = 'bs-title-option';\n          titleOption.appendChild(document.createTextNode(this.options.title));\n          titleOption.value = '';\n          element.insertBefore(titleOption, element.firstChild);\n          // Check if selected attribute is already set on an option. If not, select the titleOption option.\n          if ($(element.options[element.selectedIndex]).attr('selected') === undefined) titleOption.selected = true;\n        }\n      }\n\n      this.$element.find('option').each(function (index) {\n        var $this = $(this);\n\n        liIndex++;\n\n        if ($this.hasClass('bs-title-option')) return;\n\n        // Get the class and text for the option\n        var optionClass = this.className || '',\n            inline = this.style.cssText,\n            text = $this.data('content') ? $this.data('content') : $this.html(),\n            tokens = $this.data('tokens') ? $this.data('tokens') : null,\n            subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $this.data('subtext') + '</small>' : '',\n            icon = typeof $this.data('icon') !== 'undefined' ? '<span class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></span> ' : '',\n            isDisabled = this.disabled || (this.parentElement.tagName === 'OPTGROUP' && this.parentElement.disabled);\n\n        if (icon !== '' && isDisabled) {\n          icon = '<span>' + icon + '</span>';\n        }\n\n        if (that.options.hideDisabled && isDisabled) {\n          liIndex--;\n          return;\n        }\n\n        if (!$this.data('content')) {\n          // Prepend any icon and append any subtext to the main text.\n          text = icon + '<span class=\"text\">' + text + subtext + '</span>';\n        }\n\n        if (this.parentElement.tagName === 'OPTGROUP' && $this.data('divider') !== true) {\n          var optGroupClass = ' ' + this.parentElement.className || '';\n\n          if ($this.index() === 0) { // Is it the first option of the optgroup?\n            optID += 1;\n\n            // Get the opt group label\n            var label = this.parentElement.label,\n                labelSubtext = typeof $this.parent().data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $this.parent().data('subtext') + '</small>' : '',\n                labelIcon = $this.parent().data('icon') ? '<span class=\"' + that.options.iconBase + ' ' + $this.parent().data('icon') + '\"></span> ' : '';\n            \n            label = labelIcon + '<span class=\"text\">' + label + labelSubtext + '</span>';\n\n            if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?\n              liIndex++;\n              _li.push(generateLI('', null, 'divider', optID + 'div'));\n            }\n            liIndex++;\n            _li.push(generateLI(label, null, 'dropdown-header' + optGroupClass, optID));\n          }\n          _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID));\n        } else if ($this.data('divider') === true) {\n          _li.push(generateLI('', index, 'divider'));\n        } else if ($this.data('hidden') === true) {\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden'));\n        } else {\n          if (this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP') {\n            liIndex++;\n            _li.push(generateLI('', null, 'divider', optID + 'div'));\n          }\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index));\n        }\n\n        that.liObj[index] = liIndex;\n      });\n\n      //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button\n      if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {\n        this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');\n      }\n\n      return _li.join('');\n    },\n\n    findLis: function () {\n      if (this.$lis == null) this.$lis = this.$menu.find('li');\n      return this.$lis;\n    },\n\n    /**\n     * @param [updateLi] defaults to true\n     */\n    render: function (updateLi) {\n      var that = this,\n          notDisabled;\n\n      //Update the LI to match the SELECT\n      if (updateLi !== false) {\n        this.$element.find('option').each(function (index) {\n          var $lis = that.findLis().eq(that.liObj[index]);\n\n          that.setDisabled(index, this.disabled || this.parentElement.tagName === 'OPTGROUP' && this.parentElement.disabled, $lis);\n          that.setSelected(index, this.selected, $lis);\n        });\n      }\n\n      this.tabIndex();\n\n      var selectedItems = this.$element.find('option').map(function () {\n        if (this.selected) {\n          if (that.options.hideDisabled && (this.disabled || this.parentElement.tagName === 'OPTGROUP' && this.parentElement.disabled)) return false;\n\n          var $this = $(this),\n              icon = $this.data('icon') && that.options.showIcon ? '<i class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></i> ' : '',\n              subtext;\n\n          if (that.options.showSubtext && $this.data('subtext') && !that.multiple) {\n            subtext = ' <small class=\"text-muted\">' + $this.data('subtext') + '</small>';\n          } else {\n            subtext = '';\n          }\n          if (typeof $this.attr('title') !== 'undefined') {\n            return $this.attr('title');\n          } else if ($this.data('content') && that.options.showContent) {\n            return $this.data('content');\n          } else {\n            return icon + $this.html() + subtext;\n          }\n        }\n      }).toArray();\n\n      //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled\n      //Convert all the values into a comma delimited string\n      var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);\n\n      //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..\n      if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {\n        var max = this.options.selectedTextFormat.split('>');\n        if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {\n          notDisabled = this.options.hideDisabled ? ', [disabled]' : '';\n          var totalCount = this.$element.find('option').not('[data-divider=\"true\"], [data-hidden=\"true\"]' + notDisabled).length,\n              tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;\n          title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());\n        }\n      }\n\n      if (this.options.title == undefined) {\n        this.options.title = this.$element.attr('title');\n      }\n\n      if (this.options.selectedTextFormat == 'static') {\n        title = this.options.title;\n      }\n\n      //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text\n      if (!title) {\n        title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;\n      }\n\n      //strip all html-tags and trim the result\n      this.$button.attr('title', $.trim(title.replace(/<[^>]*>?/g, '')));\n      this.$button.children('.filter-option').html(title);\n\n      this.$element.trigger('rendered.bs.select');\n    },\n\n    /**\n     * @param [style]\n     * @param [status]\n     */\n    setStyle: function (style, status) {\n      if (this.$element.attr('class')) {\n        this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\\[.*\\]/gi, ''));\n      }\n\n      var buttonClass = style ? style : this.options.style;\n\n      if (status == 'add') {\n        this.$button.addClass(buttonClass);\n      } else if (status == 'remove') {\n        this.$button.removeClass(buttonClass);\n      } else {\n        this.$button.removeClass(this.options.style);\n        this.$button.addClass(buttonClass);\n      }\n    },\n\n    liHeight: function (refresh) {\n      if (!refresh && (this.options.size === false || this.sizeInfo)) return;\n\n      var newElement = document.createElement('div'),\n          menu = document.createElement('div'),\n          menuInner = document.createElement('ul'),\n          divider = document.createElement('li'),\n          li = document.createElement('li'),\n          a = document.createElement('a'),\n          text = document.createElement('span'),\n          header = this.options.header ? this.$menu.find('.popover-title')[0].cloneNode(true) : null,\n          search = this.options.liveSearch ? document.createElement('div') : null,\n          actions = this.options.actionsBox && this.multiple ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null,\n          doneButton = this.options.doneButton && this.multiple ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null;\n\n      text.className = 'text';\n      newElement.className = this.$menu[0].parentNode.className + ' open';\n      menu.className = 'dropdown-menu open';\n      menuInner.className = 'dropdown-menu inner';\n      divider.className = 'divider';\n\n      text.appendChild(document.createTextNode('Inner text'));\n      a.appendChild(text);\n      li.appendChild(a);\n      menuInner.appendChild(li);\n      menuInner.appendChild(divider);\n      if (header) menu.appendChild(header);\n      if (search) {\n        // create a span instead of input as creating an input element is slower\n        var input = document.createElement('span');\n        search.className = 'bs-searchbox';\n        input.className = 'form-control';\n        search.appendChild(input);\n        menu.appendChild(search);\n      }\n      if (actions) menu.appendChild(actions);\n      menu.appendChild(menuInner);\n      if (doneButton) menu.appendChild(doneButton);\n      newElement.appendChild(menu);\n\n      document.body.appendChild(newElement);\n\n      var liHeight = a.offsetHeight,\n          headerHeight = header ? header.offsetHeight : 0,\n          searchHeight = search ? search.offsetHeight : 0,\n          actionsHeight = actions ? actions.offsetHeight : 0,\n          doneButtonHeight = doneButton ? doneButton.offsetHeight : 0,\n          dividerHeight = $(divider).outerHeight(true),\n          // fall back to jQuery if getComputedStyle is not supported\n          menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,\n          $menu = menuStyle ? null : $(menu),\n          menuPadding = parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +\n                        parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +\n                        parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +\n                        parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),\n          menuExtras =  menuPadding + \n                        parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) + \n                        parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2;\n\n      document.body.removeChild(newElement);\n\n      this.sizeInfo = {\n        liHeight: liHeight,\n        headerHeight: headerHeight,\n        searchHeight: searchHeight,\n        actionsHeight: actionsHeight,\n        doneButtonHeight: doneButtonHeight,\n        dividerHeight: dividerHeight,\n        menuPadding: menuPadding,\n        menuExtras: menuExtras\n      };\n    },\n\n    setSize: function () {\n      this.findLis();\n      this.liHeight();\n\n      if (this.options.header) this.$menu.css('padding-top', 0);\n      if (this.options.size === false) return;\n\n      var that = this,\n          $menu = this.$menu,\n          $menuInner = this.$menuInner,\n          $window = $(window),\n          selectHeight = this.$newElement[0].offsetHeight,\n          liHeight = this.sizeInfo['liHeight'],\n          headerHeight = this.sizeInfo['headerHeight'],\n          searchHeight = this.sizeInfo['searchHeight'],\n          actionsHeight = this.sizeInfo['actionsHeight'],\n          doneButtonHeight = this.sizeInfo['doneButtonHeight'],\n          divHeight = this.sizeInfo['dividerHeight'],\n          menuPadding = this.sizeInfo['menuPadding'],\n          menuExtras = this.sizeInfo['menuExtras'],\n          notDisabled = this.options.hideDisabled ? '.disabled' : '',\n          menuHeight,\n          getHeight,\n          selectOffsetTop,\n          selectOffsetBot,\n          posVert = function () {\n            selectOffsetTop = that.$newElement.offset().top - $window.scrollTop();\n            selectOffsetBot = $window.height() - selectOffsetTop - selectHeight;\n          };\n\n      posVert();\n\n      if (this.options.size === 'auto') {\n        var getSize = function () {\n          var minHeight,\n              hasClass = function (className, include) {\n                return function (element) {\n                    if (include) {\n                        return (element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    } else {\n                        return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    }\n                };\n              },\n              lis = that.$menuInner[0].getElementsByTagName('li'),\n              lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),\n              optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');\n\n          posVert();\n          menuHeight = selectOffsetBot - menuExtras;\n\n          if (that.options.container) {\n            if (!$menu.data('height')) $menu.data('height', $menu.height());\n            getHeight = $menu.data('height');\n          } else {\n            getHeight = $menu.height();\n          }\n\n          if (that.options.dropupAuto) {\n            that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras) < getHeight);\n          }\n          if (that.$newElement.hasClass('dropup')) {\n            menuHeight = selectOffsetTop - menuExtras;\n          }\n\n          if ((lisVisible.length + optGroup.length) > 3) {\n            minHeight = liHeight * 3 + menuExtras - 2;\n          } else {\n            minHeight = 0;\n          }\n\n          $menu.css({\n            'max-height': menuHeight + 'px',\n            'overflow': 'hidden',\n            'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'\n          });\n          $menuInner.css({\n            'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding + 'px',\n            'overflow-y': 'auto',\n            'min-height': Math.max(minHeight - menuPadding, 0) + 'px'\n          });\n        };\n        getSize();\n        this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);\n        $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize);\n      } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {\n        var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),\n            divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;\n        menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding;\n\n        if (that.options.container) {\n          if (!$menu.data('height')) $menu.data('height', $menu.height());\n          getHeight = $menu.data('height');\n        } else {\n          getHeight = $menu.height();\n        }\n\n        if (that.options.dropupAuto) {\n          //noinspection JSUnusedAssignment\n          this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras) < getHeight);\n        }\n        $menu.css({\n          'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',\n          'overflow': 'hidden',\n          'min-height': ''\n        });\n        $menuInner.css({\n          'max-height': menuHeight - menuPadding + 'px',\n          'overflow-y': 'auto',\n          'min-height': ''\n        });\n      }\n    },\n\n    setWidth: function () {\n      if (this.options.width === 'auto') {\n        this.$menu.css('min-width', '0');\n\n        // Get correct width if element is hidden\n        var $selectClone = this.$menu.parent().clone().appendTo('body'),\n            $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone,\n            ulWidth = $selectClone.children('.dropdown-menu').outerWidth(),\n            btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth();\n\n        $selectClone.remove();\n        $selectClone2.remove();\n\n        // Set width to whatever's larger, button title or longest option\n        this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px');\n      } else if (this.options.width === 'fit') {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '').addClass('fit-width');\n      } else if (this.options.width) {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', this.options.width);\n      } else {\n        // Remove inline min-width/width so width can be changed\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '');\n      }\n      // Remove fit-width class if width is changed programmatically\n      if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {\n        this.$newElement.removeClass('fit-width');\n      }\n    },\n\n    selectPosition: function () {\n      var that = this,\n          drop = '<div />',\n          $drop = $(drop),\n          pos,\n          actualHeight,\n          getPlacement = function ($element) {\n            $drop.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));\n            pos = $element.offset();\n            actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;\n            $drop.css({\n              'top': pos.top + actualHeight,\n              'left': pos.left,\n              'width': $element[0].offsetWidth,\n              'position': 'absolute'\n            });\n          };\n\n      this.$newElement.on('click', function () {\n        if (that.isDisabled()) {\n          return;\n        }\n        getPlacement($(this));\n        $drop.appendTo(that.options.container);\n        $drop.toggleClass('open', !$(this).hasClass('open'));\n        $drop.append(that.$menu);\n      });\n\n      $(window).on('resize scroll', function () {\n        getPlacement(that.$newElement);\n      });\n\n      this.$element.on('hide.bs.select', function () {\n        that.$menu.data('height', that.$menu.height());\n        $drop.detach();\n      });\n    },\n\n    setSelected: function (index, selected, $lis) {\n      if (!$lis) {\n        var $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      $lis.toggleClass('selected', selected);\n    },\n\n    setDisabled: function (index, disabled, $lis) {\n      if (!$lis) {\n        var $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      if (disabled) {\n        $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1);\n      } else {\n        $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0);\n      }\n    },\n\n    isDisabled: function () {\n      return this.$element[0].disabled;\n    },\n\n    checkDisabled: function () {\n      var that = this;\n\n      if (this.isDisabled()) {\n        this.$newElement.addClass('disabled');\n        this.$button.addClass('disabled').attr('tabindex', -1);\n      } else {\n        if (this.$button.hasClass('disabled')) {\n          this.$newElement.removeClass('disabled');\n          this.$button.removeClass('disabled');\n        }\n\n        if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) {\n          this.$button.removeAttr('tabindex');\n        }\n      }\n\n      this.$button.click(function () {\n        return !that.isDisabled();\n      });\n    },\n\n    tabIndex: function () {\n      if (this.$element.is('[tabindex]')) {\n        this.$element.data('tabindex', this.$element.attr('tabindex'));\n        this.$button.attr('tabindex', this.$element.data('tabindex'));\n      }\n    },\n\n    clickListener: function () {\n      var that = this,\n          $document = $(document);\n\n      this.$newElement.on('touchstart.dropdown', '.dropdown-menu', function (e) {\n        e.stopPropagation();\n      });\n\n      $document.data('spaceSelect', false);\n      \n      this.$button.on('keyup', function (e) {\n        if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {\n            e.preventDefault();\n            $document.data('spaceSelect', false);\n        }\n      });\n\n      this.$newElement.on('click', function () {\n        that.setSize();\n        that.$element.on('shown.bs.select', function () {\n          if (!that.options.liveSearch && !that.multiple) {\n            that.$menu.find('.selected a').focus();\n          } else if (!that.multiple) {\n            var selectedIndex = that.liObj[that.$element[0].selectedIndex];\n\n            if (typeof selectedIndex !== 'number' || that.options.size === false) return;\n            \n            // scroll to selected option\n            var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop;\n            offset = offset - that.$menuInner[0].offsetHeight/2 + that.sizeInfo.liHeight/2;\n            that.$menuInner[0].scrollTop = offset;\n          }\n        });\n      });\n\n      this.$menu.on('click', 'li a', function (e) {\n        var $this = $(this),\n            clickedIndex = $this.parent().data('originalIndex'),\n            prevValue = that.$element.val(),\n            prevIndex = that.$element.prop('selectedIndex');\n\n        // Don't close on multi choice menu\n        if (that.multiple) {\n          e.stopPropagation();\n        }\n\n        e.preventDefault();\n\n        //Don't run if we have been disabled\n        if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {\n          var $options = that.$element.find('option'),\n              $option = $options.eq(clickedIndex),\n              state = $option.prop('selected'),\n              $optgroup = $option.parent('optgroup'),\n              maxOptions = that.options.maxOptions,\n              maxOptionsGrp = $optgroup.data('maxOptions') || false;\n\n          if (!that.multiple) { // Deselect all others if not multi select box\n            $options.prop('selected', false);\n            $option.prop('selected', true);\n            that.$menu.find('.selected').removeClass('selected');\n            that.setSelected(clickedIndex, true);\n          } else { // Toggle the one we have chosen if we are multi select.\n            $option.prop('selected', !state);\n            that.setSelected(clickedIndex, !state);\n            $this.blur();\n\n            if (maxOptions !== false || maxOptionsGrp !== false) {\n              var maxReached = maxOptions < $options.filter(':selected').length,\n                  maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;\n\n              if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {\n                if (maxOptions && maxOptions == 1) {\n                  $options.prop('selected', false);\n                  $option.prop('selected', true);\n                  that.$menu.find('.selected').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else if (maxOptionsGrp && maxOptionsGrp == 1) {\n                  $optgroup.find('option:selected').prop('selected', false);\n                  $option.prop('selected', true);\n                  var optgroupID = $this.parent().data('optgroup');\n                  that.$menu.find('[data-optgroup=\"' + optgroupID + '\"]').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else {\n                  var maxOptionsArr = (typeof that.options.maxOptionsText === 'function') ?\n                          that.options.maxOptionsText(maxOptions, maxOptionsGrp) : that.options.maxOptionsText,\n                      maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),\n                      maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),\n                      $notify = $('<div class=\"notify\"></div>');\n                  // If {var} is set in array, replace it\n                  /** @deprecated */\n                  if (maxOptionsArr[2]) {\n                    maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);\n                    maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);\n                  }\n\n                  $option.prop('selected', false);\n\n                  that.$menu.append($notify);\n\n                  if (maxOptions && maxReached) {\n                    $notify.append($('<div>' + maxTxt + '</div>'));\n                    that.$element.trigger('maxReached.bs.select');\n                  }\n\n                  if (maxOptionsGrp && maxReachedGrp) {\n                    $notify.append($('<div>' + maxTxtGrp + '</div>'));\n                    that.$element.trigger('maxReachedGrp.bs.select');\n                  }\n\n                  setTimeout(function () {\n                    that.setSelected(clickedIndex, false);\n                  }, 10);\n\n                  $notify.delay(750).fadeOut(300, function () {\n                    $(this).remove();\n                  });\n                }\n              }\n            }\n          }\n\n          if (!that.multiple) {\n            that.$button.focus();\n          } else if (that.options.liveSearch) {\n            that.$searchbox.focus();\n          }\n\n          // Trigger select 'change'\n          if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {\n            that.$element.triggerNative('change');\n            // $option.prop('selected') is current option state (selected/unselected). state is previous option state.\n            that.$element.trigger('changed.bs.select', [clickedIndex, $option.prop('selected'), state]);\n          }\n        }\n      });\n\n      this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {\n        if (e.currentTarget == this) {\n          e.preventDefault();\n          e.stopPropagation();\n          if (that.options.liveSearch && !$(e.target).hasClass('close')) {\n            that.$searchbox.focus();\n          } else {\n            that.$button.focus();\n          }\n        }\n      });\n\n      this.$menu.on('click', 'li.divider, li.dropdown-header', function (e) {\n        e.preventDefault();\n        e.stopPropagation();\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n      });\n\n      this.$menu.on('click', '.popover-title .close', function () {\n        that.$button.click();\n      });\n\n      this.$searchbox.on('click', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$menu.on('click', '.actions-btn', function (e) {\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n\n        e.preventDefault();\n        e.stopPropagation();\n\n        if ($(this).hasClass('bs-select-all')) {\n          that.selectAll();\n        } else {\n          that.deselectAll();\n        }\n        that.$element.triggerNative('change');\n      });\n\n      this.$element.change(function () {\n        that.render(false);\n      });\n    },\n\n    liveSearchListener: function () {\n      var that = this,\n          $no_results = $('<li class=\"no-results\"></li>');\n\n      this.$newElement.on('click.dropdown.data-api touchstart.dropdown.data-api', function () {\n        that.$menuInner.find('.active').removeClass('active');\n        if (!!that.$searchbox.val()) {\n          that.$searchbox.val('');\n          that.$lis.not('.is-hidden').removeClass('hidden');\n          if (!!$no_results.parent().length) $no_results.remove();\n        }\n        if (!that.multiple) that.$menuInner.find('.selected').addClass('active');\n        setTimeout(function () {\n          that.$searchbox.focus();\n        }, 10);\n      });\n\n      this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$searchbox.on('input propertychange', function () {\n        if (that.$searchbox.val()) {\n          var $searchBase = that.$lis.not('.is-hidden').removeClass('hidden').children('a');\n          if (that.options.liveSearchNormalize) {\n            $searchBase = $searchBase.not(':a' + that._searchStyle() + '(\"' + normalizeToBase(that.$searchbox.val()) + '\")');\n          } else {\n            $searchBase = $searchBase.not(':' + that._searchStyle() + '(\"' + that.$searchbox.val() + '\")');\n          }\n          $searchBase.parent().addClass('hidden');\n\n          that.$lis.filter('.dropdown-header').each(function () {\n            var $this = $(this),\n                optgroup = $this.data('optgroup');\n\n            if (that.$lis.filter('[data-optgroup=' + optgroup + ']').not($this).not('.hidden').length === 0) {\n              $this.addClass('hidden');\n              that.$lis.filter('[data-optgroup=' + optgroup + 'div]').addClass('hidden');\n            }\n          });\n\n          var $lisVisible = that.$lis.not('.hidden');\n\n          // hide divider if first or last visible, or if followed by another divider\n          $lisVisible.each(function (index) {\n            var $this = $(this);\n\n            if ($this.hasClass('divider') && (\n              $this.index() === $lisVisible.eq(0).index() ||\n              $this.index() === $lisVisible.last().index() ||\n              $lisVisible.eq(index + 1).hasClass('divider'))) {\n              $this.addClass('hidden');\n            }\n          });\n\n          if (!that.$lis.not('.hidden, .no-results').length) {\n            if (!!$no_results.parent().length) {\n              $no_results.remove();\n            }\n            $no_results.html(that.options.noneResultsText.replace('{0}', '\"' + htmlEscape(that.$searchbox.val()) + '\"')).show();\n            that.$menuInner.append($no_results);\n          } else if (!!$no_results.parent().length) {\n            $no_results.remove();\n          }\n\n        } else {\n          that.$lis.not('.is-hidden').removeClass('hidden');\n          if (!!$no_results.parent().length) {\n            $no_results.remove();\n          }\n        }\n\n        that.$lis.filter('.active').removeClass('active');\n        if (that.$searchbox.val()) that.$lis.not('.hidden, .divider, .dropdown-header').eq(0).addClass('active').children('a').focus();\n        $(this).focus();\n      });\n    },\n\n    _searchStyle: function () {\n      var style = 'icontains';\n      switch (this.options.liveSearchStyle) {\n        case 'begins':\n        case 'startsWith':\n          style = 'ibegins';\n          break;\n        case 'contains':\n        default:\n          break; //no need to change the default\n      }\n\n      return style;\n    },\n\n    val: function (value) {\n      if (typeof value !== 'undefined') {\n        this.$element.val(value);\n        this.render();\n\n        return this.$element;\n      } else {\n        return this.$element.val();\n      }\n    },\n\n    selectAll: function () {\n      this.findLis();\n      this.$element.find('option:enabled').not('[data-divider], [data-hidden]').prop('selected', true);\n      this.$lis.not('.divider, .dropdown-header, .disabled, .hidden').addClass('selected');\n      this.render(false);\n    },\n\n    deselectAll: function () {\n      this.findLis();\n      this.$element.find('option:enabled').not('[data-divider], [data-hidden]').prop('selected', false);\n      this.$lis.not('.divider, .dropdown-header, .disabled, .hidden').removeClass('selected');\n      this.render(false);\n    },\n\n    keydown: function (e) {\n      var $this = $(this),\n          $parent = $this.is('input') ? $this.parent().parent() : $this.parent(),\n          $items,\n          that = $parent.data('this'),\n          index,\n          next,\n          first,\n          last,\n          prev,\n          nextPrev,\n          prevIndex,\n          isActive,\n          selector = ':not(.disabled, .hidden, .dropdown-header, .divider)',\n          keyCodeMap = {\n            32: ' ',\n            48: '0',\n            49: '1',\n            50: '2',\n            51: '3',\n            52: '4',\n            53: '5',\n            54: '6',\n            55: '7',\n            56: '8',\n            57: '9',\n            59: ';',\n            65: 'a',\n            66: 'b',\n            67: 'c',\n            68: 'd',\n            69: 'e',\n            70: 'f',\n            71: 'g',\n            72: 'h',\n            73: 'i',\n            74: 'j',\n            75: 'k',\n            76: 'l',\n            77: 'm',\n            78: 'n',\n            79: 'o',\n            80: 'p',\n            81: 'q',\n            82: 'r',\n            83: 's',\n            84: 't',\n            85: 'u',\n            86: 'v',\n            87: 'w',\n            88: 'x',\n            89: 'y',\n            90: 'z',\n            96: '0',\n            97: '1',\n            98: '2',\n            99: '3',\n            100: '4',\n            101: '5',\n            102: '6',\n            103: '7',\n            104: '8',\n            105: '9'\n          };\n\n      if (that.options.liveSearch) $parent = $this.parent().parent();\n\n      if (that.options.container) $parent = that.$menu;\n\n      $items = $('[role=menu] li a', $parent);\n\n      isActive = that.$menu.parent().hasClass('open');\n\n      if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 65 && e.keyCode <= 90)) {\n        if (!that.options.container) {\n          that.setSize();\n          that.$menu.parent().addClass('open');\n          isActive = true;\n        } else {\n          that.$newElement.trigger('click');\n        }\n        that.$searchbox.focus();\n      }\n\n      if (that.options.liveSearch) {\n        if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && that.$menu.find('.active').length === 0) {\n          e.preventDefault();\n          that.$menu.parent().removeClass('open');\n          if (that.options.container) that.$newElement.removeClass('open');\n          that.$button.focus();\n        }\n        // $items contains li elements when liveSearch is enabled\n        $items = $('[role=menu] li:not(.disabled, .hidden, .dropdown-header, .divider)', $parent);\n        if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) {\n          if ($items.filter('.active').length === 0) {\n            $items = that.$newElement.find('li');\n            if (that.options.liveSearchNormalize) {\n              $items = $items.filter(':a' + that._searchStyle() + '(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');\n            } else {\n              $items = $items.filter(':' + that._searchStyle() + '(' + keyCodeMap[e.keyCode] + ')');\n            }\n          }\n        }\n      }\n\n      if (!$items.length) return;\n\n      if (/(38|40)/.test(e.keyCode.toString(10))) {\n        index = $items.index($items.filter(':focus'));\n        first = $items.parent(selector).first().data('originalIndex');\n        last = $items.parent(selector).last().data('originalIndex');\n        next = $items.eq(index).parent().nextAll(selector).eq(0).data('originalIndex');\n        prev = $items.eq(index).parent().prevAll(selector).eq(0).data('originalIndex');\n        nextPrev = $items.eq(next).parent().prevAll(selector).eq(0).data('originalIndex');\n\n        if (that.options.liveSearch) {\n          $items.each(function (i) {\n            if (!$(this).hasClass('disabled')) {\n              $(this).data('index', i);\n            }\n          });\n          index = $items.index($items.filter('.active'));\n          first = $items.first().data('index');\n          last = $items.last().data('index');\n          next = $items.eq(index).nextAll().eq(0).data('index');\n          prev = $items.eq(index).prevAll().eq(0).data('index');\n          nextPrev = $items.eq(next).prevAll().eq(0).data('index');\n        }\n\n        prevIndex = $this.data('prevIndex');\n\n        if (e.keyCode == 38) {\n          if (that.options.liveSearch) index -= 1;\n          if (index != nextPrev && index > prev) index = prev;\n          if (index < first) index = first;\n          if (index == prevIndex) index = last;\n        } else if (e.keyCode == 40) {\n          if (that.options.liveSearch) index += 1;\n          if (index == -1) index = 0;\n          if (index != nextPrev && index < next) index = next;\n          if (index > last) index = last;\n          if (index == prevIndex) index = first;\n        }\n\n        $this.data('prevIndex', index);\n\n        if (!that.options.liveSearch) {\n          $items.eq(index).focus();\n        } else {\n          e.preventDefault();\n          if (!$this.hasClass('dropdown-toggle')) {\n            $items.removeClass('active').eq(index).addClass('active').children('a').focus();\n            $this.focus();\n          }\n        }\n\n      } else if (!$this.is('input')) {\n        var keyIndex = [],\n            count,\n            prevKey;\n\n        $items.each(function () {\n          if (!$(this).parent().hasClass('disabled')) {\n            if ($.trim($(this).text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {\n              keyIndex.push($(this).parent().index());\n            }\n          }\n        });\n\n        count = $(document).data('keycount');\n        count++;\n        $(document).data('keycount', count);\n\n        prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);\n\n        if (prevKey != keyCodeMap[e.keyCode]) {\n          count = 1;\n          $(document).data('keycount', count);\n        } else if (count >= keyIndex.length) {\n          $(document).data('keycount', 0);\n          if (count > keyIndex.length) count = 1;\n        }\n\n        $items.eq(keyIndex[count - 1]).focus();\n      }\n\n      // Select focused option if \"Enter\", \"Spacebar\" or \"Tab\" (when selectOnTab is true) are pressed inside the menu.\n      if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {\n        if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();\n        if (!that.options.liveSearch) {\n          var elem = $(':focus');\n          elem.click();\n          // Bring back focus for multiselects\n          elem.focus();\n          // Prevent screen from scrolling if the user hit the spacebar\n          e.preventDefault();\n          // Fixes spacebar selection of dropdown items in FF & IE\n          $(document).data('spaceSelect', true);\n        } else if (!/(32)/.test(e.keyCode.toString(10))) {\n          that.$menu.find('.active a').click();\n          $this.focus();\n        }\n        $(document).data('keycount', 0);\n      }\n\n      if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {\n        that.$menu.parent().removeClass('open');\n        if (that.options.container) that.$newElement.removeClass('open');\n        that.$button.focus();\n      }\n    },\n\n    mobile: function () {\n      this.$element.addClass('mobile-device').appendTo(this.$newElement);\n      if (this.options.container) this.$menu.hide();\n    },\n\n    refresh: function () {\n      this.$lis = null;\n      this.liObj = {};\n      this.reloadLi();\n      this.render();\n      this.checkDisabled();\n      this.liHeight(true);\n      this.setStyle();\n      this.setWidth();\n      if (this.$lis) this.$searchbox.trigger('propertychange');\n\n      this.$element.trigger('refreshed.bs.select');\n    },\n\n    hide: function () {\n      this.$newElement.hide();\n    },\n\n    show: function () {\n      this.$newElement.show();\n    },\n\n    remove: function () {\n      this.$newElement.remove();\n      this.$element.remove();\n    }\n  };\n\n  // SELECTPICKER PLUGIN DEFINITION\n  // ==============================\n  function Plugin(option, event) {\n    // get the args of the outer function..\n    var args = arguments;\n    // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them\n    // to get lost/corrupted in android 2.3 and IE9 #715 #775\n    var _option = option,\n        _event = event;\n    [].shift.apply(args);\n\n    var value;\n    var chain = this.each(function () {\n      var $this = $(this);\n      if ($this.is('select')) {\n        var data = $this.data('selectpicker'),\n            options = typeof _option == 'object' && _option;\n\n        if (!data) {\n          var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);\n          $this.data('selectpicker', (data = new Selectpicker(this, config, _event)));\n        } else if (options) {\n          for (var i in options) {\n            if (options.hasOwnProperty(i)) {\n              data.options[i] = options[i];\n            }\n          }\n        }\n\n        if (typeof _option == 'string') {\n          if (data[_option] instanceof Function) {\n            value = data[_option].apply(data, args);\n          } else {\n            value = data.options[_option];\n          }\n        }\n      }\n    });\n\n    if (typeof value !== 'undefined') {\n      //noinspection JSUnusedAssignment\n      return value;\n    } else {\n      return chain;\n    }\n  }\n\n  var old = $.fn.selectpicker;\n  $.fn.selectpicker = Plugin;\n  $.fn.selectpicker.Constructor = Selectpicker;\n\n  // SELECTPICKER NO CONFLICT\n  // ========================\n  $.fn.selectpicker.noConflict = function () {\n    $.fn.selectpicker = old;\n    return this;\n  };\n\n  $(document)\n      .data('keycount', 0)\n      .on('keydown', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"menu\"], .bs-searchbox input', Selectpicker.prototype.keydown)\n      .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"menu\"], .bs-searchbox input', function (e) {\n        e.stopPropagation();\n      });\n\n  // SELECTPICKER DATA-API\n  // =====================\n  $(window).on('load.bs.select.data-api', function () {\n    $('.selectpicker').each(function () {\n      var $selectpicker = $(this);\n      Plugin.call($selectpicker, $selectpicker.data());\n    })\n  });\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-bg_BG.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нищо избрано',\n    noneResultsText: 'Няма резултат за {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} избран елемент\" : \"{0} избрани елемента\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Лимита е достигнат ({n} елемент максимум)' : 'Лимита е достигнат ({n} елемента максимум)',\n        (numGroup == 1) ? 'Груповия лимит е достигнат ({n} елемент максимум)' : 'Груповия лимит е достигнат ({n} елемента максимум)'\n      ];\n    },\n    selectAllText: 'Избери всички',\n    deselectAllText: 'Размаркирай всички',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-cs_CZ.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic není vybráno',\n    noneResultsText: 'Žádné výsledky {0}',\n    countSelectedText: 'Označeno {0} z {1}',\n    maxOptionsText: ['Limit překročen ({n} {var} max)', 'Limit skupiny překročen ({n} {var} max)', ['položek', 'položka']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-da_DK.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Intet valgt',\n    noneResultsText: 'Ingen resultater fundet {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valgt\" : \"{0} valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Begrænsning nået (max {n} valgt)' : 'Begrænsning nået (max {n} valgte)',\n        (numGroup == 1) ? 'Gruppe-begrænsning nået (max {n} valgt)' : 'Gruppe-begrænsning nået (max {n} valgte)'\n      ];\n    },\n    selectAllText: 'Markér alle',\n    deselectAllText: 'Afmarkér alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-de_DE.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Bitte wählen...',\n    noneResultsText: 'Keine Ergebnisse für {0}',\n    countSelectedText: '{0} von {1} ausgewählt',\n    maxOptionsText: ['Limit erreicht ({n} {var} max.)', 'Gruppen-Limit erreicht ({n} {var} max.)', ['Eintrag', 'Einträge']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-en_US.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results match {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-es_CL.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-eu.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hautapenik ez',\n    noneResultsText: 'Emaitzarik ez {0}',\n    countSelectedText: '{1}(e)tik {0} hautatuta',\n    maxOptionsText: ['Mugara iritsita ({n} {var} gehienez)', 'Taldearen mugara iritsita ({n} {var} gehienez)', ['elementu', 'elementu']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-fa_IR.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n    $.fn.selectpicker.defaults = {\n        noneSelectedText: 'چیزی انتخاب نشده است',\n        noneResultsText: 'هیج مشابهی برای {0} پیدا نشد',\n        countSelectedText: \"{0} از {1} مورد انتخاب شده\",\n        maxOptionsText: ['بیشتر ممکن نیست {حداکثر {n} عدد}', 'بیشتر ممکن نیست {حداکثر {n} عدد}'],\n        selectAllText: 'انتخاب همه',\n        deselectAllText: 'انتخاب هیچ کدام',\n        multipleSeparator: ', '\n    };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-fr_FR.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Aucune s&eacute;lection',\n    noneResultsText: 'Aucun r&eacute;sultat pour {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected > 1) ? \"{0} &eacute;l&eacute;ments s&eacute;lectionn&eacute;s\" : \"{0} &eacute;l&eacute;ment s&eacute;lectionn&eacute;\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll > 1) ? 'Limite atteinte ({n} &eacute;l&eacute;ments max)' : 'Limite atteinte ({n} &eacute;l&eacute;ment max)',\n        (numGroup > 1) ? 'Limite du groupe atteinte ({n} &eacute;l&eacute;ments max)' : 'Limite du groupe atteinte ({n} &eacute;l&eacute;ment max)'\n      ];\n    },\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-hu_HU.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Válasszon!',\n    noneResultsText: 'Nincs találat {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return '{n} elem kiválasztva';\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Legfeljebb {n} elem választható',\n        'A csoportban legfeljebb {n} elem választható'\n      ];\n    },\n    selectAllText: 'Mind',\n    deselectAllText: 'Egyik sem',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-it_IT.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nessuna selezione',\n    noneResultsText: 'Nessun risultato per {0}',\n    countSelectedText: 'Selezionati {0} di {1}',\n    maxOptionsText: ['Limite raggiunto ({n} {var} max)', 'Limite del gruppo raggiunto ({n} {var} max)', ['elementi', 'elemento']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-ko_KR.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '항목을 선택해주세요',\n    noneResultsText: '{0} 검색 결과가 없습니다',\n    countSelectedText: function (numSelected, numTotal) {\n      return \"{0}개를 선택하였습니다\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        '{n}개까지 선택 가능합니다',\n        '해당 그룹은 {n}개까지 선택 가능합니다'\n      ];\n    },\n    selectAllText: '전체선택',\n    deselectAllText: '전체해제',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-nl_NL.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niets geselecteerd',\n    noneResultsText: 'Geen resultaten gevonden voor {0}',\n    countSelectedText: '{0} van {1} geselecteerd',\n    maxOptionsText: ['Limiet bereikt ({n} {var} max)', 'Groep limiet bereikt ({n} {var} max)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-pl_PL.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic nie zaznaczono',\n    noneResultsText: 'Brak wyników wyszukiwania {0}',\n    countSelectedText: 'Zaznaczono {0} z {1}',\n    maxOptionsText: ['Osiągnięto limit ({n} {var} max)', 'Limit grupy osiągnięty ({n} {var} max)', ['elementy', 'element']],\n    selectAll: 'Zaznacz wszystkie',\n    deselectAll: 'Odznacz wszystkie',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-pt_BR.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nada selecionado',\n    noneResultsText: 'Nada encontrado contendo {0}',\n    countSelectedText: 'Selecionado {0} de {1}',\n    maxOptionsText: ['Limite excedido (máx. {n} {var})', 'Limite do grupo excedido (máx. {n} {var})', ['itens', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-pt_PT.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n$.fn.selectpicker.defaults = {\nnoneSelectedText: 'Nenhum seleccionado',\nnoneResultsText: 'Sem resultados contendo {0}',\ncountSelectedText: 'Selecionado {0} de {1}',\nmaxOptionsText: ['Limite ultrapassado (máx. {n} {var})', 'Limite de seleções ultrapassado (máx. {n} {var})', ['itens', 'item']],\nmultipleSeparator: ', '\n};\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-ro_RO.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nu a fost selectat nimic',\n    noneResultsText: 'Nu exista niciun rezultat {0}',\n    countSelectedText: '{0} din {1} selectat(e)',\n    maxOptionsText: ['Limita a fost atinsa ({n} {var} max)', 'Limita de grup a fost atinsa ({n} {var} max)', ['iteme', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-ru_RU.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ничего не выбрано',\n    noneResultsText: 'Совпадений не найдено {0}',\n    countSelectedText: 'Выбрано {0} из {1}',\n    maxOptionsText: ['Достигнут предел ({n} {var} максимум)', 'Достигнут предел в группе ({n} {var} максимум)', ['items', 'item']],\n    doneButtonText: 'Закрыть',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-sk_SK.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Vyberte zo zoznamu',\n    noneResultsText: 'Pre výraz {0} neboli nájdené žiadne výsledky',\n    countSelectedText: 'Vybrané {0} z {1}',\n    maxOptionsText: ['Limit prekročený ({n} {var} max)', 'Limit skupiny prekročený ({n} {var} max)', ['položiek', 'položka']],\n    selectAllText: 'Vybrať všetky',\n    deselectAllText: 'Zrušiť výber',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-sl_SI.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nič izbranega',\n    noneResultsText: 'Ni zadetkov za {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      \"Število izbranih: {0}\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Omejitev dosežena (max. izbranih: {n})',\n        'Omejitev skupine dosežena (max. izbranih: {n})'\n      ];\n    },\n    selectAllText: 'Izberi vse',\n    deselectAllText: 'Počisti izbor',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-sv_SE.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Inget valt',\n    noneResultsText: 'Inget sökresultat matchar {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected === 1) ? \"{0} alternativ valt\" : \"{0} alternativ valda\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Gräns uppnåd (max {n} alternativ)',\n        'Gräns uppnåd (max {n} gruppalternativ)'\n      ];\n    },\n    selectAllText: 'Markera alla',\n    deselectAllText: 'Avmarkera alla',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-tr_TR.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hiçbiri seçilmedi',\n    noneResultsText: 'Hiçbir sonuç bulunamadı {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} öğe seçildi\" : \"{0} öğe seçildi\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit aşıldı (maksimum {n} sayıda öğe )' : 'Limit aşıldı (maksimum {n} sayıda öğe)',\n        (numGroup == 1) ? 'Grup limiti aşıldı (maksimum {n} sayıda öğe)' : 'Grup limiti aşıldı (maksimum {n} sayıda öğe)'\n      ];\n    },\n    selectAllText: 'Tümünü Seç',\n    deselectAllText: 'Seçiniz',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-ua_UA.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нічого не вибрано',\n    noneResultsText: 'Збігів не знайдено {0}',\n    countSelectedText: 'Вибрано {0} із {1}',\n    maxOptionsText: ['Досягнута межа ({n} {var} максимум)', 'Досягнута межа в групі ({n} {var} максимум)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-zh_CN.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '没有选中任何项',\n    noneResultsText: '没有找到匹配项',\n    countSelectedText: '选中{1}中的{0}项',\n    maxOptionsText: ['超出限制 (最多选择{n}项)', '组选择超出限制(最多选择{n}组)'],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/dist/js/i18n/defaults-zh_TW.js",
    "content": "/*!\n * Bootstrap-select v1.7.3 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2015 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof exports === 'object') {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(jQuery);\n  }\n}(this, function () {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '沒有選取任何項目',\n    noneResultsText: '沒有找到符合的結果',\n    countSelectedText: '已經選取{0}個項目',\n    maxOptionsText: ['超過限制 (最多選擇{n}項)', '超過限制(最多選擇{n}組)'],\n    selectAllText: '選取全部',\n    deselectAllText: '全部取消',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/.jshintrc",
    "content": "{\n  \"curly\": true,\n  \"eqeqeq\": true,\n  \"immed\": true,\n  \"latedef\": true,\n  \"newcap\": true,\n  \"noarg\": true,\n  \"sub\": true,\n  \"undef\": true,\n  \"unused\": true,\n  \"boss\": true,\n  \"eqnull\": true,\n  \"browser\": true,\n  \"jquery\": true\n}\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/bootstrap-select.js",
    "content": "(function ($) {\n  'use strict';\n\n  //<editor-fold desc=\"Shims\">\n  if (!String.prototype.includes) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var toString = {}.toString;\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var indexOf = ''.indexOf;\n      var includes = function (search) {\n        if (this == null) {\n          throw TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        return indexOf.call(string, searchString, pos) != -1;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'includes', {\n          'value': includes,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.includes = includes;\n      }\n    }());\n  }\n\n  if (!String.prototype.startsWith) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var toString = {}.toString;\n      var startsWith = function (search) {\n        if (this == null) {\n          throw TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        var index = -1;\n        while (++index < searchLength) {\n          if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {\n            return false;\n          }\n        }\n        return true;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'startsWith', {\n          'value': startsWith,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.startsWith = startsWith;\n      }\n    }());\n  }\n\n  if (!Object.keys) {\n    Object.keys = function (\n      o, // object\n      k, // key\n      r  // result array\n      ){\n      // initialize object and result\n      r=[];\n      // iterate over object keys\n      for (k in o) \n          // fill result array with non-prototypical keys\n        r.hasOwnProperty.call(o, k) && r.push(k);\n      // return result\n      return r\n    };\n  }\n\n  $.fn.triggerNative = function (eventName) {\n    var el = this[0],\n        event;\n\n    if (el.dispatchEvent) {\n      if (typeof Event === 'function') {\n        // For modern browsers\n        event = new Event(eventName, {\n          bubbles: true\n        });\n      } else {\n        // For IE since it doesn't support Event constructor\n        event = document.createEvent('Event');\n        event.initEvent(eventName, true, false);\n      }\n\n      el.dispatchEvent(event);\n    } else {\n      if (el.fireEvent) {\n        event = document.createEventObject();\n        event.eventType = eventName;\n        el.fireEvent('on' + eventName, event);\n      }\n\n      this.trigger(eventName);\n    }\n  };\n  //</editor-fold>\n\n  // Case insensitive contains search\n  $.expr[':'].icontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case insensitive begins search\n  $.expr[':'].ibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive contains search\n  $.expr[':'].aicontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive begins search\n  $.expr[':'].aibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  /**\n   * Remove all diatrics from the given text.\n   * @access private\n   * @param {String} text\n   * @returns {String}\n   */\n  function normalizeToBase(text) {\n    var rExps = [\n      {re: /[\\xC0-\\xC6]/g, ch: \"A\"},\n      {re: /[\\xE0-\\xE6]/g, ch: \"a\"},\n      {re: /[\\xC8-\\xCB]/g, ch: \"E\"},\n      {re: /[\\xE8-\\xEB]/g, ch: \"e\"},\n      {re: /[\\xCC-\\xCF]/g, ch: \"I\"},\n      {re: /[\\xEC-\\xEF]/g, ch: \"i\"},\n      {re: /[\\xD2-\\xD6]/g, ch: \"O\"},\n      {re: /[\\xF2-\\xF6]/g, ch: \"o\"},\n      {re: /[\\xD9-\\xDC]/g, ch: \"U\"},\n      {re: /[\\xF9-\\xFC]/g, ch: \"u\"},\n      {re: /[\\xC7-\\xE7]/g, ch: \"c\"},\n      {re: /[\\xD1]/g, ch: \"N\"},\n      {re: /[\\xF1]/g, ch: \"n\"}\n    ];\n    $.each(rExps, function () {\n      text = text.replace(this.re, this.ch);\n    });\n    return text;\n  }\n\n\n  function htmlEscape(html) {\n    var escapeMap = {\n      '&': '&amp;',\n      '<': '&lt;',\n      '>': '&gt;',\n      '\"': '&quot;',\n      \"'\": '&#x27;',\n      '`': '&#x60;'\n    };\n    var source = '(?:' + Object.keys(escapeMap).join('|') + ')',\n        testRegexp = new RegExp(source),\n        replaceRegexp = new RegExp(source, 'g'),\n        string = html == null ? '' : '' + html;\n    return testRegexp.test(string) ? string.replace(replaceRegexp, function (match) {\n      return escapeMap[match];\n    }) : string;\n  }\n\n  var Selectpicker = function (element, options, e) {\n    if (e) {\n      e.stopPropagation();\n      e.preventDefault();\n    }\n\n    this.$element = $(element);\n    this.$newElement = null;\n    this.$button = null;\n    this.$menu = null;\n    this.$lis = null;\n    this.options = options;\n\n    // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a\n    // data-attribute)\n    if (this.options.title === null) {\n      this.options.title = this.$element.attr('title');\n    }\n\n    //Expose public methods\n    this.val = Selectpicker.prototype.val;\n    this.render = Selectpicker.prototype.render;\n    this.refresh = Selectpicker.prototype.refresh;\n    this.setStyle = Selectpicker.prototype.setStyle;\n    this.selectAll = Selectpicker.prototype.selectAll;\n    this.deselectAll = Selectpicker.prototype.deselectAll;\n    this.destroy = Selectpicker.prototype.remove;\n    this.remove = Selectpicker.prototype.remove;\n    this.show = Selectpicker.prototype.show;\n    this.hide = Selectpicker.prototype.hide;\n\n    this.init();\n  };\n\n  Selectpicker.VERSION = '1.7.2';\n\n  // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.\n  Selectpicker.DEFAULTS = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results matched {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    doneButton: false,\n    doneButtonText: 'Close',\n    multipleSeparator: ', ',\n    styleBase: 'btn',\n    style: 'btn-default',\n    size: 'auto',\n    title: null,\n    selectedTextFormat: 'values',\n    width: false,\n    container: false,\n    hideDisabled: false,\n    showSubtext: false,\n    showIcon: true,\n    showContent: true,\n    dropupAuto: true,\n    header: false,\n    liveSearch: false,\n    liveSearchPlaceholder: null,\n    liveSearchNormalize: false,\n    liveSearchStyle: 'contains',\n    actionsBox: false,\n    iconBase: 'glyphicon',\n    tickIcon: 'glyphicon-ok',\n    maxOptions: false,\n    mobile: false,\n    selectOnTab: false,\n    dropdownAlignRight: false\n  };\n\n  Selectpicker.prototype = {\n\n    constructor: Selectpicker,\n\n    init: function () {\n      var that = this,\n          id = this.$element.attr('id');\n\n      this.$element.addClass('bs-select-hidden');\n      // store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility\n      // allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index=\"' + index + '\"]')\n      this.liObj = {};\n      this.multiple = this.$element.prop('multiple');\n      this.autofocus = this.$element.prop('autofocus');\n      this.$newElement = this.createView();\n      this.$element.after(this.$newElement);\n      this.$button = this.$newElement.children('button');\n      this.$menu = this.$newElement.children('.dropdown-menu');\n      this.$menuInner = this.$menu.children('.inner');\n      this.$searchbox = this.$menu.find('input');\n\n      if (this.options.dropdownAlignRight)\n        this.$menu.addClass('dropdown-menu-right');\n\n      if (typeof id !== 'undefined') {\n        this.$button.attr('data-id', id);\n        $('label[for=\"' + id + '\"]').click(function (e) {\n          e.preventDefault();\n          that.$button.focus();\n        });\n      }\n\n      this.checkDisabled();\n      this.clickListener();\n      if (this.options.liveSearch) this.liveSearchListener();\n      this.render();\n      this.setStyle();\n      this.setWidth();\n      if (this.options.container) this.selectPosition();\n      this.$menu.data('this', this);\n      this.$newElement.data('this', this);\n      if (this.options.mobile) this.mobile();\n\n      this.$newElement.on('hide.bs.dropdown', function (e) {\n        that.$element.trigger('hide.bs.select', e);\n      });\n      \n      this.$newElement.on('hidden.bs.dropdown', function (e) {\n        that.$element.trigger('hidden.bs.select', e);\n      });\n      \n      this.$newElement.on('show.bs.dropdown', function (e) {\n        that.$element.trigger('show.bs.select', e);\n      });\n      \n      this.$newElement.on('shown.bs.dropdown', function (e) {\n        that.$element.trigger('shown.bs.select', e);\n      });\n\n      setTimeout(function () {\n        that.$element.trigger('loaded.bs.select');\n      });\n    },\n\n    createDropdown: function () {\n      // Options\n      // If we are multiple, then add the show-tick class by default\n      var multiple = this.multiple ? ' show-tick' : '',\n          inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',\n          autofocus = this.autofocus ? ' autofocus' : '';\n      // Elements\n      var header = this.options.header ? '<div class=\"popover-title\"><button type=\"button\" class=\"close\" aria-hidden=\"true\">&times;</button>' + this.options.header + '</div>' : '';\n      var searchbox = this.options.liveSearch ?\n      '<div class=\"bs-searchbox\">' +\n      '<input type=\"text\" class=\"form-control\" autocomplete=\"off\"' +\n      (null === this.options.liveSearchPlaceholder ? '' : ' placeholder=\"' + htmlEscape(this.options.liveSearchPlaceholder) + '\"') + '>' +\n      '</div>'\n          : '';\n      var actionsbox = this.multiple && this.options.actionsBox ?\n      '<div class=\"bs-actionsbox\">' +\n      '<div class=\"btn-group btn-group-sm btn-block\">' +\n      '<button type=\"button\" class=\"actions-btn bs-select-all btn btn-default\">' +\n      this.options.selectAllText +\n      '</button>' +\n      '<button type=\"button\" class=\"actions-btn bs-deselect-all btn btn-default\">' +\n      this.options.deselectAllText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var donebutton = this.multiple && this.options.doneButton ?\n      '<div class=\"bs-donebutton\">' +\n      '<div class=\"btn-group btn-block\">' +\n      '<button type=\"button\" class=\"btn btn-sm btn-default\">' +\n      this.options.doneButtonText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var drop =\n          '<div class=\"btn-group bootstrap-select' + multiple + inputGroup + '\">' +\n          '<button type=\"button\" class=\"' + this.options.styleBase + ' dropdown-toggle\" data-toggle=\"dropdown\"' + autofocus + '>' +\n          '<span class=\"filter-option pull-left\"></span>&nbsp;' +\n          '<span class=\"caret\"></span>' +\n          '</button>' +\n          '<div class=\"dropdown-menu open\">' +\n          header +\n          searchbox +\n          actionsbox +\n          '<ul class=\"dropdown-menu inner\" role=\"menu\">' +\n          '</ul>' +\n          donebutton +\n          '</div>' +\n          '</div>';\n\n      return $(drop);\n    },\n\n    createView: function () {\n      var $drop = this.createDropdown(),\n          li = this.createLi();\n\n      $drop.find('ul')[0].innerHTML = li;\n      return $drop;\n    },\n\n    reloadLi: function () {\n      //Remove all children.\n      this.destroyLi();\n      //Re build\n      var li = this.createLi();\n      this.$menuInner[0].innerHTML = li;\n    },\n\n    destroyLi: function () {\n      this.$menu.find('li').remove();\n    },\n\n    createLi: function () {\n      var that = this,\n          _li = [],\n          optID = 0,\n          titleOption = document.createElement('option'),\n          liIndex = -1; // increment liIndex whenever a new <li> element is created to ensure liObj is correct\n\n      // Helper functions\n      /**\n       * @param content\n       * @param [index]\n       * @param [classes]\n       * @param [optgroup]\n       * @returns {string}\n       */\n      var generateLI = function (content, index, classes, optgroup) {\n        return '<li' +\n            ((typeof classes !== 'undefined' & '' !== classes) ? ' class=\"' + classes + '\"' : '') +\n            ((typeof index !== 'undefined' & null !== index) ? ' data-original-index=\"' + index + '\"' : '') +\n            ((typeof optgroup !== 'undefined' & null !== optgroup) ? 'data-optgroup=\"' + optgroup + '\"' : '') +\n            '>' + content + '</li>';\n      };\n\n      /**\n       * @param text\n       * @param [classes]\n       * @param [inline]\n       * @param [tokens]\n       * @returns {string}\n       */\n      var generateA = function (text, classes, inline, tokens) {\n        return '<a tabindex=\"0\"' +\n            (typeof classes !== 'undefined' ? ' class=\"' + classes + '\"' : '') +\n            (typeof inline !== 'undefined' ? ' style=\"' + inline + '\"' : '') +\n            (that.options.liveSearchNormalize ? ' data-normalized-text=\"' + normalizeToBase(htmlEscape(text)) + '\"' : '') +\n            (typeof tokens !== 'undefined' || tokens !== null ? ' data-tokens=\"' + tokens + '\"' : '') +\n            '>' + text +\n            '<span class=\"' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark\"></span>' +\n            '</a>';\n      };\n\n      if (this.options.title && !this.multiple) {\n        // this option doesn't create a new <li> element, but does add a new option, so liIndex is decreased\n        // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended\n        liIndex--;\n\n        if (!this.$element.find('.bs-title-option').length) {\n          // Use native JS to prepend option (faster)\n          var element = this.$element[0];\n          titleOption.className = 'bs-title-option';\n          titleOption.appendChild(document.createTextNode(this.options.title));\n          titleOption.value = '';\n          element.insertBefore(titleOption, element.firstChild);\n          // Check if selected attribute is already set on an option. If not, select the titleOption option.\n          if ($(element.options[element.selectedIndex]).attr('selected') === undefined) titleOption.selected = true;\n        }\n      }\n\n      this.$element.find('option').each(function (index) {\n        var $this = $(this);\n\n        liIndex++;\n\n        if ($this.hasClass('bs-title-option')) return;\n\n        // Get the class and text for the option\n        var optionClass = this.className || '',\n            inline = this.style.cssText,\n            text = $this.data('content') ? $this.data('content') : $this.html(),\n            tokens = $this.data('tokens') ? $this.data('tokens') : null,\n            subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $this.data('subtext') + '</small>' : '',\n            icon = typeof $this.data('icon') !== 'undefined' ? '<span class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></span> ' : '',\n            isDisabled = this.disabled || (this.parentElement.tagName === 'OPTGROUP' && this.parentElement.disabled);\n\n        if (icon !== '' && isDisabled) {\n          icon = '<span>' + icon + '</span>';\n        }\n\n        if (that.options.hideDisabled && isDisabled) {\n          liIndex--;\n          return;\n        }\n\n        if (!$this.data('content')) {\n          // Prepend any icon and append any subtext to the main text.\n          text = icon + '<span class=\"text\">' + text + subtext + '</span>';\n        }\n\n        if (this.parentElement.tagName === 'OPTGROUP' && $this.data('divider') !== true) {\n          var optGroupClass = ' ' + this.parentElement.className || '';\n\n          if ($this.index() === 0) { // Is it the first option of the optgroup?\n            optID += 1;\n\n            // Get the opt group label\n            var label = this.parentElement.label,\n                labelSubtext = typeof $this.parent().data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $this.parent().data('subtext') + '</small>' : '',\n                labelIcon = $this.parent().data('icon') ? '<span class=\"' + that.options.iconBase + ' ' + $this.parent().data('icon') + '\"></span> ' : '';\n            \n            label = labelIcon + '<span class=\"text\">' + label + labelSubtext + '</span>';\n\n            if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?\n              liIndex++;\n              _li.push(generateLI('', null, 'divider', optID + 'div'));\n            }\n            liIndex++;\n            _li.push(generateLI(label, null, 'dropdown-header' + optGroupClass, optID));\n          }\n          _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID));\n        } else if ($this.data('divider') === true) {\n          _li.push(generateLI('', index, 'divider'));\n        } else if ($this.data('hidden') === true) {\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden'));\n        } else {\n          if (this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP') {\n            liIndex++;\n            _li.push(generateLI('', null, 'divider', optID + 'div'));\n          }\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index));\n        }\n\n        that.liObj[index] = liIndex;\n      });\n\n      //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button\n      if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {\n        this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');\n      }\n\n      return _li.join('');\n    },\n\n    findLis: function () {\n      if (this.$lis == null) this.$lis = this.$menu.find('li');\n      return this.$lis;\n    },\n\n    /**\n     * @param [updateLi] defaults to true\n     */\n    render: function (updateLi) {\n      var that = this,\n          notDisabled;\n\n      //Update the LI to match the SELECT\n      if (updateLi !== false) {\n        this.$element.find('option').each(function (index) {\n          var $lis = that.findLis().eq(that.liObj[index]);\n\n          that.setDisabled(index, this.disabled || this.parentElement.tagName === 'OPTGROUP' && this.parentElement.disabled, $lis);\n          that.setSelected(index, this.selected, $lis);\n        });\n      }\n\n      this.tabIndex();\n\n      var selectedItems = this.$element.find('option').map(function () {\n        if (this.selected) {\n          if (that.options.hideDisabled && (this.disabled || this.parentElement.tagName === 'OPTGROUP' && this.parentElement.disabled)) return false;\n\n          var $this = $(this),\n              icon = $this.data('icon') && that.options.showIcon ? '<i class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></i> ' : '',\n              subtext;\n\n          if (that.options.showSubtext && $this.data('subtext') && !that.multiple) {\n            subtext = ' <small class=\"text-muted\">' + $this.data('subtext') + '</small>';\n          } else {\n            subtext = '';\n          }\n          if (typeof $this.attr('title') !== 'undefined') {\n            return $this.attr('title');\n          } else if ($this.data('content') && that.options.showContent) {\n            return $this.data('content');\n          } else {\n            return icon + $this.html() + subtext;\n          }\n        }\n      }).toArray();\n\n      //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled\n      //Convert all the values into a comma delimited string\n      var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);\n\n      //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..\n      if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {\n        var max = this.options.selectedTextFormat.split('>');\n        if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {\n          notDisabled = this.options.hideDisabled ? ', [disabled]' : '';\n          var totalCount = this.$element.find('option').not('[data-divider=\"true\"], [data-hidden=\"true\"]' + notDisabled).length,\n              tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;\n          title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());\n        }\n      }\n\n      if (this.options.title == undefined) {\n        this.options.title = this.$element.attr('title');\n      }\n\n      if (this.options.selectedTextFormat == 'static') {\n        title = this.options.title;\n      }\n\n      //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text\n      if (!title) {\n        title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;\n      }\n\n      //strip all html-tags and trim the result\n      this.$button.attr('title', $.trim(title.replace(/<[^>]*>?/g, '')));\n      this.$button.children('.filter-option').html(title);\n\n      this.$element.trigger('rendered.bs.select');\n    },\n\n    /**\n     * @param [style]\n     * @param [status]\n     */\n    setStyle: function (style, status) {\n      if (this.$element.attr('class')) {\n        this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\\[.*\\]/gi, ''));\n      }\n\n      var buttonClass = style ? style : this.options.style;\n\n      if (status == 'add') {\n        this.$button.addClass(buttonClass);\n      } else if (status == 'remove') {\n        this.$button.removeClass(buttonClass);\n      } else {\n        this.$button.removeClass(this.options.style);\n        this.$button.addClass(buttonClass);\n      }\n    },\n\n    liHeight: function (refresh) {\n      if (!refresh && (this.options.size === false || this.sizeInfo)) return;\n\n      var newElement = document.createElement('div'),\n          menu = document.createElement('div'),\n          menuInner = document.createElement('ul'),\n          divider = document.createElement('li'),\n          li = document.createElement('li'),\n          a = document.createElement('a'),\n          text = document.createElement('span'),\n          header = this.options.header ? this.$menu.find('.popover-title')[0].cloneNode(true) : null,\n          search = this.options.liveSearch ? document.createElement('div') : null,\n          actions = this.options.actionsBox && this.multiple ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null,\n          doneButton = this.options.doneButton && this.multiple ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null;\n\n      text.className = 'text';\n      newElement.className = this.$menu[0].parentNode.className + ' open';\n      menu.className = 'dropdown-menu open';\n      menuInner.className = 'dropdown-menu inner';\n      divider.className = 'divider';\n\n      text.appendChild(document.createTextNode('Inner text'));\n      a.appendChild(text);\n      li.appendChild(a);\n      menuInner.appendChild(li);\n      menuInner.appendChild(divider);\n      if (header) menu.appendChild(header);\n      if (search) {\n        // create a span instead of input as creating an input element is slower\n        var input = document.createElement('span');\n        search.className = 'bs-searchbox';\n        input.className = 'form-control';\n        search.appendChild(input);\n        menu.appendChild(search);\n      }\n      if (actions) menu.appendChild(actions);\n      menu.appendChild(menuInner);\n      if (doneButton) menu.appendChild(doneButton);\n      newElement.appendChild(menu);\n\n      document.body.appendChild(newElement);\n\n      var liHeight = a.offsetHeight,\n          headerHeight = header ? header.offsetHeight : 0,\n          searchHeight = search ? search.offsetHeight : 0,\n          actionsHeight = actions ? actions.offsetHeight : 0,\n          doneButtonHeight = doneButton ? doneButton.offsetHeight : 0,\n          dividerHeight = $(divider).outerHeight(true),\n          // fall back to jQuery if getComputedStyle is not supported\n          menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,\n          $menu = menuStyle ? null : $(menu),\n          menuPadding = parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +\n                        parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +\n                        parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +\n                        parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),\n          menuExtras =  menuPadding + \n                        parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) + \n                        parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2;\n\n      document.body.removeChild(newElement);\n\n      this.sizeInfo = {\n        liHeight: liHeight,\n        headerHeight: headerHeight,\n        searchHeight: searchHeight,\n        actionsHeight: actionsHeight,\n        doneButtonHeight: doneButtonHeight,\n        dividerHeight: dividerHeight,\n        menuPadding: menuPadding,\n        menuExtras: menuExtras\n      };\n    },\n\n    setSize: function () {\n      this.findLis();\n      this.liHeight();\n\n      if (this.options.header) this.$menu.css('padding-top', 0);\n      if (this.options.size === false) return;\n\n      var that = this,\n          $menu = this.$menu,\n          $menuInner = this.$menuInner,\n          $window = $(window),\n          selectHeight = this.$newElement[0].offsetHeight,\n          liHeight = this.sizeInfo['liHeight'],\n          headerHeight = this.sizeInfo['headerHeight'],\n          searchHeight = this.sizeInfo['searchHeight'],\n          actionsHeight = this.sizeInfo['actionsHeight'],\n          doneButtonHeight = this.sizeInfo['doneButtonHeight'],\n          divHeight = this.sizeInfo['dividerHeight'],\n          menuPadding = this.sizeInfo['menuPadding'],\n          menuExtras = this.sizeInfo['menuExtras'],\n          notDisabled = this.options.hideDisabled ? '.disabled' : '',\n          menuHeight,\n          getHeight,\n          selectOffsetTop,\n          selectOffsetBot,\n          posVert = function () {\n            selectOffsetTop = that.$newElement.offset().top - $window.scrollTop();\n            selectOffsetBot = $window.height() - selectOffsetTop - selectHeight;\n          };\n\n      posVert();\n\n      if (this.options.size === 'auto') {\n        var getSize = function () {\n          var minHeight,\n              hasClass = function (className, include) {\n                return function (element) {\n                    if (include) {\n                        return (element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    } else {\n                        return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    }\n                };\n              },\n              lis = that.$menuInner[0].getElementsByTagName('li'),\n              lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),\n              optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');\n\n          posVert();\n          menuHeight = selectOffsetBot - menuExtras;\n\n          if (that.options.container) {\n            if (!$menu.data('height')) $menu.data('height', $menu.height());\n            getHeight = $menu.data('height');\n          } else {\n            getHeight = $menu.height();\n          }\n\n          if (that.options.dropupAuto) {\n            that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras) < getHeight);\n          }\n          if (that.$newElement.hasClass('dropup')) {\n            menuHeight = selectOffsetTop - menuExtras;\n          }\n\n          if ((lisVisible.length + optGroup.length) > 3) {\n            minHeight = liHeight * 3 + menuExtras - 2;\n          } else {\n            minHeight = 0;\n          }\n\n          $menu.css({\n            'max-height': menuHeight + 'px',\n            'overflow': 'hidden',\n            'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'\n          });\n          $menuInner.css({\n            'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding + 'px',\n            'overflow-y': 'auto',\n            'min-height': Math.max(minHeight - menuPadding, 0) + 'px'\n          });\n        };\n        getSize();\n        this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);\n        $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize);\n      } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {\n        var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),\n            divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;\n        menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding;\n\n        if (that.options.container) {\n          if (!$menu.data('height')) $menu.data('height', $menu.height());\n          getHeight = $menu.data('height');\n        } else {\n          getHeight = $menu.height();\n        }\n\n        if (that.options.dropupAuto) {\n          //noinspection JSUnusedAssignment\n          this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras) < getHeight);\n        }\n        $menu.css({\n          'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',\n          'overflow': 'hidden',\n          'min-height': ''\n        });\n        $menuInner.css({\n          'max-height': menuHeight - menuPadding + 'px',\n          'overflow-y': 'auto',\n          'min-height': ''\n        });\n      }\n    },\n\n    setWidth: function () {\n      if (this.options.width === 'auto') {\n        this.$menu.css('min-width', '0');\n\n        // Get correct width if element is hidden\n        var $selectClone = this.$menu.parent().clone().appendTo('body'),\n            $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone,\n            ulWidth = $selectClone.children('.dropdown-menu').outerWidth(),\n            btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth();\n\n        $selectClone.remove();\n        $selectClone2.remove();\n\n        // Set width to whatever's larger, button title or longest option\n        this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px');\n      } else if (this.options.width === 'fit') {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '').addClass('fit-width');\n      } else if (this.options.width) {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', this.options.width);\n      } else {\n        // Remove inline min-width/width so width can be changed\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '');\n      }\n      // Remove fit-width class if width is changed programmatically\n      if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {\n        this.$newElement.removeClass('fit-width');\n      }\n    },\n\n    selectPosition: function () {\n      var that = this,\n          drop = '<div />',\n          $drop = $(drop),\n          pos,\n          actualHeight,\n          getPlacement = function ($element) {\n            $drop.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));\n            pos = $element.offset();\n            actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;\n            $drop.css({\n              'top': pos.top + actualHeight,\n              'left': pos.left,\n              'width': $element[0].offsetWidth,\n              'position': 'absolute'\n            });\n          };\n\n      this.$newElement.on('click', function () {\n        if (that.isDisabled()) {\n          return;\n        }\n        getPlacement($(this));\n        $drop.appendTo(that.options.container);\n        $drop.toggleClass('open', !$(this).hasClass('open'));\n        $drop.append(that.$menu);\n      });\n\n      $(window).on('resize scroll', function () {\n        getPlacement(that.$newElement);\n      });\n\n      this.$element.on('hide.bs.select', function () {\n        that.$menu.data('height', that.$menu.height());\n        $drop.detach();\n      });\n    },\n\n    setSelected: function (index, selected, $lis) {\n      if (!$lis) {\n        var $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      $lis.toggleClass('selected', selected);\n    },\n\n    setDisabled: function (index, disabled, $lis) {\n      if (!$lis) {\n        var $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      if (disabled) {\n        $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1);\n      } else {\n        $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0);\n      }\n    },\n\n    isDisabled: function () {\n      return this.$element[0].disabled;\n    },\n\n    checkDisabled: function () {\n      var that = this;\n\n      if (this.isDisabled()) {\n        this.$newElement.addClass('disabled');\n        this.$button.addClass('disabled').attr('tabindex', -1);\n      } else {\n        if (this.$button.hasClass('disabled')) {\n          this.$newElement.removeClass('disabled');\n          this.$button.removeClass('disabled');\n        }\n\n        if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) {\n          this.$button.removeAttr('tabindex');\n        }\n      }\n\n      this.$button.click(function () {\n        return !that.isDisabled();\n      });\n    },\n\n    tabIndex: function () {\n      if (this.$element.is('[tabindex]')) {\n        this.$element.data('tabindex', this.$element.attr('tabindex'));\n        this.$button.attr('tabindex', this.$element.data('tabindex'));\n      }\n    },\n\n    clickListener: function () {\n      var that = this,\n          $document = $(document);\n\n      this.$newElement.on('touchstart.dropdown', '.dropdown-menu', function (e) {\n        e.stopPropagation();\n      });\n\n      $document.data('spaceSelect', false);\n      \n      this.$button.on('keyup', function (e) {\n        if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {\n            e.preventDefault();\n            $document.data('spaceSelect', false);\n        }\n      });\n\n      this.$newElement.on('click', function () {\n        that.setSize();\n        that.$element.on('shown.bs.select', function () {\n          if (!that.options.liveSearch && !that.multiple) {\n            that.$menu.find('.selected a').focus();\n          } else if (!that.multiple) {\n            var selectedIndex = that.liObj[that.$element[0].selectedIndex];\n\n            if (typeof selectedIndex !== 'number' || that.options.size === false) return;\n            \n            // scroll to selected option\n            var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop;\n            offset = offset - that.$menuInner[0].offsetHeight/2 + that.sizeInfo.liHeight/2;\n            that.$menuInner[0].scrollTop = offset;\n          }\n        });\n      });\n\n      this.$menu.on('click', 'li a', function (e) {\n        var $this = $(this),\n            clickedIndex = $this.parent().data('originalIndex'),\n            prevValue = that.$element.val(),\n            prevIndex = that.$element.prop('selectedIndex');\n\n        // Don't close on multi choice menu\n        if (that.multiple) {\n          e.stopPropagation();\n        }\n\n        e.preventDefault();\n\n        //Don't run if we have been disabled\n        if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {\n          var $options = that.$element.find('option'),\n              $option = $options.eq(clickedIndex),\n              state = $option.prop('selected'),\n              $optgroup = $option.parent('optgroup'),\n              maxOptions = that.options.maxOptions,\n              maxOptionsGrp = $optgroup.data('maxOptions') || false;\n\n          if (!that.multiple) { // Deselect all others if not multi select box\n            $options.prop('selected', false);\n            $option.prop('selected', true);\n            that.$menu.find('.selected').removeClass('selected');\n            that.setSelected(clickedIndex, true);\n          } else { // Toggle the one we have chosen if we are multi select.\n            $option.prop('selected', !state);\n            that.setSelected(clickedIndex, !state);\n            $this.blur();\n\n            if (maxOptions !== false || maxOptionsGrp !== false) {\n              var maxReached = maxOptions < $options.filter(':selected').length,\n                  maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;\n\n              if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {\n                if (maxOptions && maxOptions == 1) {\n                  $options.prop('selected', false);\n                  $option.prop('selected', true);\n                  that.$menu.find('.selected').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else if (maxOptionsGrp && maxOptionsGrp == 1) {\n                  $optgroup.find('option:selected').prop('selected', false);\n                  $option.prop('selected', true);\n                  var optgroupID = $this.parent().data('optgroup');\n                  that.$menu.find('[data-optgroup=\"' + optgroupID + '\"]').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else {\n                  var maxOptionsArr = (typeof that.options.maxOptionsText === 'function') ?\n                          that.options.maxOptionsText(maxOptions, maxOptionsGrp) : that.options.maxOptionsText,\n                      maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),\n                      maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),\n                      $notify = $('<div class=\"notify\"></div>');\n                  // If {var} is set in array, replace it\n                  /** @deprecated */\n                  if (maxOptionsArr[2]) {\n                    maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);\n                    maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);\n                  }\n\n                  $option.prop('selected', false);\n\n                  that.$menu.append($notify);\n\n                  if (maxOptions && maxReached) {\n                    $notify.append($('<div>' + maxTxt + '</div>'));\n                    that.$element.trigger('maxReached.bs.select');\n                  }\n\n                  if (maxOptionsGrp && maxReachedGrp) {\n                    $notify.append($('<div>' + maxTxtGrp + '</div>'));\n                    that.$element.trigger('maxReachedGrp.bs.select');\n                  }\n\n                  setTimeout(function () {\n                    that.setSelected(clickedIndex, false);\n                  }, 10);\n\n                  $notify.delay(750).fadeOut(300, function () {\n                    $(this).remove();\n                  });\n                }\n              }\n            }\n          }\n\n          if (!that.multiple) {\n            that.$button.focus();\n          } else if (that.options.liveSearch) {\n            that.$searchbox.focus();\n          }\n\n          // Trigger select 'change'\n          if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {\n            that.$element.triggerNative('change');\n            // $option.prop('selected') is current option state (selected/unselected). state is previous option state.\n            that.$element.trigger('changed.bs.select', [clickedIndex, $option.prop('selected'), state]);\n          }\n        }\n      });\n\n      this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {\n        if (e.currentTarget == this) {\n          e.preventDefault();\n          e.stopPropagation();\n          if (that.options.liveSearch && !$(e.target).hasClass('close')) {\n            that.$searchbox.focus();\n          } else {\n            that.$button.focus();\n          }\n        }\n      });\n\n      this.$menu.on('click', 'li.divider, li.dropdown-header', function (e) {\n        e.preventDefault();\n        e.stopPropagation();\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n      });\n\n      this.$menu.on('click', '.popover-title .close', function () {\n        that.$button.click();\n      });\n\n      this.$searchbox.on('click', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$menu.on('click', '.actions-btn', function (e) {\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n\n        e.preventDefault();\n        e.stopPropagation();\n\n        if ($(this).hasClass('bs-select-all')) {\n          that.selectAll();\n        } else {\n          that.deselectAll();\n        }\n        that.$element.triggerNative('change');\n      });\n\n      this.$element.change(function () {\n        that.render(false);\n      });\n    },\n\n    liveSearchListener: function () {\n      var that = this,\n          $no_results = $('<li class=\"no-results\"></li>');\n\n      this.$newElement.on('click.dropdown.data-api touchstart.dropdown.data-api', function () {\n        that.$menuInner.find('.active').removeClass('active');\n        if (!!that.$searchbox.val()) {\n          that.$searchbox.val('');\n          that.$lis.not('.is-hidden').removeClass('hidden');\n          if (!!$no_results.parent().length) $no_results.remove();\n        }\n        if (!that.multiple) that.$menuInner.find('.selected').addClass('active');\n        setTimeout(function () {\n          that.$searchbox.focus();\n        }, 10);\n      });\n\n      this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$searchbox.on('input propertychange', function () {\n        if (that.$searchbox.val()) {\n          var $searchBase = that.$lis.not('.is-hidden').removeClass('hidden').children('a');\n          if (that.options.liveSearchNormalize) {\n            $searchBase = $searchBase.not(':a' + that._searchStyle() + '(\"' + normalizeToBase(that.$searchbox.val()) + '\")');\n          } else {\n            $searchBase = $searchBase.not(':' + that._searchStyle() + '(\"' + that.$searchbox.val() + '\")');\n          }\n          $searchBase.parent().addClass('hidden');\n\n          that.$lis.filter('.dropdown-header').each(function () {\n            var $this = $(this),\n                optgroup = $this.data('optgroup');\n\n            if (that.$lis.filter('[data-optgroup=' + optgroup + ']').not($this).not('.hidden').length === 0) {\n              $this.addClass('hidden');\n              that.$lis.filter('[data-optgroup=' + optgroup + 'div]').addClass('hidden');\n            }\n          });\n\n          var $lisVisible = that.$lis.not('.hidden');\n\n          // hide divider if first or last visible, or if followed by another divider\n          $lisVisible.each(function (index) {\n            var $this = $(this);\n\n            if ($this.hasClass('divider') && (\n              $this.index() === $lisVisible.eq(0).index() ||\n              $this.index() === $lisVisible.last().index() ||\n              $lisVisible.eq(index + 1).hasClass('divider'))) {\n              $this.addClass('hidden');\n            }\n          });\n\n          if (!that.$lis.not('.hidden, .no-results').length) {\n            if (!!$no_results.parent().length) {\n              $no_results.remove();\n            }\n            $no_results.html(that.options.noneResultsText.replace('{0}', '\"' + htmlEscape(that.$searchbox.val()) + '\"')).show();\n            that.$menuInner.append($no_results);\n          } else if (!!$no_results.parent().length) {\n            $no_results.remove();\n          }\n\n        } else {\n          that.$lis.not('.is-hidden').removeClass('hidden');\n          if (!!$no_results.parent().length) {\n            $no_results.remove();\n          }\n        }\n\n        that.$lis.filter('.active').removeClass('active');\n        if (that.$searchbox.val()) that.$lis.not('.hidden, .divider, .dropdown-header').eq(0).addClass('active').children('a').focus();\n        $(this).focus();\n      });\n    },\n\n    _searchStyle: function () {\n      var style = 'icontains';\n      switch (this.options.liveSearchStyle) {\n        case 'begins':\n        case 'startsWith':\n          style = 'ibegins';\n          break;\n        case 'contains':\n        default:\n          break; //no need to change the default\n      }\n\n      return style;\n    },\n\n    val: function (value) {\n      if (typeof value !== 'undefined') {\n        this.$element.val(value);\n        this.render();\n\n        return this.$element;\n      } else {\n        return this.$element.val();\n      }\n    },\n\n    selectAll: function () {\n      this.findLis();\n      this.$element.find('option:enabled').not('[data-divider], [data-hidden]').prop('selected', true);\n      this.$lis.not('.divider, .dropdown-header, .disabled, .hidden').addClass('selected');\n      this.render(false);\n    },\n\n    deselectAll: function () {\n      this.findLis();\n      this.$element.find('option:enabled').not('[data-divider], [data-hidden]').prop('selected', false);\n      this.$lis.not('.divider, .dropdown-header, .disabled, .hidden').removeClass('selected');\n      this.render(false);\n    },\n\n    keydown: function (e) {\n      var $this = $(this),\n          $parent = $this.is('input') ? $this.parent().parent() : $this.parent(),\n          $items,\n          that = $parent.data('this'),\n          index,\n          next,\n          first,\n          last,\n          prev,\n          nextPrev,\n          prevIndex,\n          isActive,\n          selector = ':not(.disabled, .hidden, .dropdown-header, .divider)',\n          keyCodeMap = {\n            32: ' ',\n            48: '0',\n            49: '1',\n            50: '2',\n            51: '3',\n            52: '4',\n            53: '5',\n            54: '6',\n            55: '7',\n            56: '8',\n            57: '9',\n            59: ';',\n            65: 'a',\n            66: 'b',\n            67: 'c',\n            68: 'd',\n            69: 'e',\n            70: 'f',\n            71: 'g',\n            72: 'h',\n            73: 'i',\n            74: 'j',\n            75: 'k',\n            76: 'l',\n            77: 'm',\n            78: 'n',\n            79: 'o',\n            80: 'p',\n            81: 'q',\n            82: 'r',\n            83: 's',\n            84: 't',\n            85: 'u',\n            86: 'v',\n            87: 'w',\n            88: 'x',\n            89: 'y',\n            90: 'z',\n            96: '0',\n            97: '1',\n            98: '2',\n            99: '3',\n            100: '4',\n            101: '5',\n            102: '6',\n            103: '7',\n            104: '8',\n            105: '9'\n          };\n\n      if (that.options.liveSearch) $parent = $this.parent().parent();\n\n      if (that.options.container) $parent = that.$menu;\n\n      $items = $('[role=menu] li a', $parent);\n\n      isActive = that.$menu.parent().hasClass('open');\n\n      if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 65 && e.keyCode <= 90)) {\n        if (!that.options.container) {\n          that.setSize();\n          that.$menu.parent().addClass('open');\n          isActive = true;\n        } else {\n          that.$newElement.trigger('click');\n        }\n        that.$searchbox.focus();\n      }\n\n      if (that.options.liveSearch) {\n        if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && that.$menu.find('.active').length === 0) {\n          e.preventDefault();\n          that.$menu.parent().removeClass('open');\n          if (that.options.container) that.$newElement.removeClass('open');\n          that.$button.focus();\n        }\n        // $items contains li elements when liveSearch is enabled\n        $items = $('[role=menu] li:not(.disabled, .hidden, .dropdown-header, .divider)', $parent);\n        if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) {\n          if ($items.filter('.active').length === 0) {\n            $items = that.$newElement.find('li');\n            if (that.options.liveSearchNormalize) {\n              $items = $items.filter(':a' + that._searchStyle() + '(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');\n            } else {\n              $items = $items.filter(':' + that._searchStyle() + '(' + keyCodeMap[e.keyCode] + ')');\n            }\n          }\n        }\n      }\n\n      if (!$items.length) return;\n\n      if (/(38|40)/.test(e.keyCode.toString(10))) {\n        index = $items.index($items.filter(':focus'));\n        first = $items.parent(selector).first().data('originalIndex');\n        last = $items.parent(selector).last().data('originalIndex');\n        next = $items.eq(index).parent().nextAll(selector).eq(0).data('originalIndex');\n        prev = $items.eq(index).parent().prevAll(selector).eq(0).data('originalIndex');\n        nextPrev = $items.eq(next).parent().prevAll(selector).eq(0).data('originalIndex');\n\n        if (that.options.liveSearch) {\n          $items.each(function (i) {\n            if (!$(this).hasClass('disabled')) {\n              $(this).data('index', i);\n            }\n          });\n          index = $items.index($items.filter('.active'));\n          first = $items.first().data('index');\n          last = $items.last().data('index');\n          next = $items.eq(index).nextAll().eq(0).data('index');\n          prev = $items.eq(index).prevAll().eq(0).data('index');\n          nextPrev = $items.eq(next).prevAll().eq(0).data('index');\n        }\n\n        prevIndex = $this.data('prevIndex');\n\n        if (e.keyCode == 38) {\n          if (that.options.liveSearch) index -= 1;\n          if (index != nextPrev && index > prev) index = prev;\n          if (index < first) index = first;\n          if (index == prevIndex) index = last;\n        } else if (e.keyCode == 40) {\n          if (that.options.liveSearch) index += 1;\n          if (index == -1) index = 0;\n          if (index != nextPrev && index < next) index = next;\n          if (index > last) index = last;\n          if (index == prevIndex) index = first;\n        }\n\n        $this.data('prevIndex', index);\n\n        if (!that.options.liveSearch) {\n          $items.eq(index).focus();\n        } else {\n          e.preventDefault();\n          if (!$this.hasClass('dropdown-toggle')) {\n            $items.removeClass('active').eq(index).addClass('active').children('a').focus();\n            $this.focus();\n          }\n        }\n\n      } else if (!$this.is('input')) {\n        var keyIndex = [],\n            count,\n            prevKey;\n\n        $items.each(function () {\n          if (!$(this).parent().hasClass('disabled')) {\n            if ($.trim($(this).text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {\n              keyIndex.push($(this).parent().index());\n            }\n          }\n        });\n\n        count = $(document).data('keycount');\n        count++;\n        $(document).data('keycount', count);\n\n        prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);\n\n        if (prevKey != keyCodeMap[e.keyCode]) {\n          count = 1;\n          $(document).data('keycount', count);\n        } else if (count >= keyIndex.length) {\n          $(document).data('keycount', 0);\n          if (count > keyIndex.length) count = 1;\n        }\n\n        $items.eq(keyIndex[count - 1]).focus();\n      }\n\n      // Select focused option if \"Enter\", \"Spacebar\" or \"Tab\" (when selectOnTab is true) are pressed inside the menu.\n      if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {\n        if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();\n        if (!that.options.liveSearch) {\n          var elem = $(':focus');\n          elem.click();\n          // Bring back focus for multiselects\n          elem.focus();\n          // Prevent screen from scrolling if the user hit the spacebar\n          e.preventDefault();\n          // Fixes spacebar selection of dropdown items in FF & IE\n          $(document).data('spaceSelect', true);\n        } else if (!/(32)/.test(e.keyCode.toString(10))) {\n          that.$menu.find('.active a').click();\n          $this.focus();\n        }\n        $(document).data('keycount', 0);\n      }\n\n      if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {\n        that.$menu.parent().removeClass('open');\n        if (that.options.container) that.$newElement.removeClass('open');\n        that.$button.focus();\n      }\n    },\n\n    mobile: function () {\n      this.$element.addClass('mobile-device').appendTo(this.$newElement);\n      if (this.options.container) this.$menu.hide();\n    },\n\n    refresh: function () {\n      this.$lis = null;\n      this.liObj = {};\n      this.reloadLi();\n      this.render();\n      this.checkDisabled();\n      this.liHeight(true);\n      this.setStyle();\n      this.setWidth();\n      if (this.$lis) this.$searchbox.trigger('propertychange');\n\n      this.$element.trigger('refreshed.bs.select');\n    },\n\n    hide: function () {\n      this.$newElement.hide();\n    },\n\n    show: function () {\n      this.$newElement.show();\n    },\n\n    remove: function () {\n      this.$newElement.remove();\n      this.$element.remove();\n    }\n  };\n\n  // SELECTPICKER PLUGIN DEFINITION\n  // ==============================\n  function Plugin(option, event) {\n    // get the args of the outer function..\n    var args = arguments;\n    // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them\n    // to get lost/corrupted in android 2.3 and IE9 #715 #775\n    var _option = option,\n        _event = event;\n    [].shift.apply(args);\n\n    var value;\n    var chain = this.each(function () {\n      var $this = $(this);\n      if ($this.is('select')) {\n        var data = $this.data('selectpicker'),\n            options = typeof _option == 'object' && _option;\n\n        if (!data) {\n          var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);\n          $this.data('selectpicker', (data = new Selectpicker(this, config, _event)));\n        } else if (options) {\n          for (var i in options) {\n            if (options.hasOwnProperty(i)) {\n              data.options[i] = options[i];\n            }\n          }\n        }\n\n        if (typeof _option == 'string') {\n          if (data[_option] instanceof Function) {\n            value = data[_option].apply(data, args);\n          } else {\n            value = data.options[_option];\n          }\n        }\n      }\n    });\n\n    if (typeof value !== 'undefined') {\n      //noinspection JSUnusedAssignment\n      return value;\n    } else {\n      return chain;\n    }\n  }\n\n  var old = $.fn.selectpicker;\n  $.fn.selectpicker = Plugin;\n  $.fn.selectpicker.Constructor = Selectpicker;\n\n  // SELECTPICKER NO CONFLICT\n  // ========================\n  $.fn.selectpicker.noConflict = function () {\n    $.fn.selectpicker = old;\n    return this;\n  };\n\n  $(document)\n      .data('keycount', 0)\n      .on('keydown', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"menu\"], .bs-searchbox input', Selectpicker.prototype.keydown)\n      .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"menu\"], .bs-searchbox input', function (e) {\n        e.stopPropagation();\n      });\n\n  // SELECTPICKER DATA-API\n  // =====================\n  $(window).on('load.bs.select.data-api', function () {\n    $('.selectpicker').each(function () {\n      var $selectpicker = $(this);\n      Plugin.call($selectpicker, $selectpicker.data());\n    })\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-bg_BG.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: BG (Bulgaria)\n * Region: BG (Bulgaria)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нищо избрано',\n    noneResultsText: 'Няма резултат за {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} избран елемент\" : \"{0} избрани елемента\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Лимита е достигнат ({n} елемент максимум)' : 'Лимита е достигнат ({n} елемента максимум)',\n        (numGroup == 1) ? 'Груповия лимит е достигнат ({n} елемент максимум)' : 'Груповия лимит е достигнат ({n} елемента максимум)'\n      ];\n    },\n    selectAllText: 'Избери всички',\n    deselectAllText: 'Размаркирай всички',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-cs_CZ.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: CS\n * Region: CZ (Czech Republic)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic není vybráno',\n    noneResultsText: 'Žádné výsledky {0}',\n    countSelectedText: 'Označeno {0} z {1}',\n    maxOptionsText: ['Limit překročen ({n} {var} max)', 'Limit skupiny překročen ({n} {var} max)', ['položek', 'položka']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-da_DK.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: DA (Danish)\n * Region: DK (Denmark)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Intet valgt',\n    noneResultsText: 'Ingen resultater fundet {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valgt\" : \"{0} valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Begrænsning nået (max {n} valgt)' : 'Begrænsning nået (max {n} valgte)',\n        (numGroup == 1) ? 'Gruppe-begrænsning nået (max {n} valgt)' : 'Gruppe-begrænsning nået (max {n} valgte)'\n      ];\n    },\n    selectAllText: 'Markér alle',\n    deselectAllText: 'Afmarkér alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-de_DE.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: DE (German, deutsch)\n * Region: DE (Germany, Deutschland)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Bitte wählen...',\n    noneResultsText: 'Keine Ergebnisse für {0}',\n    countSelectedText: '{0} von {1} ausgewählt',\n    maxOptionsText: ['Limit erreicht ({n} {var} max.)', 'Gruppen-Limit erreicht ({n} {var} max.)', ['Eintrag', 'Einträge']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-en_US.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: EN (English)\n * Region: US (United States)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results match {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-es_CL.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: ES (Spanish)\n * Region: CL (Chile)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-eu.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: EU (Basque)\n * Region: \n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hautapenik ez',\n    noneResultsText: 'Emaitzarik ez {0}',\n    countSelectedText: '{1}(e)tik {0} hautatuta',\n    maxOptionsText: ['Mugara iritsita ({n} {var} gehienez)', 'Taldearen mugara iritsita ({n} {var} gehienez)', ['elementu', 'elementu']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-fa_IR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: FA (Farsi)\n * Region: IR (Iran)\n */\n(function ($) {\n    $.fn.selectpicker.defaults = {\n        noneSelectedText: 'چیزی انتخاب نشده است',\n        noneResultsText: 'هیج مشابهی برای {0} پیدا نشد',\n        countSelectedText: \"{0} از {1} مورد انتخاب شده\",\n        maxOptionsText: ['بیشتر ممکن نیست {حداکثر {n} عدد}', 'بیشتر ممکن نیست {حداکثر {n} عدد}'],\n        selectAllText: 'انتخاب همه',\n        deselectAllText: 'انتخاب هیچ کدام',\n        multipleSeparator: ', '\n    };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-fr_FR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: FR (French; Français)\n * Region: FR (France)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Aucune s&eacute;lection',\n    noneResultsText: 'Aucun r&eacute;sultat pour {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected > 1) ? \"{0} &eacute;l&eacute;ments s&eacute;lectionn&eacute;s\" : \"{0} &eacute;l&eacute;ment s&eacute;lectionn&eacute;\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll > 1) ? 'Limite atteinte ({n} &eacute;l&eacute;ments max)' : 'Limite atteinte ({n} &eacute;l&eacute;ment max)',\n        (numGroup > 1) ? 'Limite du groupe atteinte ({n} &eacute;l&eacute;ments max)' : 'Limite du groupe atteinte ({n} &eacute;l&eacute;ment max)'\n      ];\n    },\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-hu_HU.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: HU (Hungarian)\n * Region: HU (Hungary)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Válasszon!',\n    noneResultsText: 'Nincs találat {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return '{n} elem kiválasztva';\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Legfeljebb {n} elem választható',\n        'A csoportban legfeljebb {n} elem választható'\n      ];\n    },\n    selectAllText: 'Mind',\n    deselectAllText: 'Egyik sem',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-it_IT.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: IT (Italian; italiano)\n * Region: IT (Italy; Italia)\n * Author: Michele Beltrame <mb@cattlegrid.info>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nessuna selezione',\n    noneResultsText: 'Nessun risultato per {0}',\n    countSelectedText: 'Selezionati {0} di {1}',\n    maxOptionsText: ['Limite raggiunto ({n} {var} max)', 'Limite del gruppo raggiunto ({n} {var} max)', ['elementi', 'elemento']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-ko_KR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: KO (Korean)\n * Region: KR (South Korea)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '항목을 선택해주세요',\n    noneResultsText: '{0} 검색 결과가 없습니다',\n    countSelectedText: function (numSelected, numTotal) {\n      return \"{0}개를 선택하였습니다\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        '{n}개까지 선택 가능합니다',\n        '해당 그룹은 {n}개까지 선택 가능합니다'\n      ];\n    },\n    selectAllText: '전체선택',\n    deselectAllText: '전체해제',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-nl_NL.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: NL (Dutch; Nederlands)\n * Region: NL (Europe)\n * Author: Daan Rosbergen (Badmuts)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niets geselecteerd',\n    noneResultsText: 'Geen resultaten gevonden voor {0}',\n    countSelectedText: '{0} van {1} geselecteerd',\n    maxOptionsText: ['Limiet bereikt ({n} {var} max)', 'Groep limiet bereikt ({n} {var} max)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-pl_PL.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: PL (Polish)\n * Region: EU (Europe)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic nie zaznaczono',\n    noneResultsText: 'Brak wyników wyszukiwania {0}',\n    countSelectedText: 'Zaznaczono {0} z {1}',\n    maxOptionsText: ['Osiągnięto limit ({n} {var} max)', 'Limit grupy osiągnięty ({n} {var} max)', ['elementy', 'element']],\n    selectAll: 'Zaznacz wszystkie',\n    deselectAll: 'Odznacz wszystkie',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-pt_BR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: PT (Portuguese; português)\n * Region: BR (Brazil; Brasil)\n * Author: Rodrigo de Avila <rodrigo@avila.net.br>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nada selecionado',\n    noneResultsText: 'Nada encontrado contendo {0}',\n    countSelectedText: 'Selecionado {0} de {1}',\n    maxOptionsText: ['Limite excedido (máx. {n} {var})', 'Limite do grupo excedido (máx. {n} {var})', ['itens', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-pt_PT.js",
    "content": "/*\n* Translated default messages for bootstrap-select.\n* Locale: PT (Portuguese; português)\n* Region: PT (Portugal; Portugal)\n* Author: Burnspirit <burnspirit@gmail.com>\n*/\n(function ($) {\n$.fn.selectpicker.defaults = {\nnoneSelectedText: 'Nenhum seleccionado',\nnoneResultsText: 'Sem resultados contendo {0}',\ncountSelectedText: 'Selecionado {0} de {1}',\nmaxOptionsText: ['Limite ultrapassado (máx. {n} {var})', 'Limite de seleções ultrapassado (máx. {n} {var})', ['itens', 'item']],\nmultipleSeparator: ', '\n};\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-ro_RO.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: RO (Romanian)\n * Region: RO (Romania)\n * Alex Florea <alecz.fia@gmail.com>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nu a fost selectat nimic',\n    noneResultsText: 'Nu exista niciun rezultat {0}',\n    countSelectedText: '{0} din {1} selectat(e)',\n    maxOptionsText: ['Limita a fost atinsa ({n} {var} max)', 'Limita de grup a fost atinsa ({n} {var} max)', ['iteme', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-ru_RU.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: RU (Russian; Русский)\n * Region: RU (Russian Federation)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ничего не выбрано',\n    noneResultsText: 'Совпадений не найдено {0}',\n    countSelectedText: 'Выбрано {0} из {1}',\n    maxOptionsText: ['Достигнут предел ({n} {var} максимум)', 'Достигнут предел в группе ({n} {var} максимум)', ['items', 'item']],\n    doneButtonText: 'Закрыть',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-sk_SK.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: SK\n * Region: SK (Slovak Republic)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Vyberte zo zoznamu',\n    noneResultsText: 'Pre výraz {0} neboli nájdené žiadne výsledky',\n    countSelectedText: 'Vybrané {0} z {1}',\n    maxOptionsText: ['Limit prekročený ({n} {var} max)', 'Limit skupiny prekročený ({n} {var} max)', ['položiek', 'položka']],\n    selectAllText: 'Vybrať všetky',\n    deselectAllText: 'Zrušiť výber',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-sl_SI.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: SL (Slovenian)\n * Region: SI (Slovenia)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nič izbranega',\n    noneResultsText: 'Ni zadetkov za {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      \"Število izbranih: {0}\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Omejitev dosežena (max. izbranih: {n})',\n        'Omejitev skupine dosežena (max. izbranih: {n})'\n      ];\n    },\n    selectAllText: 'Izberi vse',\n    deselectAllText: 'Počisti izbor',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-sv_SE.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: SV (Swedish)\n * Region: SE (Sweden)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Inget valt',\n    noneResultsText: 'Inget sökresultat matchar {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected === 1) ? \"{0} alternativ valt\" : \"{0} alternativ valda\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Gräns uppnåd (max {n} alternativ)',\n        'Gräns uppnåd (max {n} gruppalternativ)'\n      ];\n    },\n    selectAllText: 'Markera alla',\n    deselectAllText: 'Avmarkera alla',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-tr_TR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: TR (Turkey)\n * Region: TR (Europe)\n * Author: Serhan Güney\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hiçbiri seçilmedi',\n    noneResultsText: 'Hiçbir sonuç bulunamadı {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} öğe seçildi\" : \"{0} öğe seçildi\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit aşıldı (maksimum {n} sayıda öğe )' : 'Limit aşıldı (maksimum {n} sayıda öğe)',\n        (numGroup == 1) ? 'Grup limiti aşıldı (maksimum {n} sayıda öğe)' : 'Grup limiti aşıldı (maksimum {n} sayıda öğe)'\n      ];\n    },\n    selectAllText: 'Tümünü Seç',\n    deselectAllText: 'Seçiniz',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-ua_UA.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: UA (Ukrainian; Українська)\n * Region: UA (Ukraine)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нічого не вибрано',\n    noneResultsText: 'Збігів не знайдено {0}',\n    countSelectedText: 'Вибрано {0} із {1}',\n    maxOptionsText: ['Досягнута межа ({n} {var} максимум)', 'Досягнута межа в групі ({n} {var} максимум)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-zh_CN.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: ZH (Chinese)\n * Region: CN (China)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '没有选中任何项',\n    noneResultsText: '没有找到匹配项',\n    countSelectedText: '选中{1}中的{0}项',\n    maxOptionsText: ['超出限制 (最多选择{n}项)', '组选择超出限制(最多选择{n}组)'],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-select/js/i18n/defaults-zh_TW.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: ZH (Chinese)\n * Region: TW (Taiwan)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '沒有選取任何項目',\n    noneResultsText: '沒有找到符合的結果',\n    countSelectedText: '已經選取{0}個項目',\n    maxOptionsText: ['超過限制 (最多選擇{n}項)', '超過限制(最多選擇{n}組)'],\n    selectAllText: '選取全部',\n    deselectAllText: '全部取消',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/bootstrap-table-all.js",
    "content": "/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * version: 1.8.1\n * https://github.com/wenzhixin/bootstrap-table/\n */\n\n!function ($) {\n    'use strict';\n\n    // TOOLS DEFINITION\n    // ======================\n\n    var cellHeight = 37, // update css if changed\n        cachedWidth = null,\n        arrowAsc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ' +\n        '0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBd' +\n        'qEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVo' +\n        'AADeemwtPcZI2wAAAABJRU5ErkJggg==',\n        arrowBoth = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X' +\n        'QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azio' +\n        'NZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4eut' +\n        's6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC',\n        arrowDesc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWj' +\n        'YBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJ' +\n        'zcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= ';\n\n    // it only does '%s', and return '' when arguments are undefined\n    var sprintf = function (str) {\n        var args = arguments,\n            flag = true,\n            i = 1;\n\n        str = str.replace(/%s/g, function () {\n            var arg = args[i++];\n\n            if (typeof arg === 'undefined') {\n                flag = false;\n                return '';\n            }\n            return arg;\n        });\n        return flag ? str : '';\n    };\n\n    var getPropertyFromOther = function (list, from, to, value) {\n        var result = '';\n        $.each(list, function (i, item) {\n            if (item[from] === value) {\n                result = item[to];\n                return false;\n            }\n            return true;\n        });\n        return result;\n    };\n\n    var getFieldIndex = function (columns, field) {\n        var index = -1;\n\n        $.each(columns, function (i, column) {\n            if (column.field === field) {\n                index = i;\n                return false;\n            }\n            return true;\n        });\n        return index;\n    };\n\n    var getScrollBarWidth = function () {\n        if (cachedWidth === null) {\n            var inner = $('<p/>').addClass('fixed-table-scroll-inner'),\n                outer = $('<div/>').addClass('fixed-table-scroll-outer'),\n                w1, w2;\n\n            outer.append(inner);\n            $('body').append(outer);\n\n            w1 = inner[0].offsetWidth;\n            outer.css('overflow', 'scroll');\n            w2 = inner[0].offsetWidth;\n\n            if (w1 === w2) {\n                w2 = outer[0].clientWidth;\n            }\n\n            outer.remove();\n            cachedWidth = w1 - w2;\n        }\n        return cachedWidth;\n    };\n\n    var calculateObjectValue = function (self, name, args, defaultValue) {\n        var func = name;\n\n        if (typeof name === 'string') {\n            // support obj.func1.func2\n            var names = name.split('.');\n\n            if (names.length > 1) {\n                func = window;\n                $.each(names, function (i, f) {\n                    func = func[f];\n                });\n            } else {\n                func = window[name];\n            }\n        }\n        if (typeof func === 'object') {\n            return func;\n        }\n        if (typeof func === 'function') {\n            return func.apply(self, args);\n        }\n        if (!func && typeof name === 'string' && sprintf.apply(this, [name].concat(args))) {\n            return sprintf.apply(this, [name].concat(args));\n        }\n        return defaultValue;\n    };\n\n    var escapeHTML = function (text) {\n        if (typeof text === 'string') {\n            return text\n                .replace(/&/g, \"&amp;\")\n                .replace(/</g, \"&lt;\")\n                .replace(/>/g, \"&gt;\")\n                .replace(/\"/g, \"&quot;\")\n                .replace(/'/g, \"&#039;\");\n        }\n        return text;\n    };\n\n    var getRealHeight = function ($el) {\n        var height = 0;\n        $el.children().each(function () {\n            if (height < $(this).outerHeight(true)) {\n                height = $(this).outerHeight(true);\n            }\n        });\n        return height;\n    };\n\n    var getRealDataAttr = function (dataAttr) {\n        for (var attr in dataAttr) {\n            var auxAttr = attr.split(/(?=[A-Z])/).join('-').toLowerCase();\n            if (auxAttr !== attr) {\n                dataAttr[auxAttr] = dataAttr[attr];\n                delete dataAttr[attr];\n            }\n        }\n\n        return dataAttr;\n    };\n\n    // BOOTSTRAP TABLE CLASS DEFINITION\n    // ======================\n\n    var BootstrapTable = function (el, options) {\n        this.options = options;\n        this.$el = $(el);\n        this.$el_ = this.$el.clone();\n        this.timeoutId_ = 0;\n        this.timeoutFooter_ = 0;\n\n        this.init();\n    };\n\n    BootstrapTable.DEFAULTS = {\n        classes: 'table table-hover',\n        height: undefined,\n        undefinedText: '-',\n        sortName: undefined,\n        sortOrder: 'asc',\n        striped: false,\n        columns: [],\n        data: [],\n        method: 'get',\n        url: undefined,\n        ajax: undefined,\n        cache: true,\n        contentType: 'application/json',\n        dataType: 'json',\n        ajaxOptions: {},\n        queryParams: function (params) {\n            return params;\n        },\n        queryParamsType: 'limit', // undefined\n        responseHandler: function (res) {\n            return res;\n        },\n        pagination: false,\n        sidePagination: 'client', // client or server\n        totalRows: 0, // server side need to set\n        pageNumber: 1,\n        pageSize: 10,\n        pageList: [10, 25, 50, 100],\n        paginationHAlign: 'right', //right, left\n        paginationVAlign: 'bottom', //bottom, top, both\n        paginationDetailHAlign: 'left', //right, left\n        paginationFirstText: '&laquo;',\n        paginationPreText: '&lsaquo;',\n        paginationNextText: '&rsaquo;',\n        paginationLastText: '&raquo;',\n        search: false,\n        searchAlign: 'right',\n        selectItemName: 'btSelectItem',\n        showHeader: true,\n        showFooter: false,\n        showColumns: false,\n        showPaginationSwitch: false,\n        showRefresh: false,\n        showToggle: false,\n        buttonsAlign: 'right',\n        smartDisplay: true,\n        minimumCountColumns: 1,\n        idField: undefined,\n        uniqueId: undefined,\n        cardView: false,\n        detailView: false,\n        detailFormatter: function (index, row) {\n            return '';\n        },\n        trimOnSearch: true,\n        clickToSelect: false,\n        singleSelect: false,\n        toolbar: undefined,\n        toolbarAlign: 'left',\n        checkboxHeader: true,\n        sortable: true,\n        maintainSelected: false,\n        searchTimeOut: 500,\n        searchText: '',\n        iconSize: undefined,\n        iconsPrefix: 'glyphicon', // glyphicon of fa (font awesome)\n        icons: {\n            paginationSwitchDown: 'glyphicon-collapse-down icon-chevron-down',\n            paginationSwitchUp: 'glyphicon-collapse-up icon-chevron-up',\n            refresh: 'glyphicon-refresh icon-refresh',\n            toggle: 'glyphicon-list-alt icon-list-alt',\n            columns: 'glyphicon-th icon-th'\n        },\n\n        rowStyle: function (row, index) {\n            return {};\n        },\n\n        rowAttributes: function (row, index) {\n            return {};\n        },\n\n        onAll: function (name, args) {\n            return false;\n        },\n        onClickCell: function (field, value, row, $element) {\n            return false;\n        },\n        onDblClickCell: function (field, value, row, $element) {\n            return false;\n        },\n        onClickRow: function (item, $element) {\n            return false;\n        },\n        onDblClickRow: function (item, $element) {\n            return false;\n        },\n        onSort: function (name, order) {\n            return false;\n        },\n        onCheck: function (row) {\n            return false;\n        },\n        onUncheck: function (row) {\n            return false;\n        },\n        onCheckAll: function (rows) {\n            return false;\n        },\n        onUncheckAll: function (rows) {\n            return false;\n        },\n        onCheckSome: function(rows){\n            return false;\n        },\n        onUncheckSome: function(rows){\n            return false;\n        },\n        onLoadSuccess: function (data) {\n            return false;\n        },\n        onLoadError: function (status) {\n            return false;\n        },\n        onColumnSwitch: function (field, checked) {\n            return false;\n        },\n        onPageChange: function (number, size) {\n            return false;\n        },\n        onSearch: function (text) {\n            return false;\n        },\n        onToggle: function (cardView) {\n            return false;\n        },\n        onPreBody: function (data) {\n            return false;\n        },\n        onPostBody: function () {\n            return false;\n        },\n        onPostHeader: function () {\n            return false;\n        },\n        onExpandRow: function (index, row, $detail) {\n            return false;\n        },\n        onCollapseRow: function (index, row) {\n            return false;\n        }\n    };\n\n    BootstrapTable.LOCALES = [];\n\n    BootstrapTable.LOCALES['en-US'] = {\n        formatLoadingMessage: function () {\n            return 'Loading, please wait...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return sprintf('%s records per page', pageNumber);\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return sprintf('Showing %s to %s of %s rows', pageFrom, pageTo, totalRows);\n        },\n        formatSearch: function () {\n            return 'Search';\n        },\n        formatNoMatches: function () {\n            return 'No matching records found';\n        },\n        formatPaginationSwitch: function () {\n            return 'Hide/Show pagination';\n        },\n        formatRefresh: function () {\n            return 'Refresh';\n        },\n        formatToggle: function () {\n            return 'Toggle';\n        },\n        formatColumns: function () {\n            return 'Columns';\n        },\n        formatAllRows: function () {\n            return 'All';\n        }\n    };\n\n    $.extend(BootstrapTable.DEFAULTS, BootstrapTable.LOCALES['en-US']);\n\n    BootstrapTable.COLUMN_DEFAULTS = {\n        radio: false,\n        checkbox: false,\n        checkboxEnabled: true,\n        field: undefined,\n        title: undefined,\n        'class': undefined,\n        align: undefined, // left, right, center\n        halign: undefined, // left, right, center\n        falign: undefined, // left, right, center\n        valign: undefined, // top, middle, bottom\n        width: undefined,\n        sortable: false,\n        order: 'asc', // asc, desc\n        visible: true,\n        switchable: true,\n        clickToSelect: true,\n        formatter: undefined,\n        footerFormatter: undefined,\n        events: undefined,\n        sorter: undefined,\n        sortName: undefined,\n        cellStyle: undefined,\n        searchable: true,\n        cardVisible: true\n    };\n\n    BootstrapTable.EVENTS = {\n        'all.bs.table': 'onAll',\n        'click-cell.bs.table': 'onClickCell',\n        'dbl-click-cell.bs.table': 'onDblClickCell',\n        'click-row.bs.table': 'onClickRow',\n        'dbl-click-row.bs.table': 'onDblClickRow',\n        'sort.bs.table': 'onSort',\n        'check.bs.table': 'onCheck',\n        'uncheck.bs.table': 'onUncheck',\n        'check-all.bs.table': 'onCheckAll',\n        'uncheck-all.bs.table': 'onUncheckAll',\n        'check-some.bs.table': 'onCheckSome',\n        'uncheck-some.bs.table': 'onUncheckSome',\n        'load-success.bs.table': 'onLoadSuccess',\n        'load-error.bs.table': 'onLoadError',\n        'column-switch.bs.table': 'onColumnSwitch',\n        'page-change.bs.table': 'onPageChange',\n        'search.bs.table': 'onSearch',\n        'toggle.bs.table': 'onToggle',\n        'pre-body.bs.table': 'onPreBody',\n        'post-body.bs.table': 'onPostBody',\n        'post-header.bs.table': 'onPostHeader',\n        'expand-row.bs.table': 'onExpandRow',\n        'collapse-row.bs.table': 'onCollapseRow'\n    };\n\n    BootstrapTable.prototype.init = function () {\n        this.initContainer();\n        this.initTable();\n        this.initHeader();\n        this.initData();\n        this.initFooter();\n        this.initToolbar();\n        this.initPagination();\n        this.initBody();\n        this.initServer();\n    };\n\n    BootstrapTable.prototype.initContainer = function () {\n        this.$container = $([\n            '<div class=\"bootstrap-table\">',\n            '<div class=\"fixed-table-toolbar\"></div>',\n            this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ?\n                '<div class=\"fixed-table-pagination\" style=\"clear: both;\"></div>' :\n                '',\n            '<div class=\"fixed-table-container\">',\n            '<div class=\"fixed-table-header\"><table></table></div>',\n            '<div class=\"fixed-table-body\">',\n            '<div class=\"fixed-table-loading\">',\n            this.options.formatLoadingMessage(),\n            '</div>',\n            '</div>',\n            '<div class=\"fixed-table-footer\"><table><tr></tr></table></div>',\n            this.options.paginationVAlign === 'bottom' || this.options.paginationVAlign === 'both' ?\n                '<div class=\"fixed-table-pagination\"></div>' :\n                '',\n            '</div>',\n            '</div>'].join(''));\n\n        this.$container.insertAfter(this.$el);\n        this.$tableContainer = this.$container.find('.fixed-table-container');\n        this.$tableHeader = this.$container.find('.fixed-table-header');\n        this.$tableBody = this.$container.find('.fixed-table-body');\n        this.$tableLoading = this.$container.find('.fixed-table-loading');\n        this.$tableFooter = this.$container.find('.fixed-table-footer');\n        this.$toolbar = this.$container.find('.fixed-table-toolbar');\n        this.$pagination = this.$container.find('.fixed-table-pagination');\n\n        this.$tableBody.append(this.$el);\n        this.$container.after('<div class=\"clearfix\"></div>');\n\n        this.$el.addClass(this.options.classes);\n        if (this.options.striped) {\n            this.$el.addClass('table-striped');\n        }\n        if ($.inArray('table-no-bordered', this.options.classes.split(' ')) !== -1) {\n            this.$tableContainer.addClass('table-no-bordered');\n        }\n    };\n\n    BootstrapTable.prototype.initTable = function () {\n        var that = this,\n            columns = [],\n            data = [];\n\n        this.$header = this.$el.find('thead');\n        if (!this.$header.length) {\n            this.$header = $('<thead></thead>').appendTo(this.$el);\n        }\n        if (!this.$header.find('tr').length) {\n            this.$header.append('<tr></tr>');\n        }\n        this.$header.find('th').each(function () {\n            var column = $.extend({}, {\n                title: $(this).html(),\n                'class': $(this).attr('class')\n            }, $(this).data());\n\n            columns.push(column);\n        });\n        this.options.columns = $.extend(true, [], columns, this.options.columns);\n        $.each(this.options.columns, function (i, column) {\n            that.options.columns[i] = $.extend({}, BootstrapTable.COLUMN_DEFAULTS,\n                {field: i}, column); // when field is undefined, use index instead\n        });\n\n        // if options.data is setting, do not process tbody data\n        if (this.options.data.length) {\n            return;\n        }\n\n        this.$el.find('tbody tr').each(function () {\n            var row = {};\n\n            // save tr's id, class and data-* attributes\n            row._id = $(this).attr('id');\n            row._class = $(this).attr('class');\n            row._data = getRealDataAttr($(this).data());\n\n            $(this).find('td').each(function (i) {\n                var field = that.options.columns[i].field;\n\n                row[field] = $(this).html();\n                // save td's id, class and data-* attributes\n                row['_' + field + '_id'] = $(this).attr('id');\n                row['_' + field + '_class'] = $(this).attr('class');\n                row['_' + field + '_rowspan'] = $(this).attr('rowspan');\n                row['_' + field + '_data'] = getRealDataAttr($(this).data());\n            });\n            data.push(row);\n        });\n        this.options.data = data;\n    };\n\n    BootstrapTable.prototype.initHeader = function () {\n        var that = this,\n            visibleColumns = [],\n            html = [],\n            timeoutId = 0;\n\n        this.header = {\n            fields: [],\n            styles: [],\n            classes: [],\n            formatters: [],\n            events: [],\n            sorters: [],\n            sortNames: [],\n            cellStyles: [],\n            clickToSelects: [],\n            searchables: []\n        };\n\n        if (!this.options.cardView && this.options.detailView) {\n            html.push('<th class=\"detail\"><div class=\"fht-cell\"></div></th>');\n            visibleColumns.push({});\n        }\n\n        $.each(this.options.columns, function (i, column) {\n            var text = '',\n                halign = '', // header align style\n                align = '', // body align style\n                style = '',\n                class_ = sprintf(' class=\"%s\"', column['class']),\n                order = that.options.sortOrder || column.order,\n                unitWidth = 'px',\n                width = column.width;\n\n            if (!column.visible) {\n                // Fix #229. Default Sort order is wrong\n                // if data-visible=\"false\" is set on the field referenced by data-sort-name.\n                if (column.field === that.options.sortName) {\n                    that.header.fields.push(column.field);\n                }\n                return;\n            }\n\n            if (that.options.cardView && (!column.cardVisible)) {\n                return;\n            }\n\n            if (column.width !== undefined && (!that.options.cardView)) {\n                if (typeof column.width === 'string') {\n                    if (column.width.indexOf('%') !== -1) {\n                        unitWidth = '%';\n                    }\n                }\n            }\n            if (column.width && typeof column.width === 'string') {\n                width = column.width.replace('%', '').replace('px', '');\n            }\n\n            halign = sprintf('text-align: %s; ', column.halign ? column.halign : column.align);\n            align = sprintf('text-align: %s; ', column.align);\n            style = sprintf('vertical-align: %s; ', column.valign);\n            style += sprintf('width: %s%s; ', column.checkbox || column.radio ? 36 : width, unitWidth);\n\n            visibleColumns.push(column);\n            that.header.fields.push(column.field);\n            that.header.styles.push(align + style);\n            that.header.classes.push(class_);\n            that.header.formatters.push(column.formatter);\n            that.header.events.push(column.events);\n            that.header.sorters.push(column.sorter);\n            that.header.sortNames.push(column.sortName);\n            that.header.cellStyles.push(column.cellStyle);\n            that.header.clickToSelects.push(column.clickToSelect);\n            that.header.searchables.push(column.searchable);\n\n            html.push('<th',\n                column.checkbox || column.radio ?\n                    sprintf(' class=\"bs-checkbox %s\"', column['class'] || '') :\n                    class_,\n                sprintf(' style=\"%s\"', halign + style),\n                '>');\n\n            html.push(sprintf('<div class=\"th-inner %s\">', that.options.sortable && column.sortable ?\n                'sortable' : ''));\n\n            text = column.title;\n\n            if (column.checkbox) {\n                if (!that.options.singleSelect && that.options.checkboxHeader) {\n                    text = '<input name=\"btSelectAll\" type=\"checkbox\" />';\n                }\n                that.header.stateField = column.field;\n            }\n            if (column.radio) {\n                text = '';\n                that.header.stateField = column.field;\n                that.options.singleSelect = true;\n            }\n\n            html.push(text);\n            html.push('</div>');\n            html.push('<div class=\"fht-cell\"></div>');\n            html.push('</div>');\n            html.push('</th>');\n        });\n\n        this.$header.find('tr').html(html.join(''));\n        this.$header.find('th').each(function (i) {\n            $(this).data(visibleColumns[i]);\n        });\n        this.$container.off('click', '.th-inner').on('click', '.th-inner', function (event) {\n            if (that.options.sortable && $(this).parent().data().sortable) {\n                that.onSort(event);\n            }\n        });\n\n        if (!this.options.showHeader || this.options.cardView) {\n            this.$header.hide();\n            this.$tableHeader.hide();\n            this.$tableLoading.css('top', 0);\n        } else {\n            this.$header.show();\n            this.$tableHeader.show();\n            this.$tableLoading.css('top', cellHeight + 'px');\n            // Assign the correct sortable arrow\n            this.getCaretHtml();\n        }\n\n        this.$selectAll = this.$header.find('[name=\"btSelectAll\"]');\n        this.$container.off('click', '[name=\"btSelectAll\"]')\n            .on('click', '[name=\"btSelectAll\"]', function () {\n                var checked = $(this).prop('checked');\n                that[checked ? 'checkAll' : 'uncheckAll']();\n            });\n    };\n\n    BootstrapTable.prototype.initFooter = function () {\n        if (!this.options.showFooter || this.options.cardView) {\n            this.$tableFooter.hide();\n        } else {\n            this.$tableFooter.show();\n        }\n    };\n\n    /**\n     * @param data\n     * @param type: append / prepend\n     */\n    BootstrapTable.prototype.initData = function (data, type) {\n        if (type === 'append') {\n            this.data = this.data.concat(data);\n        } else if (type === 'prepend') {\n            this.data = [].concat(data).concat(this.data);\n        } else {\n            this.data = data || this.options.data;\n        }\n\n        // Fix #839 Records deleted when adding new row on filtered table\n        if (type === 'append') {\n            this.options.data = this.options.data.concat(data);\n        } else if (type === 'prepend') {\n            this.options.data = [].concat(data).concat(this.options.data);\n        } else {\n            this.options.data = this.data;\n        }\n\n        if (this.options.sidePagination === 'server') {\n            return;\n        }\n        this.initSort();\n    };\n\n    BootstrapTable.prototype.initSort = function () {\n        var that = this,\n            name = this.options.sortName,\n            order = this.options.sortOrder === 'desc' ? -1 : 1,\n            index = $.inArray(this.options.sortName, this.header.fields);\n\n        if (index !== -1) {\n            this.data.sort(function (a, b) {\n                if (that.header.sortNames[index]) {\n                    name = that.header.sortNames[index];\n                }\n                var aa = a[name],\n                    bb = b[name],\n                    value = calculateObjectValue(that.header, that.header.sorters[index], [aa, bb]);\n\n                if (value !== undefined) {\n                    return order * value;\n                }\n\n                // Fix #161: undefined or null string sort bug.\n                if (aa === undefined || aa === null) {\n                    aa = '';\n                }\n                if (bb === undefined || bb === null) {\n                    bb = '';\n                }\n\n                // IF both values are numeric, do a numeric comparison\n                if ($.isNumeric(aa) && $.isNumeric(bb)) {\n                    // Convert numerical values form string to float.\n                    aa = parseFloat(aa);\n                    bb = parseFloat(bb);\n                    if (aa < bb) {\n                        return order * -1;\n                    }\n                    return order;\n                }\n\n                if (aa === bb) {\n                    return 0;\n                }\n\n                // If value is not a string, convert to string\n                if (typeof aa !== 'string') {\n                    aa = aa.toString();\n                }\n\n                if (aa.localeCompare(bb) === -1) {\n                    return order * -1;\n                }\n\n                return order;\n            });\n        }\n    };\n\n    BootstrapTable.prototype.onSort = function (event) {\n        var $this = $(event.currentTarget).parent(),\n            $this_ = this.$header.find('th').eq($this.index());\n\n        this.$header.add(this.$header_).find('span.order').remove();\n\n        if (this.options.sortName === $this.data('field')) {\n            this.options.sortOrder = this.options.sortOrder === 'asc' ? 'desc' : 'asc';\n        } else {\n            this.options.sortName = $this.data('field');\n            this.options.sortOrder = $this.data('order') === 'asc' ? 'desc' : 'asc';\n        }\n        this.trigger('sort', this.options.sortName, this.options.sortOrder);\n\n        $this.add($this_).data('order', this.options.sortOrder);\n\n        // Assign the correct sortable arrow\n        this.getCaretHtml();\n\n        if (this.options.sidePagination === 'server') {\n            this.initServer();\n            return;\n        }\n\n        this.initSort();\n        this.initBody();\n    };\n\n    BootstrapTable.prototype.initToolbar = function () {\n        var that = this,\n            html = [],\n            timeoutId = 0,\n            $keepOpen,\n            $search,\n            switchableCount = 0;\n\n        this.$toolbar.html('');\n\n        if (typeof this.options.toolbar === 'string') {\n            $(sprintf('<div class=\"bars pull-%s\"></div>', this.options.toolbarAlign))\n                .appendTo(this.$toolbar)\n                .append($(this.options.toolbar));\n        }\n\n        // showColumns, showToggle, showRefresh\n        html = [sprintf('<div class=\"columns columns-%s btn-group pull-%s\">',\n            this.options.buttonsAlign, this.options.buttonsAlign)];\n\n        if (typeof this.options.icons === 'string') {\n            this.options.icons = calculateObjectValue(null, this.options.icons);\n        }\n\n        if (this.options.showPaginationSwitch) {\n            html.push(sprintf('<button class=\"btn btn-default\" type=\"button\" name=\"paginationSwitch\" title=\"%s\">',\n                this.options.formatPaginationSwitch()),\n                sprintf('<i class=\"%s %s\"></i>', this.options.iconsPrefix, this.options.icons.paginationSwitchDown),\n                '</button>');\n        }\n\n        if (this.options.showRefresh) {\n            html.push(sprintf('<button class=\"btn btn-default' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + '\" type=\"button\" name=\"refresh\" title=\"%s\">',\n                this.options.formatRefresh()),\n                sprintf('<i class=\"%s %s\"></i>', this.options.iconsPrefix, this.options.icons.refresh),\n                '</button>');\n        }\n\n        if (this.options.showToggle) {\n            html.push(sprintf('<button class=\"btn btn-default' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + '\" type=\"button\" name=\"toggle\" title=\"%s\">',\n                this.options.formatToggle()),\n                sprintf('<i class=\"%s %s\"></i>', this.options.iconsPrefix, this.options.icons.toggle),\n                '</button>');\n        }\n\n        if (this.options.showColumns) {\n            html.push(sprintf('<div class=\"keep-open btn-group\" title=\"%s\">',\n                this.options.formatColumns()),\n                '<button type=\"button\" class=\"btn btn-default' + (this.options.iconSize == undefined ? '' : ' btn-' + this.options.iconSize) + ' dropdown-toggle\" data-toggle=\"dropdown\">',\n                sprintf('<i class=\"%s %s\"></i>', this.options.iconsPrefix, this.options.icons.columns),\n                ' <span class=\"caret\"></span>',\n                '</button>',\n                '<ul class=\"dropdown-menu\" role=\"menu\">');\n\n            $.each(this.options.columns, function (i, column) {\n                if (column.radio || column.checkbox) {\n                    return;\n                }\n\n                if (that.options.cardView && (!column.cardVisible)) {\n                    return;\n                }\n\n                var checked = column.visible ? ' checked=\"checked\"' : '';\n\n                if (column.switchable) {\n                    html.push(sprintf('<li>' +\n                        '<label><input type=\"checkbox\" data-field=\"%s\" value=\"%s\"%s> %s</label>' +\n                        '</li>', column.field, i, checked, column.title));\n                    switchableCount++;\n                }\n            });\n            html.push('</ul>',\n                '</div>');\n        }\n\n        html.push('</div>');\n\n        // Fix #188: this.showToolbar is for extentions\n        if (this.showToolbar || html.length > 2) {\n            this.$toolbar.append(html.join(''));\n        }\n\n        if (this.options.showPaginationSwitch) {\n            this.$toolbar.find('button[name=\"paginationSwitch\"]')\n                .off('click').on('click', $.proxy(this.togglePagination, this));\n        }\n\n        if (this.options.showRefresh) {\n            this.$toolbar.find('button[name=\"refresh\"]')\n                .off('click').on('click', $.proxy(this.refresh, this));\n        }\n\n        if (this.options.showToggle) {\n            this.$toolbar.find('button[name=\"toggle\"]')\n                .off('click').on('click', function () {\n                    that.toggleView();\n                });\n        }\n\n        if (this.options.showColumns) {\n            $keepOpen = this.$toolbar.find('.keep-open');\n\n            if (switchableCount <= this.options.minimumCountColumns) {\n                $keepOpen.find('input').prop('disabled', true);\n            }\n\n            $keepOpen.find('li').off('click').on('click', function (event) {\n                event.stopImmediatePropagation();\n            });\n            $keepOpen.find('input').off('click').on('click', function () {\n                var $this = $(this);\n\n                that.toggleColumn(getFieldIndex(that.options.columns, $(this).data('field')), $this.prop('checked'), false);\n                that.trigger('column-switch', $(this).data('field'), $this.prop('checked'));\n            });\n        }\n\n        if (this.options.search) {\n            html = [];\n            html.push(\n                '<div class=\"pull-' + this.options.searchAlign + ' search\">',\n                sprintf('<input class=\"form-control' + (this.options.iconSize === undefined ? '' : ' input-' + this.options.iconSize) + '\" type=\"text\" placeholder=\"%s\">',\n                    this.options.formatSearch()),\n                '</div>');\n\n            this.$toolbar.append(html.join(''));\n            $search = this.$toolbar.find('.search input');\n            $search.off('keyup drop').on('keyup drop', function (event) {\n                clearTimeout(timeoutId); // doesn't matter if it's 0\n                timeoutId = setTimeout(function () {\n                    that.onSearch(event);\n                }, that.options.searchTimeOut);\n            });\n\n            if (this.options.searchText !== '') {\n                $search.val(this.options.searchText);\n                clearTimeout(timeoutId); // doesn't matter if it's 0\n                timeoutId = setTimeout(function () {\n                    $search.trigger('keyup');\n                }, that.options.searchTimeOut);\n            }\n        }\n    };\n\n    BootstrapTable.prototype.onSearch = function (event) {\n        var text = $.trim($(event.currentTarget).val());\n\n        // trim search input\n        if (this.options.trimOnSearch && $(event.currentTarget).val() !== text) {\n            $(event.currentTarget).val(text);\n        }\n\n        if (text === this.searchText) {\n            return;\n        }\n        this.searchText = text;\n\n        this.options.pageNumber = 1;\n        this.initSearch();\n        this.updatePagination();\n        this.trigger('search', text);\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        var that = this;\n\n        if (this.options.sidePagination !== 'server') {\n            var s = this.searchText && this.searchText.toLowerCase();\n            var f = $.isEmptyObject(this.filterColumns) ? null : this.filterColumns;\n\n            // Check filter\n            this.data = f ? $.grep(this.options.data, function (item, i) {\n                for (var key in f) {\n                    if (item[key] !== f[key]) {\n                        return false;\n                    }\n                }\n                return true;\n            }) : this.options.data;\n\n            this.data = s ? $.grep(this.data, function (item, i) {\n                for (var key in item) {\n                    key = $.isNumeric(key) ? parseInt(key, 10) : key;\n                    var value = item[key],\n                        column = that.options.columns[getFieldIndex(that.options.columns, key)],\n                        j = $.inArray(key, that.header.fields);\n\n                    // Fix #142: search use formated data\n                    value = calculateObjectValue(column,\n                        that.header.formatters[j],\n                        [value, item, i], value);\n\n                    var index = $.inArray(key, that.header.fields);\n                    if (index !== -1 && that.header.searchables[index] &&\n                        (typeof value === 'string' ||\n                            typeof value === 'number') &&\n                        (value + '').toLowerCase().indexOf(s) !== -1) {\n                        return true;\n                    }\n                }\n                return false;\n            }) : this.data;\n        }\n    };\n\n    BootstrapTable.prototype.initPagination = function () {\n        if (!this.options.pagination) {\n            this.$pagination.hide();\n            return;\n        } else {\n            this.$pagination.show();\n        }\n\n        var that = this,\n            html = [],\n            $allSelected = false,\n            i, from, to,\n            $pageList,\n            $first, $pre,\n            $next, $last,\n            $number,\n            data = this.getData();\n\n        if (this.options.sidePagination !== 'server') {\n            this.options.totalRows = data.length;\n        }\n\n        this.totalPages = 0;\n        if (this.options.totalRows) {\n            if (this.options.pageSize === this.options.formatAllRows()) {\n                this.options.pageSize = this.options.totalRows;\n                $allSelected = true;\n            } else if (this.options.pageSize === this.options.totalRows) {\n                // Fix #667 Table with pagination, multiple pages and a search that matches to one page throws exception\n                var pageLst = typeof this.options.pageList === 'string' ?\n                    this.options.pageList.replace('[', '').replace(']', '').replace(/ /g, '').toLowerCase().split(',') :\n                    this.options.pageList;\n                if (pageLst.indexOf(this.options.formatAllRows().toLowerCase()) > -1) {\n                    $allSelected = true;\n                }\n            }\n\n            this.totalPages = ~~((this.options.totalRows - 1) / this.options.pageSize) + 1;\n\n            this.options.totalPages = this.totalPages;\n        }\n        if (this.totalPages > 0 && this.options.pageNumber > this.totalPages) {\n            this.options.pageNumber = this.totalPages;\n        }\n\n        this.pageFrom = (this.options.pageNumber - 1) * this.options.pageSize + 1;\n        this.pageTo = this.options.pageNumber * this.options.pageSize;\n        if (this.pageTo > this.options.totalRows) {\n            this.pageTo = this.options.totalRows;\n        }\n\n        html.push(\n            '<div class=\"pull-' + this.options.paginationDetailHAlign + ' pagination-detail\">',\n            '<span class=\"pagination-info\">',\n            this.options.formatShowingRows(this.pageFrom, this.pageTo, this.options.totalRows),\n            '</span>');\n\n        html.push('<span class=\"page-list\">');\n\n        var pageNumber = [\n                sprintf('<span class=\"btn-group %s\">', this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ?\n                    'dropdown' : 'dropup'),\n                '<button type=\"button\" class=\"btn btn-default ' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + ' dropdown-toggle\" data-toggle=\"dropdown\">',\n                '<span class=\"page-size\">',\n                $allSelected ? this.options.formatAllRows() : this.options.pageSize,\n                '</span>',\n                ' <span class=\"caret\"></span>',\n                '</button>',\n                '<ul class=\"dropdown-menu\" role=\"menu\">'],\n            pageList = this.options.pageList;\n\n        if (typeof this.options.pageList === 'string') {\n            var list = this.options.pageList.replace('[', '').replace(']', '').replace(/ /g, '').split(',');\n\n            pageList = [];\n            $.each(list, function (i, value) {\n                pageList.push(value.toUpperCase() === that.options.formatAllRows().toUpperCase() ?\n                    that.options.formatAllRows() : +value);\n            });\n        }\n\n        $.each(pageList, function (i, page) {\n            if (!that.options.smartDisplay || i === 0 || pageList[i - 1] <= that.options.totalRows) {\n                var active;\n                if ($allSelected) {\n                    active = page === that.options.formatAllRows() ? ' class=\"active\"' : '';\n                } else {\n                    active = page === that.options.pageSize ? ' class=\"active\"' : '';\n                }\n                pageNumber.push(sprintf('<li%s><a href=\"javascript:void(0)\">%s</a></li>', active, page));\n            }\n        });\n        pageNumber.push('</ul></span>');\n\n        html.push(this.options.formatRecordsPerPage(pageNumber.join('')));\n        html.push('</span>');\n\n        html.push('</div>',\n            '<div class=\"pull-' + this.options.paginationHAlign + ' pagination\">',\n            '<ul class=\"pagination' + (this.options.iconSize === undefined ? '' : ' pagination-' + this.options.iconSize) + '\">',\n            '<li class=\"page-first\"><a href=\"javascript:void(0)\">' + this.options.paginationFirstText + '</a></li>',\n            '<li class=\"page-pre\"><a href=\"javascript:void(0)\">' + this.options.paginationPreText + '</a></li>');\n\n        if (this.totalPages < 5) {\n            from = 1;\n            to = this.totalPages;\n        } else {\n            from = this.options.pageNumber - 2;\n            to = from + 4;\n            if (from < 1) {\n                from = 1;\n                to = 5;\n            }\n            if (to > this.totalPages) {\n                to = this.totalPages;\n                from = to - 4;\n            }\n        }\n        for (i = from; i <= to; i++) {\n            html.push('<li class=\"page-number' + (i === this.options.pageNumber ? ' active' : '') + '\">',\n                '<a href=\"javascript:void(0)\">', i, '</a>',\n                '</li>');\n        }\n\n        html.push(\n            '<li class=\"page-next\"><a href=\"javascript:void(0)\">' + this.options.paginationNextText + '</a></li>',\n            '<li class=\"page-last\"><a href=\"javascript:void(0)\">' + this.options.paginationLastText + '</a></li>',\n            '</ul>',\n            '</div>');\n\n        this.$pagination.html(html.join(''));\n\n        $pageList = this.$pagination.find('.page-list a');\n        $first = this.$pagination.find('.page-first');\n        $pre = this.$pagination.find('.page-pre');\n        $next = this.$pagination.find('.page-next');\n        $last = this.$pagination.find('.page-last');\n        $number = this.$pagination.find('.page-number');\n\n        if (this.options.pageNumber <= 1) {\n            $first.addClass('disabled');\n            $pre.addClass('disabled');\n        }\n        if (this.options.pageNumber >= this.totalPages) {\n            $next.addClass('disabled');\n            $last.addClass('disabled');\n        }\n        if (this.options.smartDisplay) {\n            if (this.totalPages <= 1) {\n                this.$pagination.find('div.pagination').hide();\n            }\n            if (pageList.length < 2 || this.options.totalRows <= pageList[0]) {\n                this.$pagination.find('span.page-list').hide();\n            }\n\n            // when data is empty, hide the pagination\n            this.$pagination[this.getData().length ? 'show' : 'hide']();\n        }\n        if ($allSelected) {\n            this.options.pageSize = this.options.formatAllRows();\n        }\n        $pageList.off('click').on('click', $.proxy(this.onPageListChange, this));\n        $first.off('click').on('click', $.proxy(this.onPageFirst, this));\n        $pre.off('click').on('click', $.proxy(this.onPagePre, this));\n        $next.off('click').on('click', $.proxy(this.onPageNext, this));\n        $last.off('click').on('click', $.proxy(this.onPageLast, this));\n        $number.off('click').on('click', $.proxy(this.onPageNumber, this));\n    };\n\n    BootstrapTable.prototype.updatePagination = function (event) {\n        // Fix #171: IE disabled button can be clicked bug.\n        if (event && $(event.currentTarget).hasClass('disabled')) {\n            return;\n        }\n\n        if (!this.options.maintainSelected) {\n            this.resetRows();\n        }\n\n        this.initPagination();\n        if (this.options.sidePagination === 'server') {\n            this.initServer();\n        } else {\n            this.initBody();\n        }\n\n        this.trigger('page-change', this.options.pageNumber, this.options.pageSize);\n    };\n\n    BootstrapTable.prototype.onPageListChange = function (event) {\n        var $this = $(event.currentTarget);\n\n        $this.parent().addClass('active').siblings().removeClass('active');\n        this.options.pageSize = $this.text().toUpperCase() === this.options.formatAllRows().toUpperCase() ?\n            this.options.formatAllRows() : +$this.text();\n        this.$toolbar.find('.page-size').text(this.options.pageSize);\n\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPageFirst = function (event) {\n        this.options.pageNumber = 1;\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPagePre = function (event) {\n        this.options.pageNumber--;\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPageNext = function (event) {\n        this.options.pageNumber++;\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPageLast = function (event) {\n        this.options.pageNumber = this.totalPages;\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPageNumber = function (event) {\n        if (this.options.pageNumber === +$(event.currentTarget).text()) {\n            return;\n        }\n        this.options.pageNumber = +$(event.currentTarget).text();\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.initBody = function (fixedScroll) {\n        var that = this,\n            html = [],\n            data = this.getData();\n\n        this.trigger('pre-body', data);\n\n        this.$body = this.$el.find('tbody');\n        if (!this.$body.length) {\n            this.$body = $('<tbody></tbody>').appendTo(this.$el);\n        }\n\n        //Fix #389 Bootstrap-table-flatJSON is not working\n\n        if (!this.options.pagination || this.options.sidePagination === 'server') {\n            this.pageFrom = 1;\n            this.pageTo = data.length;\n        }\n\n        for (var i = this.pageFrom - 1; i < this.pageTo; i++) {\n            var key,\n                item = data[i],\n                style = {},\n                csses = [],\n                data_ = '',\n                attributes = {},\n                htmlAttributes = [];\n\n            style = calculateObjectValue(this.options, this.options.rowStyle, [item, i], style);\n\n            if (style && style.css) {\n                for (key in style.css) {\n                    csses.push(key + ': ' + style.css[key]);\n                }\n            }\n\n            attributes = calculateObjectValue(this.options,\n                this.options.rowAttributes, [item, i], attributes);\n\n            if (attributes) {\n                for (key in attributes) {\n                    htmlAttributes.push(sprintf('%s=\"%s\"', key, escapeHTML(attributes[key])));\n                }\n            }\n\n            if (item._data && !$.isEmptyObject(item._data)) {\n                $.each(item._data, function (k, v) {\n                    // ignore data-index\n                    if (k === 'index') {\n                        return;\n                    }\n                    data_ += sprintf(' data-%s=\"%s\"', k, v);\n                });\n            }\n\n            html.push('<tr',\n                sprintf(' %s', htmlAttributes.join(' ')),\n                sprintf(' id=\"%s\"', $.isArray(item) ? undefined : item._id),\n                sprintf(' class=\"%s\"', style.classes || ($.isArray(item) ? undefined : item._class)),\n                sprintf(' data-index=\"%s\"', i),\n                sprintf(' data-uniqueid=\"%s\"', item[this.options.uniqueId]),\n                sprintf('%s', data_),\n                '>'\n            );\n\n            if (this.options.cardView) {\n                html.push(sprintf('<td colspan=\"%s\">', this.header.fields.length));\n            }\n\n            if (!this.options.cardView && this.options.detailView) {\n                html.push('<td>',\n                    '<a class=\"detail-icon\" href=\"javascript:\">',\n                    '<i class=\"glyphicon glyphicon-plus icon-plus\"></i>',\n                    '</a>',\n                    '</td>');\n            }\n\n            $.each(this.header.fields, function (j, field) {\n                var text = '',\n                    value = item[field],\n                    type = '',\n                    cellStyle = {},\n                    id_ = '',\n                    class_ = that.header.classes[j],\n                    data_ = '',\n                    rowspan_ = '',\n                    column = that.options.columns[getFieldIndex(that.options.columns, field)];\n\n                style = sprintf('style=\"%s\"', csses.concat(that.header.styles[j]).join('; '));\n\n                value = calculateObjectValue(column,\n                    that.header.formatters[j], [value, item, i], value);\n\n                // handle td's id and class\n                if (item['_' + field + '_id']) {\n                    id_ = sprintf(' id=\"%s\"', item['_' + field + '_id']);\n                }\n                if (item['_' + field + '_class']) {\n                    class_ = sprintf(' class=\"%s\"', item['_' + field + '_class']);\n                }\n                if (item['_' + field + '_rowspan']) {\n                    rowspan_ = sprintf(' rowspan=\"%s\"', item['_' + field + '_rowspan']);\n                }\n                cellStyle = calculateObjectValue(that.header,\n                    that.header.cellStyles[j], [value, item, i], cellStyle);\n                if (cellStyle.classes) {\n                    class_ = sprintf(' class=\"%s\"', cellStyle.classes);\n                }\n                if (cellStyle.css) {\n                    var csses_ = [];\n                    for (var key in cellStyle.css) {\n                        csses_.push(key + ': ' + cellStyle.css[key]);\n                    }\n                    style = sprintf('style=\"%s\"', csses_.concat(that.header.styles[j]).join('; '));\n                }\n\n                if (item['_' + field + '_data'] && !$.isEmptyObject(item['_' + field + '_data'])) {\n                    $.each(item['_' + field + '_data'], function (k, v) {\n                        // ignore data-index\n                        if (k === 'index') {\n                            return;\n                        }\n                        data_ += sprintf(' data-%s=\"%s\"', k, v);\n                    });\n                }\n\n                if (column.checkbox || column.radio) {\n                    type = column.checkbox ? 'checkbox' : type;\n                    type = column.radio ? 'radio' : type;\n\n                    text = [that.options.cardView ?\n                        '<div class=\"card-view\">' : '<td class=\"bs-checkbox\">',\n                        '<input' +\n                            sprintf(' data-index=\"%s\"', i) +\n                            sprintf(' name=\"%s\"', that.options.selectItemName) +\n                            sprintf(' type=\"%s\"', type) +\n                            sprintf(' value=\"%s\"', item[that.options.idField]) +\n                            sprintf(' checked=\"%s\"', value === true ||\n                                (value && value.checked) ? 'checked' : undefined) +\n                            sprintf(' disabled=\"%s\"', !column.checkboxEnabled ||\n                                (value && value.disabled) ? 'disabled' : undefined) +\n                            ' />',\n                        that.options.cardView ? '</div>' : '</td>'].join('');\n\n                    item[that.header.stateField] = value === true || (value && value.checked);\n                } else {\n                    value = typeof value === 'undefined' || value === null ?\n                        that.options.undefinedText : value;\n\n                    text = that.options.cardView ?\n                        ['<div class=\"card-view\">',\n                            that.options.showHeader ? sprintf('<span class=\"title\" %s>%s</span>', style,\n                                getPropertyFromOther(that.options.columns, 'field', 'title', field)) : '',\n                            sprintf('<span class=\"value\">%s</span>', value),\n                            '</div>'].join('') :\n                        [sprintf('<td%s %s %s %s %s>', id_, class_, style, data_, rowspan_),\n                            value,\n                            '</td>'].join('');\n\n                    // Hide empty data on Card view when smartDisplay is set to true.\n                    if (that.options.cardView && that.options.smartDisplay && value === '') {\n                        text = '';\n                    }\n                }\n\n                html.push(text);\n            });\n\n            if (this.options.cardView) {\n                html.push('</td>');\n            }\n\n            html.push('</tr>');\n        }\n\n        // show no records\n        if (!html.length) {\n            html.push('<tr class=\"no-records-found\">',\n                sprintf('<td colspan=\"%s\">%s</td>',\n                    this.$header.find('th').length, this.options.formatNoMatches()),\n                '</tr>');\n        }\n\n        this.$body.html(html.join(''));\n\n        if (!fixedScroll) {\n            this.scrollTo(0);\n        }\n\n        // click to select by column\n        this.$body.find('> tr > td').off('click').on('click', function () {\n            var $td = $(this),\n                $tr = $td.parent(),\n                item = that.data[$tr.data('index')],\n                cellIndex = $td[0].cellIndex,\n                $headerCell = that.$header.find('th:eq(' + cellIndex + ')'),\n                field = $headerCell.data('field'),\n                value = item[field];\n            that.trigger('click-cell', field, value, item, $td);\n            that.trigger('click-row', item, $tr);\n            // if click to select - then trigger the checkbox/radio click\n            if (that.options.clickToSelect) {\n                if (that.header.clickToSelects[$tr.children().index($(this))]) {\n                    $tr.find(sprintf('[name=\"%s\"]',\n                        that.options.selectItemName))[0].click(); // #144: .trigger('click') bug\n                }\n            }\n        });\n        this.$body.find('> tr > td').off('dblclick').on('dblclick', function () {\n            var $td = $(this),\n                $tr = $td.parent(),\n                item = that.data[$tr.data('index')],\n                cellIndex = $td[0].cellIndex,\n                $headerCell = that.$header.find('th:eq(' + cellIndex + ')'),\n                field = $headerCell.data('field'),\n                value = item[field];\n            that.trigger('dbl-click-cell', field, value, item, $td);\n            that.trigger('dbl-click-row', item, $tr);\n        });\n\n        this.$body.find('> tr > td > .detail-icon').off('click').on('click', function () {\n            var $this = $(this),\n                $tr = $this.parent().parent(),\n                index = $tr.data('index'),\n                row = that.options.data[index];\n\n            // remove and update\n            if ($tr.next().is('tr.detail-view')) {\n                $this.find('i').attr('class', 'glyphicon glyphicon-plus icon-plus');\n                $tr.next().remove();\n                that.trigger('collapse-row', index, row);\n            } else {\n                $this.find('i').attr('class', 'glyphicon glyphicon-minus icon-minus');\n                $tr.after(sprintf('<tr class=\"detail-view\"><td colspan=\"%s\">%s</td></tr>',\n                    $tr.find('td').length, calculateObjectValue(that.options,\n                        that.options.detailFormatter, [index, row], '')));\n                that.trigger('expand-row', index, row, $tr.next().find('td'));\n            }\n            that.resetView();\n        });\n\n        this.$selectItem = this.$body.find(sprintf('[name=\"%s\"]', this.options.selectItemName));\n        this.$selectItem.off('click').on('click', function (event) {\n            event.stopImmediatePropagation();\n\n            var checked = $(this).prop('checked'),\n                row = that.data[$(this).data('index')];\n\n            row[that.header.stateField] = checked;\n\n            if (that.options.singleSelect) {\n                that.$selectItem.not(this).each(function () {\n                    that.data[$(this).data('index')][that.header.stateField] = false;\n                });\n                that.$selectItem.filter(':checked').not(this).prop('checked', false);\n            }\n\n            that.updateSelected();\n            that.trigger(checked ? 'check' : 'uncheck', row);\n        });\n\n        $.each(this.header.events, function (i, events) {\n            if (!events) {\n                return;\n            }\n            // fix bug, if events is defined with namespace\n            if (typeof events === 'string') {\n                events = calculateObjectValue(null, events);\n            }\n            if (!that.options.cardView && that.options.detailView) {\n                i += 1;\n            }\n            for (var key in events) {\n                that.$body.find('tr').each(function () {\n                    var $tr = $(this),\n                        $td = $tr.find(that.options.cardView ? '.card-view' : 'td').eq(i),\n                        index = key.indexOf(' '),\n                        name = key.substring(0, index),\n                        el = key.substring(index + 1),\n                        func = events[key];\n\n                    $td.find(el).off(name).on(name, function (e) {\n                        var index = $tr.data('index'),\n                            row = that.data[index],\n                            value = row[that.header.fields[i]];\n\n                        func.apply(this, [e, value, row, index]);\n                    });\n                });\n            }\n        });\n\n        this.updateSelected();\n        this.resetView();\n\n        this.trigger('post-body');\n    };\n\n    BootstrapTable.prototype.initServer = function (silent, query) {\n        var that = this,\n            data = {},\n            params = {\n                pageSize: this.options.pageSize === this.options.formatAllRows() ?\n                    this.options.totalRows : this.options.pageSize,\n                pageNumber: this.options.pageNumber,\n                searchText: this.searchText,\n                sortName: this.options.sortName,\n                sortOrder: this.options.sortOrder\n            },\n            request;\n\n        if (!this.options.url && !this.options.ajax) {\n            return;\n        }\n\n        if (this.options.queryParamsType === 'limit') {\n            params = {\n                search: params.searchText,\n                sort: params.sortName,\n                order: params.sortOrder\n            };\n            if (this.options.pagination) {\n                params.limit = this.options.pageSize === this.options.formatAllRows() ?\n                    this.options.totalRows : this.options.pageSize;\n                params.offset = this.options.pageSize === this.options.formatAllRows() ?\n                    0 : this.options.pageSize * (this.options.pageNumber - 1);\n            }\n        }\n\n        if (!($.isEmptyObject(this.filterColumnsPartial))) {\n            params['filter'] = JSON.stringify(this.filterColumnsPartial, null);\n        }\n\n        data = calculateObjectValue(this.options, this.options.queryParams, [params], data);\n\n        $.extend(data, query || {});\n\n        // false to stop request\n        if (data === false) {\n            return;\n        }\n\n        if (!silent) {\n            this.$tableLoading.show();\n        }\n        request = $.extend({}, calculateObjectValue(null, this.options.ajaxOptions), {\n            type: this.options.method,\n            url: this.options.url,\n            data: this.options.contentType === 'application/json' && this.options.method === 'post' ?\n                JSON.stringify(data) : data,\n            cache: this.options.cache,\n            contentType: this.options.contentType,\n            dataType: this.options.dataType,\n            success: function (res) {\n                res = calculateObjectValue(that.options, that.options.responseHandler, [res], res);\n\n                that.load(res);\n                that.trigger('load-success', res);\n            },\n            error: function (res) {\n                that.trigger('load-error', res.status);\n            },\n            complete: function () {\n                if (!silent) {\n                    that.$tableLoading.hide();\n                }\n            }\n        });\n\n        if (this.options.ajax) {\n            calculateObjectValue(this, this.options.ajax, [request], null);\n        } else {\n            $.ajax(request);\n        }\n    };\n\n    BootstrapTable.prototype.getCaretHtml = function () {\n        var that = this;\n\n        $.each(this.$header.find('th'), function (i, th) {\n            if ($(th).data('field') === that.options.sortName) {\n                $(th).find('.sortable').css('background-image', 'url(' + (that.options.sortOrder === 'desc' ? arrowDesc : arrowAsc) + ')');\n            } else {\n                $(th).find('.sortable').css('background-image', 'url(' + arrowBoth +')');\n            }\n        });\n    };\n\n    BootstrapTable.prototype.updateSelected = function () {\n        var checkAll = this.$selectItem.filter(':enabled').length ===\n            this.$selectItem.filter(':enabled').filter(':checked').length;\n\n        this.$selectAll.add(this.$selectAll_).prop('checked', checkAll);\n\n        this.$selectItem.each(function () {\n            $(this).parents('tr')[$(this).prop('checked') ? 'addClass' : 'removeClass']('selected');\n        });\n    };\n\n    BootstrapTable.prototype.updateRows = function () {\n        var that = this;\n\n        this.$selectItem.each(function () {\n            that.data[$(this).data('index')][that.header.stateField] = $(this).prop('checked');\n        });\n    };\n\n    BootstrapTable.prototype.resetRows = function () {\n        var that = this;\n\n        $.each(this.data, function (i, row) {\n            that.$selectAll.prop('checked', false);\n            that.$selectItem.prop('checked', false);\n            row[that.header.stateField] = false;\n        });\n    };\n\n    BootstrapTable.prototype.trigger = function (name) {\n        var args = Array.prototype.slice.call(arguments, 1);\n\n        name += '.bs.table';\n        this.options[BootstrapTable.EVENTS[name]].apply(this.options, args);\n        this.$el.trigger($.Event(name), args);\n\n        this.options.onAll(name, args);\n        this.$el.trigger($.Event('all.bs.table'), [name, args]);\n    };\n\n    BootstrapTable.prototype.resetHeader = function () {\n        // fix #61: the hidden table reset header bug.\n        // fix bug: get $el.css('width') error sometime (height = 500)\n        clearTimeout(this.timeoutId_);\n        this.timeoutId_ = setTimeout($.proxy(this.fitHeader, this), this.$el.is(':hidden') ? 100 : 0);\n    };\n\n    BootstrapTable.prototype.fitHeader = function () {\n        var that = this,\n            fixedBody,\n            scrollWidth;\n\n        if (that.$el.is(':hidden')) {\n            that.timeoutFooter_ = setTimeout($.proxy(that.fitHeader, that), 100);\n            return;\n        }\n        fixedBody = this.$tableBody.get(0);\n\n        scrollWidth = fixedBody.scrollWidth > fixedBody.clientWidth &&\n            fixedBody.scrollHeight > fixedBody.clientHeight + this.$header.height() ?\n            getScrollBarWidth() : 0;\n\n        this.$el.css('margin-top', -this.$header.height());\n        this.$header_ = this.$header.clone(true, true);\n        this.$selectAll_ = this.$header_.find('[name=\"btSelectAll\"]');\n        this.$tableHeader.css({\n            'margin-right': scrollWidth\n        }).find('table').css('width', this.$el.css('width'))\n            .html('').attr('class', this.$el.attr('class'))\n            .append(this.$header_);\n\n        // fix bug: $.data() is not working as expected after $.append()\n        this.$header.find('th').each(function (i) {\n            that.$header_.find('th').eq(i).data($(this).data());\n        });\n\n        this.$body.find('tr:first-child:not(.no-records-found) > *').each(function (i) {\n            that.$header_.find('div.fht-cell').eq(i).width($(this).innerWidth());\n        });\n        // horizontal scroll event\n        // TODO: it's probably better improving the layout than binding to scroll event\n        this.$tableBody.off('scroll').on('scroll', function () {\n            that.$tableHeader.scrollLeft($(this).scrollLeft());\n        });\n        that.trigger('post-header');\n    };\n\n    BootstrapTable.prototype.resetFooter = function () {\n        var that = this,\n            data = that.getData(),\n            html = [];\n\n        if (!this.options.showFooter || this.options.cardView) { //do nothing\n            return;\n        }\n\n        if (!this.options.cardView && this.options.detailView) {\n            html.push('<td></td>');\n        }\n\n        $.each(this.options.columns, function (i, column) {\n            var falign = '', // footer align style\n                style = '',\n                class_ = sprintf(' class=\"%s\"', column['class']);\n\n            if (!column.visible) {\n                return;\n            }\n\n            if (that.options.cardView && (!column.cardVisible)) {\n                return;\n            }\n\n            falign = sprintf('text-align: %s; ', column.falign ? column.falign : column.align);\n            style = sprintf('vertical-align: %s; ', column.valign);\n\n            html.push('<td', class_, sprintf(' style=\"%s\"', falign + style), '>');\n\n            html.push(calculateObjectValue(column, column.footerFormatter, [data], '&nbsp;') || '&nbsp;');\n            html.push('</td>');\n        });\n\n        this.$tableFooter.find('tr').html(html.join(''));\n        clearTimeout(this.timeoutFooter_);\n        this.timeoutFooter_ = setTimeout($.proxy(this.fitFooter, this),\n            this.$el.is(':hidden') ? 100 : 0);\n    };\n\n    BootstrapTable.prototype.fitFooter = function () {\n        var that = this,\n            $footerTd,\n            elWidth,\n            scrollWidth;\n\n        clearTimeout(this.timeoutFooter_);\n        if (this.$el.is(':hidden')) {\n            this.timeoutFooter_ = setTimeout($.proxy(this.fitFooter, this), 100);\n            return;\n        }\n\n        elWidth = this.$el.css('width');\n        scrollWidth = elWidth > this.$tableBody.width() ? getScrollBarWidth() : 0;\n\n        this.$tableFooter.css({\n            'margin-right': scrollWidth\n        }).find('table').css('width', elWidth)\n            .attr('class', this.$el.attr('class'));\n\n        $footerTd = this.$tableFooter.find('td');\n\n        this.$tableBody.find('tbody tr:first-child:not(.no-records-found) > td').each(function (i) {\n            $footerTd.eq(i).outerWidth($(this).outerWidth());\n        });\n    };\n\n    BootstrapTable.prototype.toggleColumn = function (index, checked, needUpdate) {\n        if (index === -1) {\n            return;\n        }\n        this.options.columns[index].visible = checked;\n        this.initHeader();\n        this.initSearch();\n        this.initPagination();\n        this.initBody();\n\n        if (this.options.showColumns) {\n            var $items = this.$toolbar.find('.keep-open input').prop('disabled', false);\n\n            if (needUpdate) {\n                $items.filter(sprintf('[value=\"%s\"]', index)).prop('checked', checked);\n            }\n\n            if ($items.filter(':checked').length <= this.options.minimumCountColumns) {\n                $items.filter(':checked').prop('disabled', true);\n            }\n        }\n    };\n\n    BootstrapTable.prototype.toggleRow = function (index, isIdField, visible) {\n        if (index === -1) {\n            return;\n        }\n\n        $(this.$body[0]).children().filter(sprintf(isIdField ? '[data-uniqueid=\"%s\"]' : '[data-index=\"%s\"]', index))\n            [visible ? 'show' : 'hide']();\n    };\n\n    // PUBLIC FUNCTION DEFINITION\n    // =======================\n\n    BootstrapTable.prototype.resetView = function (params) {\n        var padding = 0;\n\n        if (params && params.height) {\n            this.options.height = params.height;\n        }\n\n        this.$selectAll.prop('checked', this.$selectItem.length > 0 &&\n            this.$selectItem.length === this.$selectItem.filter(':checked').length);\n\n        if (this.options.height) {\n            var toolbarHeight = getRealHeight(this.$toolbar),\n                paginationHeight = getRealHeight(this.$pagination),\n                height = this.options.height - toolbarHeight - paginationHeight;\n\n            this.$tableContainer.css('height', height + 'px');\n        }\n\n        if (this.options.cardView) {\n            // remove the element css\n            this.$el.css('margin-top', '0');\n            this.$tableContainer.css('padding-bottom', '0');\n            return;\n        }\n\n        if (this.options.showHeader && this.options.height) {\n            this.$tableHeader.show();\n            this.resetHeader();\n            padding += cellHeight;\n        } else {\n            this.$tableHeader.hide();\n            this.trigger('post-header');\n        }\n\n        if (this.options.showFooter) {\n            this.resetFooter();\n            if (this.options.height) {\n                padding += cellHeight;\n            }\n        }\n\n        // Assign the correct sortable arrow\n        this.getCaretHtml();\n        this.$tableContainer.css('padding-bottom', padding + 'px');\n    };\n\n    BootstrapTable.prototype.getData = function (useCurrentPage) {\n        return (this.searchText\n            || !$.isEmptyObject(this.filterColumns)\n            || !$.isEmptyObject(this.filterColumnsPartial)) ?\n            (useCurrentPage ? this.data.slice(this.pageFrom -1, this.pageTo)\n                : this.data) :\n            (useCurrentPage ? this.options.data.slice(this.pageFrom - 1, this.pageTo)\n                : this.options.data);\n    };\n\n    BootstrapTable.prototype.load = function (data) {\n        var fixedScroll = false;\n\n        // #431: support pagination\n        if (this.options.sidePagination === 'server') {\n            this.options.totalRows = data.total;\n            fixedScroll = data.fixedScroll;\n            data = data.rows;\n        } else if (!$.isArray(data)) { // support fixedScroll\n            fixedScroll = data.fixedScroll;\n            data = data.data;\n        }\n\n        this.initData(data);\n        this.initSearch();\n        this.initPagination();\n        this.initBody(fixedScroll);\n    };\n\n    BootstrapTable.prototype.append = function (data) {\n        this.initData(data, 'append');\n        this.initSearch();\n        this.initPagination();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.prepend = function (data) {\n        this.initData(data, 'prepend');\n        this.initSearch();\n        this.initPagination();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.remove = function (params) {\n        var len = this.options.data.length,\n            i, row;\n\n        if (!params.hasOwnProperty('field') || !params.hasOwnProperty('values')) {\n            return;\n        }\n\n        for (i = len - 1; i >= 0; i--) {\n            row = this.options.data[i];\n\n            if (!row.hasOwnProperty(params.field)) {\n                continue;\n            }\n            if ($.inArray(row[params.field], params.values) !== -1) {\n                this.options.data.splice(i, 1);\n            }\n        }\n\n        if (len === this.options.data.length) {\n            return;\n        }\n\n        this.initSearch();\n        this.initPagination();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.removeAll = function () {\n        if (this.options.data.length > 0) {\n            this.options.data.splice(0, this.options.data.length);\n            this.initSearch();\n            this.initPagination();\n            this.initBody(true);\n        }\n    };\n\n    BootstrapTable.prototype.removeByUniqueId = function (id) {\n        var uniqueId = this.options.uniqueId,\n            len = this.options.data.length,\n            i, row;\n\n        for (i = len - 1; i >= 0; i--) {\n            row = this.options.data[i];\n\n            if (!row.hasOwnProperty(uniqueId)) {\n                continue;\n            }\n\n            if (typeof row[uniqueId] === 'string') {\n                id = id.toString();\n            } else if (typeof row[uniqueId] === 'number') {\n                if ((Number(row[uniqueId]) === row[uniqueId]) && (row[uniqueId] % 1 === 0)) {\n                    id = parseInt(id);\n                } else if ((row[uniqueId] === Number(row[uniqueId])) && (row[uniqueId] !== 0)) {\n                    id = parseFloat(id);\n                }\n            }\n\n            if (row[uniqueId] === id) {\n                this.options.data.splice(i, 1);\n            }\n        }\n\n        if (len === this.options.data.length) {\n            return;\n        }\n\n        this.initSearch();\n        this.initPagination();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.insertRow = function (params) {\n        if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {\n            return;\n        }\n        this.data.splice(params.index, 0, params.row);\n        this.initSearch();\n        this.initPagination();\n        this.initSort();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.updateRow = function (params) {\n        if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {\n            return;\n        }\n        $.extend(this.data[params.index], params.row);\n        this.initSort();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.showRow = function (params) {\n        if (!params.hasOwnProperty('index')) {\n            return;\n        }\n\n        this.toggleRow(params.index, params.isIdField === undefined ? false : true, true);\n    };\n\n    BootstrapTable.prototype.hideRow = function (params) {\n        if (!params.hasOwnProperty('index')) {\n            return;\n        }\n\n        this.toggleRow(params.index, params.isIdField === undefined ? false : true, false);\n    };\n\n    BootstrapTable.prototype.getRowsHidden = function (show) {\n        var rows = $(this.$body[0]).children().filter(':hidden'),\n            i = 0;\n        if (show) {\n            for (; i < rows.length; i++) {\n                $(rows[i]).show();\n            }\n        }\n        return rows;\n    };\n\n    BootstrapTable.prototype.mergeCells = function (options) {\n        var row = options.index,\n            col = $.inArray(options.field, this.header.fields),\n            rowspan = options.rowspan || 1,\n            colspan = options.colspan || 1,\n            i, j,\n            $tr = this.$body.find('tr'),\n            $td = $tr.eq(row).find('td').eq(col);\n\n        if (!this.options.cardView && this.options.detailView) {\n            col += 1;\n        }\n        $td = $tr.eq(row).find('td').eq(col);\n\n        if (row < 0 || col < 0 || row >= this.data.length) {\n            return;\n        }\n\n        for (i = row; i < row + rowspan; i++) {\n            for (j = col; j < col + colspan; j++) {\n                $tr.eq(i).find('td').eq(j).hide();\n            }\n        }\n\n        $td.attr('rowspan', rowspan).attr('colspan', colspan).show();\n    };\n\n    BootstrapTable.prototype.updateCell = function (params) {\n        if (!params.hasOwnProperty('rowIndex') || !params.hasOwnProperty('fieldName') || !params.hasOwnProperty('fieldValue')) {\n            return;\n        }\n        this.data[params.rowIndex][params.fieldName] = params.fieldValue;\n        this.initSort();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.getOptions = function () {\n        return this.options;\n    };\n\n    BootstrapTable.prototype.getSelections = function () {\n        var that = this;\n\n        return $.grep(this.data, function (row) {\n            return row[that.header.stateField];\n        });\n    };\n\n    BootstrapTable.prototype.getAllSelections = function () {\n        var that = this;\n\n        return $.grep(this.options.data, function (row) {\n            return row[that.header.stateField];\n        });\n    };\n\n    BootstrapTable.prototype.checkAll = function () {\n        this.checkAll_(true);\n    };\n\n    BootstrapTable.prototype.uncheckAll = function () {\n        this.checkAll_(false);\n    };\n\n    BootstrapTable.prototype.checkAll_ = function (checked) {\n        var rows;\n        if (!checked) {\n            rows = this.getSelections();\n        }\n        this.$selectItem.filter(':enabled').prop('checked', checked);\n        this.updateRows();\n        this.updateSelected();\n        if (checked) {\n            rows = this.getSelections();\n        }\n        this.trigger(checked ? 'check-all' : 'uncheck-all', rows);\n    };\n\n    BootstrapTable.prototype.check = function (index) {\n        this.check_(true, index);\n    };\n\n    BootstrapTable.prototype.uncheck = function (index) {\n        this.check_(false, index);\n    };\n\n    BootstrapTable.prototype.check_ = function (checked, index) {\n        this.$selectItem.filter(sprintf('[data-index=\"%s\"]', index)).prop('checked', checked);\n        this.data[index][this.header.stateField] = checked;\n        this.updateSelected();\n        this.trigger(checked ? 'check' : 'uncheck', this.data[index]);\n    };\n\n    BootstrapTable.prototype.checkBy = function (obj) {\n        this.checkBy_(true, obj);\n    };\n\n    BootstrapTable.prototype.uncheckBy = function (obj) {\n        this.checkBy_(false, obj);\n    };\n\n    BootstrapTable.prototype.checkBy_ = function (checked, obj) {\n        if (!obj.hasOwnProperty('field') || !obj.hasOwnProperty('values')) {\n            return;\n        }\n\n        var that = this,\n            rows = [];\n        $.each(this.options.data, function (index, row) {\n            if (!row.hasOwnProperty(obj.field)) {\n                return false;\n            }\n            if ($.inArray(row[obj.field], obj.values) !== -1) {\n                that.$selectItem.filter(sprintf('[data-index=\"%s\"]', index)).prop('checked', checked);\n                row[that.header.stateField] = checked;\n                rows.push(row);\n                that.trigger(checked ? 'check' : 'uncheck', row);\n            }\n        });\n        this.updateSelected();\n        this.trigger(checked ? 'check-some' : 'uncheck-some', rows);\n    };\n\n    BootstrapTable.prototype.destroy = function () {\n        this.$el.insertBefore(this.$container);\n        $(this.options.toolbar).insertBefore(this.$el);\n        this.$container.next().remove();\n        this.$container.remove();\n        this.$el.html(this.$el_.html())\n            .css('margin-top', '0')\n            .attr('class', this.$el_.attr('class') || ''); // reset the class\n    };\n\n    BootstrapTable.prototype.showLoading = function () {\n        this.$tableLoading.show();\n    };\n\n    BootstrapTable.prototype.hideLoading = function () {\n        this.$tableLoading.hide();\n    };\n\n    BootstrapTable.prototype.togglePagination = function () {\n        this.options.pagination = !this.options.pagination;\n        var button = this.$toolbar.find('button[name=\"paginationSwitch\"] i');\n        if (this.options.pagination) {\n            button.attr(\"class\", this.options.iconsPrefix + \" \" + this.options.icons.paginationSwitchDown);\n        } else {\n            button.attr(\"class\", this.options.iconsPrefix + \" \" + this.options.icons.paginationSwitchUp);\n        }\n        this.updatePagination();\n    };\n\n    BootstrapTable.prototype.refresh = function (params) {\n        if (params && params.url) {\n            this.options.url = params.url;\n            this.options.pageNumber = 1;\n        }\n        this.initServer(params && params.silent, params && params.query);\n    };\n\n    BootstrapTable.prototype.resetWidth = function () {\n        if (this.options.showHeader && this.options.height) {\n            this.fitHeader();\n        }\n        if (this.options.showFooter) {\n            this.fitFooter();\n        }\n    };\n\n    BootstrapTable.prototype.showColumn = function (field) {\n        this.toggleColumn(getFieldIndex(this.options.columns, field), true, true);\n    };\n\n    BootstrapTable.prototype.hideColumn = function (field) {\n        this.toggleColumn(getFieldIndex(this.options.columns, field), false, true);\n    };\n\n    BootstrapTable.prototype.filterBy = function (columns) {\n        this.filterColumns = $.isEmptyObject(columns) ? {} : columns;\n        this.options.pageNumber = 1;\n        this.initSearch();\n        this.updatePagination();\n    };\n\n    BootstrapTable.prototype.scrollTo = function (value) {\n        if (typeof value === 'string') {\n            value = value === 'bottom' ? this.$tableBody[0].scrollHeight : 0;\n        }\n        if (typeof value === 'number') {\n            this.$tableBody.scrollTop(value);\n        }\n        if (typeof value === 'undefined') {\n            return this.$tableBody.scrollTop();\n        }\n    };\n\n    BootstrapTable.prototype.getScrollPosition = function () {\n        return this.scrollTo();\n    }\n\n    BootstrapTable.prototype.selectPage = function (page) {\n        if (page > 0 && page <= this.options.totalPages) {\n            this.options.pageNumber = page;\n            this.updatePagination();\n        }\n    };\n\n    BootstrapTable.prototype.prevPage = function () {\n        if (this.options.pageNumber > 1) {\n            this.options.pageNumber--;\n            this.updatePagination();\n        }\n    };\n\n    BootstrapTable.prototype.nextPage = function () {\n        if (this.options.pageNumber < this.options.totalPages) {\n            this.options.pageNumber++;\n            this.updatePagination();\n        }\n    };\n\n    BootstrapTable.prototype.toggleView = function () {\n        this.options.cardView = !this.options.cardView;\n        this.initHeader();\n        // Fixed remove toolbar when click cardView button.\n        //that.initToolbar();\n        this.initBody();\n        this.trigger('toggle', this.options.cardView);\n    };\n\n    // BOOTSTRAP TABLE PLUGIN DEFINITION\n    // =======================\n\n    var allowedMethods = [\n        'getOptions',\n        'getSelections', 'getAllSelections', 'getData',\n        'load', 'append', 'prepend', 'remove', 'removeAll',\n        'insertRow', 'updateRow', 'updateCell', 'removeByUniqueId',\n        'showRow', 'hideRow', 'getRowsHidden',\n        'mergeCells',\n        'checkAll', 'uncheckAll',\n        'check', 'uncheck',\n        'checkBy', 'uncheckBy',\n        'refresh',\n        'resetView',\n        'resetWidth',\n        'destroy',\n        'showLoading', 'hideLoading',\n        'showColumn', 'hideColumn',\n        'filterBy',\n        'scrollTo',\n        'getScrollPosition',\n        'selectPage', 'prevPage', 'nextPage',\n        'togglePagination',\n        'toggleView'\n    ];\n\n    $.fn.bootstrapTable = function (option) {\n        var value,\n            args = Array.prototype.slice.call(arguments, 1);\n\n        this.each(function () {\n            var $this = $(this),\n                data = $this.data('bootstrap.table'),\n                options = $.extend({}, BootstrapTable.DEFAULTS, $this.data(),\n                    typeof option === 'object' && option);\n\n            if (typeof option === 'string') {\n                if ($.inArray(option, allowedMethods) < 0) {\n                    throw new Error(\"Unknown method: \" + option);\n                }\n\n                if (!data) {\n                    return;\n                }\n\n                value = data[option].apply(data, args);\n\n                if (option === 'destroy') {\n                    $this.removeData('bootstrap.table');\n                }\n            }\n\n            if (!data) {\n                $this.data('bootstrap.table', (data = new BootstrapTable(this, options)));\n            }\n        });\n\n        return typeof value === 'undefined' ? this : value;\n    };\n\n    $.fn.bootstrapTable.Constructor = BootstrapTable;\n    $.fn.bootstrapTable.defaults = BootstrapTable.DEFAULTS;\n    $.fn.bootstrapTable.columnDefaults = BootstrapTable.COLUMN_DEFAULTS;\n    $.fn.bootstrapTable.locales = BootstrapTable.LOCALES;\n    $.fn.bootstrapTable.methods = allowedMethods;\n\n    // BOOTSTRAP TABLE INIT\n    // =======================\n\n    $(function () {\n        $('[data-toggle=\"table\"]').bootstrapTable();\n    });\n\n}(jQuery);\n\n/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.1.0\n *\n * @update zhixin wen <wenzhixin2010@gmail.com>\n */\n\n(function ($) {\n    'use strict';\n\n    var idsStateSaveList = {\n        sortOrder: 'bs.table.sortOrder',\n        sortName: 'bs.table.sortName',\n        pageNumber: 'bs.table.pageNumber',\n        pageList: 'bs.table.pageList',\n        columns: 'bs.table.columns',\n        searchText: 'bs.table.searchText'\n    };\n\n    var cookieEnabled = function () {\n        return (navigator.cookieEnabled) ? true : false;\n    };\n\n    var setCookie = function (that, cookieName, sValue, sPath, sDomain, bSecure) {\n        if ((!that.options.stateSave) || (!cookieEnabled()) || (that.options.stateSaveIdTable === '')) {\n            return;\n        }\n\n        var tableName = that.options.stateSaveIdTable,\n            vEnd = that.options.stateSaveExpire;\n\n        cookieName = tableName + '.' + cookieName;\n        if (!cookieName || /^(?:expires|max\\-age|path|domain|secure)$/i.test(cookieName)) {\n            return false;\n        }\n\n        document.cookie = encodeURIComponent(cookieName) + '=' + encodeURIComponent(sValue) + calculateExpiration(vEnd) + (sDomain ? '; domain=' + sDomain : '') + (sPath ? '; path=' + sPath : '') + (bSecure ? '; secure' : '');\n        return true;\n    };\n\n    var getCookie = function (tableName, cookieName) {\n        cookieName = tableName + '.' + cookieName;\n        if (!cookieName) {\n            return null;\n        }\n        return decodeURIComponent(document.cookie.replace(new RegExp('(?:(?:^|.*;)\\\\s*' + encodeURIComponent(cookieName).replace(/[\\-\\.\\+\\*]/g, '\\\\$&') + '\\\\s*\\\\=\\\\s*([^;]*).*$)|^.*$'), '$1')) || null;\n    };\n\n    var hasCookie = function (cookieName) {\n        if (!cookieName) {\n            return false;\n        }\n        return (new RegExp('(?:^|;\\\\s*)' + encodeURIComponent(cookieName).replace(/[\\-\\.\\+\\*]/g, '\\\\$&') + '\\\\s*\\\\=')).test(document.cookie);\n    };\n\n    var deleteCookie = function (tableName, cookieName, sPath, sDomain) {\n        cookieName = tableName + '.' + cookieName;\n        if (!hasCookie(cookieName)) {\n            return false;\n        }\n        document.cookie = encodeURIComponent(cookieName) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT' + (sDomain ? '; domain=' + sDomain : '') + (sPath ? '; path=' + sPath : '');\n        return true;\n    };\n\n    var calculateExpiration = function(vEnd) {\n        var time = vEnd.replace(/[0-9]/, ''); //s,mi,h,d,m,y\n        vEnd = vEnd.replace(/[A-Za-z]/, ''); //number\n\n        switch (time.toLowerCase()) {\n            case 's':\n                vEnd = +vEnd;\n                break;\n            case 'mi':\n                vEnd = vEnd * 60;\n                break;\n            case 'h':\n                vEnd = vEnd * 60 * 60;\n                break;\n            case 'd':\n                vEnd = vEnd * 24 * 60 * 60;\n                break;\n            case 'm':\n                vEnd = vEnd * 30 * 24 * 60 * 60;\n                break;\n            case 'y':\n                vEnd = vEnd * 365 * 30 * 24 * 60 * 60;\n                break;\n            default:\n                vEnd = undefined;\n                break;\n        }\n\n        return vEnd === undefined ? '' : '; max-age=' + vEnd;\n    }\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        stateSave: false,\n        stateSaveExpire: '2h',\n        stateSaveIdTable: ''\n    });\n\n    $.fn.bootstrapTable.methods.push('deleteCookie');\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initTable = BootstrapTable.prototype.initTable,\n        _onSort = BootstrapTable.prototype.onSort,\n        _onPageNumber = BootstrapTable.prototype.onPageNumber,\n        _onPageListChange = BootstrapTable.prototype.onPageListChange,\n        _onPageFirst = BootstrapTable.prototype.onPageFirst,\n        _onPagePre = BootstrapTable.prototype.onPagePre,\n        _onPageNext = BootstrapTable.prototype.onPageNext,\n        _onPageLast = BootstrapTable.prototype.onPageLast,\n        _toggleColumn = BootstrapTable.prototype.toggleColumn,\n        _onSearch = BootstrapTable.prototype.onSearch;\n\n    // init save data after initTable function\n    BootstrapTable.prototype.initTable = function () {\n        _initTable.apply(this, Array.prototype.slice.apply(arguments));\n        this.initStateSave();\n    };\n\n    BootstrapTable.prototype.initStateSave = function () {\n        if (!this.options.stateSave) {\n            return;\n        }\n\n        if (!cookieEnabled()) {\n            return;\n        }\n\n        if (this.options.stateSaveIdTable === '') {\n            return;\n        }\n\n        var sortOrderStateSave = getCookie(this.options.stateSaveIdTable, idsStateSaveList.sortOrder),\n            sortOrderStateName = getCookie(this.options.stateSaveIdTable, idsStateSaveList.sortName),\n            pageNumberStateSave = getCookie(this.options.stateSaveIdTable, idsStateSaveList.pageNumber),\n            pageListStateSave = getCookie(this.options.stateSaveIdTable, idsStateSaveList.pageList),\n            columnsStateSave = JSON.parse(getCookie(this.options.stateSaveIdTable, idsStateSaveList.columns)),\n            searchStateSave = getCookie(this.options.stateSaveIdTable, idsStateSaveList.searchText);\n\n        if (sortOrderStateSave) {\n            this.options.sortOrder = sortOrderStateSave;\n            this.options.sortName = sortOrderStateName;\n        }\n\n        if (pageNumberStateSave) {\n            this.options.pageNumber = +pageNumberStateSave;\n        }\n\n        if (pageListStateSave) {\n            this.options.pageSize = pageListStateSave ===\n                this.options.formatAllRows() ? pageListStateSave : +pageListStateSave;\n        }\n\n        if (columnsStateSave) {\n            $.each(this.options.columns, function (i, column) {\n                column.visible = columnsStateSave.indexOf(i) !== -1;\n            });\n        }\n\n        if (searchStateSave) {\n            this.options.searchText = searchStateSave;\n        }\n    };\n\n    BootstrapTable.prototype.onSort = function () {\n        _onSort.apply(this, Array.prototype.slice.apply(arguments));\n\n        setCookie(this, idsStateSaveList.sortOrder, this.options.sortOrder);\n        setCookie(this, idsStateSaveList.sortName, this.options.sortName);\n    };\n\n    BootstrapTable.prototype.onPageNumber = function () {\n        _onPageNumber.apply(this, Array.prototype.slice.apply(arguments));\n\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.onPageListChange = function () {\n        _onPageListChange.apply(this, Array.prototype.slice.apply(arguments));\n\n        setCookie(this, idsStateSaveList.pageList, this.options.pageSize);\n    };\n\n    BootstrapTable.prototype.onPageFirst = function () {\n        _onPageFirst.apply(this, Array.prototype.slice.apply(arguments));\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.onPagePre = function () {\n        _onPagePre.apply(this, Array.prototype.slice.apply(arguments));\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.onPageNext = function () {\n        _onPageNext.apply(this, Array.prototype.slice.apply(arguments));\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.onPageLast = function () {\n        _onPageLast.apply(this, Array.prototype.slice.apply(arguments));\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.toggleColumn = function () {\n        _toggleColumn.apply(this, Array.prototype.slice.apply(arguments));\n\n        var visibleColumns = [];\n\n        $.each(this.options.columns, function (i) {\n            if (this.visible) {\n                visibleColumns.push(i);\n            }\n        });\n\n        setCookie(this, idsStateSaveList.columns, JSON.stringify(visibleColumns));\n    };\n\n    BootstrapTable.prototype.onSearch = function () {\n        _onSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        setCookie(this, idsStateSaveList.searchText, this.searchText);\n    };\n\n    BootstrapTable.prototype.deleteCookie = function (cookieName) {\n        if ((cookieName === '') || (!cookieEnabled())) {\n            return;\n        }\n\n        deleteCookie(idsStateSaveList[cookieName]);\n    };\n})(jQuery);\n\n/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * extensions: https://github.com/vitalets/x-editable\n */\n\n!function ($) {\n\n    'use strict';\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        editable: true,\n        onEditableInit: function () {\n            return false;\n        },\n        onEditableSave: function (field, row, oldValue, $el) {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'editable-init.bs.table': 'onEditableInit',\n        'editable-save.bs.table': 'onEditableSave'\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initTable = BootstrapTable.prototype.initTable,\n        _initBody = BootstrapTable.prototype.initBody;\n\n    BootstrapTable.prototype.initTable = function () {\n        var that = this;\n        _initTable.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.editable) {\n            return;\n        }\n\n        $.each(this.options.columns, function (i, column) {\n            if (!column.editable) {\n                return;\n            }\n\n            var _formatter = column.formatter;\n            column.formatter = function (value, row, index) {\n                var result = _formatter ? _formatter(value, row, index) : value;\n\n                return ['<a href=\"javascript:void(0)\"',\n                    ' data-name=\"' + column.field + '\"',\n                    ' data-pk=\"' + row[that.options.idField] + '\"',\n                    ' data-value=\"' + result + '\"',\n                    '>' + '</a>'\n                ].join('');\n            };\n        });\n    };\n\n    BootstrapTable.prototype.initBody = function () {\n        var that = this;\n        _initBody.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.editable) {\n            return;\n        }\n\n        $.each(this.options.columns, function (i, column) {\n            if (!column.editable) {\n                return;\n            }\n\n            that.$body.find('a[data-name=\"' + column.field + '\"]').editable(column.editable)\n                .off('save').on('save', function (e, params) {\n                    var data = that.getData(),\n                        index = $(this).parents('tr[data-index]').data('index'),\n                        row = data[index],\n                        oldValue = row[column.field];\n\n                    row[column.field] = params.submitValue;\n                    that.trigger('editable-save', column.field, row, oldValue, $(this));\n                });\n        });\n        this.trigger('editable-init');\n    };\n\n}(jQuery);\n\n/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * extensions: https://github.com/kayalshri/tableExport.jquery.plugin\n */\n\n(function ($) {\n    'use strict';\n\n    var TYPE_NAME = {\n        json: 'JSON',\n        xml: 'XML',\n        png: 'PNG',\n        csv: 'CSV',\n        txt: 'TXT',\n        sql: 'SQL',\n        doc: 'MS-Word',\n        excel: 'Ms-Excel',\n        powerpoint: 'Ms-Powerpoint',\n        pdf: 'PDF'\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        showExport: false,\n        // 'json', 'xml', 'png', 'csv', 'txt', 'sql', 'doc', 'excel', 'powerpoint', 'pdf'\n        exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'],\n        exportOptions: {}\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initToolbar = BootstrapTable.prototype.initToolbar;\n\n    BootstrapTable.prototype.initToolbar = function () {\n        this.showToolbar = this.options.showExport;\n\n        _initToolbar.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.showExport) {\n            var that = this,\n                $btnGroup = this.$toolbar.find('>.btn-group'),\n                $export = $btnGroup.find('div.export');\n\n            if (!$export.length) {\n                $export = $([\n                    '<div class=\"export btn-group\">',\n                        '<button class=\"btn btn-default dropdown-toggle\" ' +\n                            'data-toggle=\"dropdown\" type=\"button\">',\n                            '<i class=\"glyphicon glyphicon-export icon-share\"></i> ',\n                            '<span class=\"caret\"></span>',\n                        '</button>',\n                        '<ul class=\"dropdown-menu\" role=\"menu\">',\n                        '</ul>',\n                    '</div>'].join('')).appendTo($btnGroup);\n\n                var $menu = $export.find('.dropdown-menu'),\n                    exportTypes = this.options.exportTypes;\n\n                if (typeof this.options.exportTypes === 'string') {\n                    var types = this.options.exportTypes.slice(1, -1).replace(/ /g, '').split(',');\n\n                    exportTypes = [];\n                    $.each(types, function (i, value) {\n                        exportTypes.push(value.slice(1, -1));\n                    });\n                }\n                $.each(exportTypes, function (i, type) {\n                    if (TYPE_NAME.hasOwnProperty(type)) {\n                        $menu.append(['<li data-type=\"' + type + '\">',\n                                '<a href=\"javascript:void(0)\">',\n                                    TYPE_NAME[type],\n                                '</a>',\n                            '</li>'].join(''));\n                    }\n                });\n\n                $menu.find('li').click(function () {\n                    that.$el.tableExport($.extend({}, that.options.exportOptions, {\n                        type: $(this).data('type'),\n                        escape: false\n                    }));\n                });\n            }\n        }\n    };\n})(jQuery);\n\n/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.0.0\n */\n\n!function ($) {\n\n    'use strict';\n\n    var sprintf = function (str) {\n        var args = arguments,\n            flag = true,\n            i = 1;\n\n        str = str.replace(/%s/g, function () {\n            var arg = args[i++];\n\n            if (typeof arg === 'undefined') {\n                flag = false;\n                return '';\n            }\n            return arg;\n        });\n        return flag ? str : '';\n    };\n\n    var getFieldIndex = function (columns, field) {\n        var index = -1;\n\n        $.each(columns, function (i, column) {\n            if (column.field === field) {\n                index = i;\n                return false;\n            }\n            return true;\n        });\n        return index;\n    };\n\n    var calculateObjectValue = function (self, name, args, defaultValue) {\n        if (typeof name === 'string') {\n            // support obj.func1.func2\n            var names = name.split('.');\n\n            if (names.length > 1) {\n                name = window;\n                $.each(names, function (i, f) {\n                    name = name[f];\n                });\n            } else {\n                name = window[name];\n            }\n        }\n        if (typeof name === 'object') {\n            return name;\n        }\n        if (typeof name === 'function') {\n            return name.apply(self, args);\n        }\n        return defaultValue;\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        filterControl: false,\n        onColumnSearch: function (field, text) {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {\n        filterControl: undefined,\n        filterData: undefined\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'column-search.bs.table': 'onColumnSearch'\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initHeader = BootstrapTable.prototype.initHeader,\n        _initBody = BootstrapTable.prototype.initBody,\n        _initSearch = BootstrapTable.prototype.initSearch;\n\n    BootstrapTable.prototype.initHeader = function () {\n        _initHeader.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.filterControl) {\n            return;\n        }\n\n        var addedFilterControl = false,\n            that = this,\n            isVisible,\n            html,\n            timeoutId = 0;\n\n        $.each(this.options.columns, function (i, column) {\n            isVisible = 'hidden';\n            html = [];\n\n            if (!column.visible) {\n                return;\n            }\n\n            if (!column.filterControl) {\n                html.push('<div style=\"height: 34px;\"></div>');\n            } else {\n                html.push('<div style=\"margin: 0px 2px 2px 2px;\" class=\"filterControl\">');\n\n                if (column.filterControl && column.searchable) {\n                    addedFilterControl = true;\n                    isVisible = 'visible'\n                }\n                switch (column.filterControl.toLowerCase()) {\n                    case 'input' :\n                        html.push(sprintf('<input type=\"text\" class=\"form-control\" style=\"width: 100%; visibility: %s\">', isVisible));\n                        break;\n                    case 'select':\n                        html.push(sprintf('<select class=\"%s form-control\" style=\"width: 100%; visibility: %s\"></select>',\n                            column.field, isVisible))\n                        break;\n                }\n            }\n\n            that.$header.find(sprintf('.th-inner:eq(\"%s\")', i)).next().append(html.join(''));\n            if (column.filterData !== undefined && column.filterData.toLowerCase() !== 'column') {\n                var filterDataType = column.filterData.substring(0, 3);\n                var filterDataSource = column.filterData.substring(4, column.filterData.length);\n                var selectControl = $('.' + column.field);\n                selectControl.append($(\"<option></option>\")\n                    .attr(\"value\", '')\n                    .text(''));\n                switch (filterDataType) {\n                    case 'url':\n                        $.ajax({\n                            url: filterDataSource,\n                            dataType: 'json',\n                            success: function (data) {\n                                $.each(data, function (key, value) {\n                                    selectControl.append($(\"<option></option>\")\n                                        .attr(\"value\", key)\n                                        .text(value));\n                                });\n                            }\n                        });\n                        break;\n                    case 'var':\n                        var variableValues = window[filterDataSource];\n                        for (var key in variableValues) {\n                            selectControl.append($(\"<option></option>\")\n                                .attr(\"value\", key)\n                                .text(variableValues[key]));\n                        };\n                        break;\n                }\n            }\n        });\n\n        if (addedFilterControl) {\n            this.$header.off('keyup', 'input').on('keyup', 'input', function (event) {\n                clearTimeout(timeoutId);\n                timeoutId = setTimeout(function () {\n                    that.onColumnSearch(event);\n                }, that.options.searchTimeOut);\n            });\n\n            this.$header.off('change', 'select').on('change', 'select', function (event) {\n                clearTimeout(timeoutId);\n                timeoutId = setTimeout(function () {\n                    that.onColumnSearch(event);\n                }, that.options.searchTimeOut);\n            });\n        } else {\n            this.$header.find('.filterControl').hide();\n        }\n    };\n\n    BootstrapTable.prototype.initBody = function () {\n        _initBody.apply(this, Array.prototype.slice.apply(arguments));\n\n        var that = this,\n            data = this.getData();\n\n        for (var i = this.pageFrom - 1; i < this.pageTo; i++) {\n            var key,\n                item = data[i];\n\n            $.each(this.header.fields, function (j, field) {\n                var value = item[field],\n                    column = that.options.columns[getFieldIndex(that.options.columns, field)];\n\n                value = calculateObjectValue(that.header,\n                    that.header.formatters[j], [value, item, i], value);\n\n                if ((!column.checkbox) || (!column.radio)) {\n                    if (column.filterControl !== undefined && column.filterControl.toLowerCase() === 'select'\n                            && column.searchable) {\n\n                        if (column.filterData === undefined || column.filterData.toLowerCase() === 'column') {\n                            var selectControl = $('.' + column.field),\n                                    iOpt = 0,\n                                    exitsOpt = false,\n                                    options;\n                            if (selectControl !== undefined) {\n                                options = selectControl.get(0).options;\n\n                                if (options.length === 0) {\n\n                                    //Added the default option\n                                    selectControl.append($(\"<option></option>\")\n                                        .attr(\"value\", '')\n                                        .text(''));\n\n                                    selectControl.append($(\"<option></option>\")\n                                        .attr(\"value\", value)\n                                        .text(value));\n                                } else {\n                                    for (; iOpt < options.length; iOpt++) {\n                                        if (options[iOpt].value === value) {\n                                            exitsOpt = true;\n                                            break;\n                                        }\n                                    }\n\n                                    if (!exitsOpt) {\n                                        selectControl.append($(\"<option></option>\")\n                                            .attr(\"value\", value)\n                                            .text(value));\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            });\n        }\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        _initSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        var that = this;\n        var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial;\n\n        //Check partial column filter\n        this.data = fp ? $.grep(this.data, function (item, i) {\n            for (var key in fp) {\n                var fval = fp[key].toLowerCase();\n                var value = item[key];\n                value = calculateObjectValue(that.header,\n                    that.header.formatters[$.inArray(key, that.header.fields)],\n                    [value, item, i], value);\n\n                if (!($.inArray(key, that.header.fields) !== -1 &&\n                    (typeof value === 'string' || typeof value === 'number') &&\n                    (value + '').toLowerCase().indexOf(fval) !== -1)) {\n                    return false;\n                }\n            }\n            return true;\n        }) : this.data;\n    };\n\n    BootstrapTable.prototype.onColumnSearch = function (event) {\n        var text = $.trim($(event.currentTarget).val());\n        var $field = $(event.currentTarget).parent().parent().parent().data('field')\n\n        if ($.isEmptyObject(this.filterColumnsPartial)) {\n            this.filterColumnsPartial = {};\n        }\n        if (text) {\n            this.filterColumnsPartial[$field] = text;\n        } else {\n            delete this.filterColumnsPartial[$field];\n        }\n\n        this.options.pageNumber = 1;\n        this.onSearch(event);\n        this.updatePagination();\n        this.trigger('column-search', $field, text);\n    };\n}(jQuery);\n\n/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * extensions: https://github.com/lukaskral/bootstrap-table-filter\n */\n\n!function($) {\n\n    'use strict';\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        showFilter: false\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _init = BootstrapTable.prototype.init,\n        _initSearch = BootstrapTable.prototype.initSearch;\n\n    BootstrapTable.prototype.init = function () {\n        _init.apply(this, Array.prototype.slice.apply(arguments));\n\n        var that = this;\n        this.$el.on('load-success.bs.table', function () {\n            if (that.options.showFilter) {\n                $(that.options.toolbar).bootstrapTableFilter({\n                    connectTo: that.$el\n                });\n            }\n        });\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        _initSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.sidePagination !== 'server') {\n            if (typeof this.searchCallback === 'function') {\n                this.data = $.grep(this.options.data, this.searchCallback);\n            }\n        }\n    };\n\n    BootstrapTable.prototype.getData = function () {\n        return (this.searchText || this.searchCallback) ? this.data : this.options.data;\n    };\n\n    BootstrapTable.prototype.getColumns = function () {\n        return this.options.columns;\n    };\n\n    BootstrapTable.prototype.registerSearchCallback = function (callback) {\n        this.searchCallback = callback;\n    };\n\n    BootstrapTable.prototype.updateSearch = function () {\n        this.options.pageNumber = 1;\n        this.initSearch();\n        this.updatePagination();\n    };\n\n    BootstrapTable.prototype.getServerUrl = function () {\n        return (this.options.sidePagination === 'server') ? this.options.url : false;\n    };\n\n    $.fn.bootstrapTable.methods.push('getColumns',\n        'registerSearchCallback', 'updateSearch',\n        'getServerUrl');\n\n}(jQuery);\n/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.2.0\n */\n\n\n(function ($) {\n    'use strict';\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        flat: false\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initData = BootstrapTable.prototype.initData;\n\n    BootstrapTable.prototype.initData = function (data, type) {\n        if( this.options.flat ){\n            data = data === undefined ? this.options.data : data;\n            data = sd.flatHelper(data);\n        }\n        _initData.apply(this, [data, type]);\n    };\n\n    //Main functions\n    var sd = {\n        flat: function (element) {\n            var result = {};\n\n            function recurse(cur, prop) {\n                if (Object(cur) !== cur) {\n                    result[prop] = cur;\n                } else if ($.isArray(cur)) {\n                    for (var i = 0, l = cur.length; i < l; i++) {\n                        recurse(cur[i], prop ? prop + \".\" + i : \"\" + i);\n                        if (l == 0) {\n                            result[prop] = [];\n                        }\n                    }\n                } else {\n                    var isEmpty = true;\n                    for (var p in cur) {\n                        isEmpty = false;\n                        recurse(cur[p], prop ? prop + \".\" + p : p);\n                    }\n                    if (isEmpty) {\n                        result[prop] = {};\n                    }\n                }\n            }\n\n            recurse(element, \"\");\n            return result;\n        },\n\n        flatHelper: function (data) {\n            var flatArray = [],\n                arrayHelper = [];\n            if (!$.isArray(data)) {\n                arrayHelper.push(data);\n                data = arrayHelper;\n            }\n            $.each(data, function (i, element) {\n                flatArray.push(sd.flat(element));\n            });\n            return flatArray;\n        }\n    };\n})(jQuery);\n\n/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.0.0\n *\n * @update zhixin wen <wenzhixin2010@gmail.com>\n */\n\n!function ($) {\n\n    'use strict';\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        keyEvents: false\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _init = BootstrapTable.prototype.init;\n\n    BootstrapTable.prototype.init = function () {\n        _init.apply(this, Array.prototype.slice.apply(arguments));\n\n        this.initKeyEvents();\n    };\n\n    BootstrapTable.prototype.initKeyEvents = function () {\n        if (this.options.keyEvents) {\n            var that = this;\n\n            $(document).off('keydown').on('keydown', function (e) {\n                var $search = that.$toolbar.find('.search input'),\n                    $refresh = that.$toolbar.find('button[name=\"refresh\"]'),\n                    $toggle = that.$toolbar.find('button[name=\"toggle\"]'),\n                    $paginationSwitch = that.$toolbar.find('button[name=\"paginationSwitch\"]');\n\n                if (document.activeElement === $search.get(0)) {\n                    return true;\n                }\n\n                switch (e.keyCode) {\n                    case 83: //s\n                        if (!that.options.search) {\n                            return;\n                        }\n                        $search.focus();\n                        return false;\n                    case 82: //r\n                        if (!that.options.showRefresh) {\n                            return;\n                        }\n                        $refresh.click();\n                        return false;\n                    case 84: //t\n                        if (!that.options.showToggle) {\n                            return;\n                        }\n                        $toggle.click();\n                        return false;\n                    case 80: //p\n                        if (!that.options.showPaginationSwitch) {\n                            return;\n                        }\n                        $paginationSwitch.click();\n                        return false;\n                    case 37: // left\n                        if (!that.options.pagination) {\n                            return;\n                        }\n                        that.prevPage();\n                        return false;\n                    case 39: // right\n                        if (!that.options.pagination) {\n                            return;\n                        }\n                        that.nextPage();\n                        return;\n                }\n            });\n        }\n    };\n}(jQuery);\n\n/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.1.0\n */\n\n!function ($) {\n\n    'use strict';\n\n    var resetView = function (that) {\n        if (that.options.height || that.options.showFooter) {\n            setTimeout(that.resetView(), 1);\n        }\n    };\n\n    var changeView = function (that, width, height) {\n        if (that.options.minHeight) {\n            if (checkValuesLessEqual(width, that.options.minWidth) && checkValuesLessEqual(height, that.options.minHeight)) {\n                conditionCardView(that);\n            } else if (checkValuesGreater(width, that.options.minWidth) && checkValuesGreater(height, that.options.minHeight)) {\n                conditionFullView(that);\n            }\n        } else {\n            if (checkValuesLessEqual(width, that.options.minWidth)) {\n                conditionCardView(that);\n            } else if (checkValuesGreater(width, that.options.minWidth)) {\n                conditionFullView(that);\n            }\n        }\n\n        resetView(that);\n    };\n\n    var checkValuesLessEqual = function (currentValue, targetValue) {\n        return currentValue <= targetValue;\n    };\n\n    var checkValuesGreater = function (currentValue, targetValue) {\n        return currentValue > targetValue;\n    };\n\n    var conditionCardView = function (that) {\n        changeTableView(that, false);\n    };\n\n    var conditionFullView = function (that) {\n        changeTableView(that, true);\n    };\n\n    var changeTableView = function (that, cardViewState) {\n        that.options.cardView = cardViewState;\n        that.toggleView();\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        mobileResponsive: false,\n        minWidth: 562,\n        minHeight: undefined,\n        checkOnInit: true,\n        toggled: false\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _init = BootstrapTable.prototype.init;\n\n    BootstrapTable.prototype.init = function () {\n        _init.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.mobileResponsive) {\n            return;\n        }\n\n        if (!this.options.minWidth) {\n            return;\n        }\n\n        var that = this;\n        $(window).resize(function () {\n            changeView(that, $(this).width(), $(this).height())\n        });\n\n        if (this.options.checkOnInit) {\n            changeView(this, $(window).width(), $(window).height());\n        }\n    };\n}(jQuery);\n\n/**\n * @author Nadim Basalamah <dimbslmh@gmail.com>\n * @version: v1.0.0\n * https://github.com/dimbslmh/bootstrap-table/tree/master/src/extensions/multiple-sort/bootstrap-table-multiple-sort.js\n */\n\n(function($) {\n    'use strict';\n\n    var isSingleSort = false;\n\n    var sort_order = {\n            asc: 'Ascending',\n            desc: 'Descending'\n        },\n        arrowAsc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ' +\n        '0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBd' +\n        'qEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVo' +\n        'AADeemwtPcZI2wAAAABJRU5ErkJggg==',\n        arrowDesc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWj' +\n        'YBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJ' +\n        'zcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= ';\n\n    var showSortModal = function(that) {\n        if (!$(\"#sortModal\").hasClass(\"modal\")) {\n            var sModal = '  <div class=\"modal fade\" id=\"sortModal\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"sortModalLabel\" aria-hidden=\"true\">';\n            sModal += '         <div class=\"modal-dialog\">';\n            sModal += '             <div class=\"modal-content\">';\n            sModal += '                 <div class=\"modal-header\">';\n            sModal += '                     <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\"><span aria-hidden=\"true\">&times;</span></button>';\n            sModal += '                     <h4 class=\"modal-title\" id=\"sortModalLabel\">' + that.options.formatMultipleSort() + '</h4>';\n            sModal += '                 </div>';\n            sModal += '                 <div class=\"modal-body\">';\n            sModal += '                     <div class=\"bootstrap-table\">';\n            sModal += '                         <div class=\"fixed-table-toolbar\">';\n            sModal += '                             <div class=\"bars\">';\n            sModal += '                                 <div id=\"toolbar\">';\n            sModal += '                                     <button id=\"add\" type=\"button\" class=\"btn btn-default\"><i class=\"' + that.options.iconsPrefix + ' ' + that.options.icons.plus + '\"></i> ' + that.options.formatAddLevel() + '</button>';\n            sModal += '                                     <button id=\"delete\" type=\"button\" class=\"btn btn-default\" disabled><i class=\"' + that.options.iconsPrefix + ' ' + that.options.icons.minus + '\"></i> ' + that.options.formatDeleteLevel() + '</button>';\n            sModal += '                                 </div>';\n            sModal += '                             </div>';\n            sModal += '                         </div>';\n            sModal += '                         <div class=\"fixed-table-container\">';\n            sModal += '                             <table id=\"multi-sort\" class=\"table\">';\n            sModal += '                                 <thead>';\n            sModal += '                                     <tr>';\n            sModal += '                                         <th></th>';\n            sModal += '                                         <th><div class=\"th-inner\">' + that.options.formatColumn() + '</div></th>';\n            sModal += '                                         <th><div class=\"th-inner\">' + that.options.formatOrder() + '</div></th>';\n            sModal += '                                     </tr>';\n            sModal += '                                 </thead>';\n            sModal += '                                 <tbody></tbody>';\n            sModal += '                             </table>';\n            sModal += '                         </div>';\n            sModal += '                     </div>';\n            sModal += '                 </div>';\n            sModal += '                 <div class=\"modal-footer\">';\n            sModal += '                     <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">' + that.options.formatCancel() + '</button>';\n            sModal += '                     <button type=\"button\" class=\"btn btn-primary\">' + that.options.formatSort() + '</button>';\n            sModal += '                 </div>';\n            sModal += '             </div>';\n            sModal += '         </div>';\n            sModal += '     </div>';\n\n            $(\"body\").append($(sModal));\n\n            var $sortModal = $('#sortModal'),\n                $rows = $sortModal.find(\"tbody > tr\");\n\n            $sortModal.off('click', '#add').on('click', '#add', function() {\n                var total = $sortModal.find('.multi-sort-name:first option').length,\n                    current = $sortModal.find('tbody tr').length;\n\n                if (current < total) {\n                    current++;\n                    that.addLevel();\n                    that.setButtonStates();\n                }\n            });\n\n            $sortModal.off('click', '#delete').on('click', '#delete', function() {\n                var total = $sortModal.find('.multi-sort-name:first option').length,\n                    current = $sortModal.find('tbody tr').length;\n\n                if (current > 1 && current <= total) {\n                    current--;\n                    $sortModal.find('tbody tr:last').remove();\n                    that.setButtonStates();\n                }\n            });\n\n            $sortModal.off('click', '.btn-primary').on('click', '.btn-primary', function() {\n                var $rows = $sortModal.find(\"tbody > tr\"),\n                    $alert = $sortModal.find('div.alert'),\n                    fields = [],\n                    results = [];\n\n\n                that.options.sortPriority = $.map($rows, function(row) {\n                    var $row = $(row),\n                        name = $row.find('.multi-sort-name').val(),\n                        order = $row.find('.multi-sort-order').val();\n\n                    fields.push(name);\n\n                    return {\n                        sortName: name,\n                        sortOrder: order\n                    };\n                });\n\n                var sorted_fields = fields.sort();\n\n                for (var i = 0; i < fields.length - 1; i++) {\n                    if (sorted_fields[i + 1] == sorted_fields[i]) {\n                        results.push(sorted_fields[i]);\n                    }\n                }\n\n                if (results.length > 0) {\n                    if ($alert.length === 0) {\n                        $alert = '<div class=\"alert alert-danger\" role=\"alert\"><strong>' + that.options.formatDuplicateAlertTitle() + '</strong> ' + that.options.formatDuplicateAlertDescription() + '</div>';\n                        $($alert).insertBefore($sortModal.find('.bars'));\n                    }\n                } else {\n                    if ($alert.length === 1) {\n                        $($alert).remove();\n                    }\n\n                    that.options.sortName = \"\";\n                    that.onMultipleSort();\n                    $sortModal.modal('hide');\n                }\n            });\n\n            if (that.options.sortPriority === null) {\n                if (that.options.sortName) {\n                    that.options.sortPriority = [{\n                        sortName: that.options.sortName,\n                        sortOrder: that.options.sortOrder\n                    }];\n                }\n            }\n            \n            if (that.options.sortPriority !== null) {\n                if ($rows.length < that.options.sortPriority.length && typeof that.options.sortPriority === 'object') {\n                    for (var i = 0; i < that.options.sortPriority.length; i++) {\n                        that.addLevel(i, that.options.sortPriority[i]);\n                    }\n                }\n            } else {\n                that.addLevel(0);\n            }\n\n            that.setButtonStates();\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        showMultiSort: false,\n        sortPriority: null,\n        onMultipleSort: function() {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.defaults.icons, {\n        sort: 'glyphicon-sort',\n        plus: 'glyphicon-plus',\n        minus: 'glyphicon-minus'\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'multiple-sort.bs.table': 'onMultipleSort'\n    });\n\n    $.extend($.fn.bootstrapTable.locales, {\n        formatMultipleSort: function() {\n            return 'Multiple Sort';\n        },\n        formatAddLevel: function() {\n            return \"Add Level\";\n        },\n        formatDeleteLevel: function() {\n            return \"Delete Level\";\n        },\n        formatColumn: function() {\n            return \"Column\";\n        },\n        formatOrder: function() {\n            return \"Order\";\n        },\n        formatSortBy: function() {\n            return \"Sort by\";\n        },\n        formatThenBy: function() {\n            return \"Then by\";\n        },\n        formatSort: function() {\n            return \"Sort\";\n        },\n        formatCancel: function() {\n            return \"Cancel\";\n        },\n        formatDuplicateAlertTitle: function() {\n            return \"Duplicate(s) detected!\";\n        },\n        formatDuplicateAlertDescription: function() {\n            return \"Please remove or change any duplicate column.\";\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initToolbar = BootstrapTable.prototype.initToolbar;\n\n    BootstrapTable.prototype.initToolbar = function() {\n        this.showToolbar = true;\n        var that = this;\n\n        _initToolbar.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.showMultiSort) {\n            var $btnGroup = this.$toolbar.find('>.btn-group'),\n                $multiSortBtn = $btnGroup.find('div.multi-sort');\n\n            if (!$multiSortBtn.length) {\n                $multiSortBtn = '  <button class=\"multi-sort btn btn-default' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + '\" type=\"button\" data-toggle=\"modal\" data-target=\"#sortModal\" title=\"' + this.options.formatMultipleSort() + '\">';\n                $multiSortBtn += '     <i class=\"' + this.options.iconsPrefix + ' ' + this.options.icons.sort + '\"></i>';\n                $multiSortBtn += '</button>';\n\n                $btnGroup.append($multiSortBtn);\n\n                showSortModal(that);\n            }\n\n            this.$el.one('sort.bs.table', function() {\n                isSingleSort = true;\n            });\n\n            this.$el.on('multiple-sort.bs.table', function() {\n                isSingleSort = false;\n            });\n\n            this.$el.on('load-success.bs.table', function() {\n                if (!isSingleSort && that.options.sortPriority !== null && typeof that.options.sortPriority === 'object') {\n                    that.onMultipleSort();\n                }\n            });\n\n            this.$el.on('column-switch.bs.table', function() {\n                that.options.sortPriority = null;\n                $('#sortModal').remove();\n                showSortModal(that);\n            });\n        }\n    };\n\n    BootstrapTable.prototype.onMultipleSort = function() {\n        var that = this;\n        \n        var cmp = function(x, y) {\n            return x > y ? 1 : x < y ? -1 : 0;\n        };\n\n        var arrayCmp = function(a, b) {\n            var arr1 = [],\n                arr2 = [];\n\n            for (var i = 0; i < that.options.sortPriority.length; i++) {\n                var order = that.options.sortPriority[i].sortOrder === 'desc' ? -1 : 1,\n                    aa = a[that.options.sortPriority[i].sortName],\n                    bb = b[that.options.sortPriority[i].sortName];\n\n                if (aa === undefined || aa === null) {\n                    aa = '';\n                }\n                if (bb === undefined || bb === null) {\n                    bb = '';\n                }\n                if ($.isNumeric(aa) && $.isNumeric(bb)) {\n                    aa = parseFloat(aa);\n                    bb = parseFloat(bb);\n                }\n                if (typeof aa !== 'string') {\n                    aa = aa.toString();\n                }\n\n                arr1.push(\n                    order * cmp(aa, bb));\n                arr2.push(\n                    order * cmp(bb, aa));\n            }\n\n            return cmp(arr1, arr2);\n        };\n\n        this.data.sort(function(a, b) {\n            return arrayCmp(a, b);\n        });\n\n        this.initBody();\n        this.assignSortableArrows();\n        this.trigger('multiple-sort');\n    };\n\n    BootstrapTable.prototype.addLevel = function(index, sortPriority) {\n        var $sortModal = $(\"#sortModal\"),\n            text = index === 0 ? this.options.formatSortBy() : this.options.formatThenBy();\n\n        $sortModal.find('tbody')\n            .append($('<tr>')\n                .append($('<td>').text(text))\n                .append($('<td>').append($('<select class=\"form-control multi-sort-name\">')))\n                .append($('<td>').append($('<select class=\"form-control multi-sort-order\">')))\n            );\n\n        var $multiSortName = $sortModal.find('.multi-sort-name').last(),\n            $multiSortOrder = $sortModal.find('.multi-sort-order').last();\n\n        this.options.columns.forEach(function(column) {\n            if (column.sortable === false || column.visible === false) {\n                return true;\n            }\n            $multiSortName.append('<option value=\"' + column.field + '\">' + column.title + '</option>');\n        });\n\n        $.each(sort_order, function(value, order) {\n            $multiSortOrder.append('<option value=\"' + value + '\">' + order + '</option>');\n        });\n\n        if (sortPriority !== undefined) {\n            $multiSortName.find('option[value=\"' + sortPriority.sortName + '\"]').attr(\"selected\", true);\n            $multiSortOrder.find('option[value=\"' + sortPriority.sortOrder + '\"]').attr(\"selected\", true);\n        }\n    };\n\n    BootstrapTable.prototype.assignSortableArrows = function() {\n        var that = this,\n            headers = that.$header.find('th');\n\n        for (var i = 0; i < headers.length; i++) {\n            for (var c = 0; c < that.options.sortPriority.length; c++) {\n                if ($(headers[i]).data('field') === that.options.sortPriority[c].sortName) {\n                    $(headers[i]).find('.sortable').css('background-image', 'url(' + (that.options.sortPriority[c].sortOrder === 'desc' ? arrowDesc : arrowAsc) + ')');\n                }\n            }\n        }\n    };\n\n    BootstrapTable.prototype.setButtonStates = function() {\n        var $sortModal = $('#sortModal'),\n            total = $sortModal.find('.multi-sort-name:first option').length,\n            current = $sortModal.find('tbody tr').length;\n\n        if (current == total) {\n            $sortModal.find('#add').attr('disabled', 'disabled');\n        }\n        if (current > 1) {\n            $sortModal.find('#delete').removeAttr('disabled');\n        }\n        if (current < total) {\n            $sortModal.find('#add').removeAttr('disabled');\n        }\n        if (current == 1) {\n            $sortModal.find('#delete').attr('disabled', 'disabled');\n        }\n    };\n})(jQuery);\n\n/**\n * @author: Brian Huisman\n * @webSite: http://www.greywyvern.com\n * @version: v1.0.0\n * JS function to allow natural sorting on bootstrap-table columns\n * just add data-sorter=\"alphanum\" to any th\n *\n * @update Dennis Hernández <http://djhvscf.github.io/Blog>\n */\n\nfunction alphanum(a, b) {\n  function chunkify(t) {\n    var tz = [],\n        x = 0,\n        y = -1,\n        n = 0,\n        i,\n        j;\n\n    while (i = (j = t.charAt(x++)).charCodeAt(0)) {\n      var m = (i === 46 || (i >= 48 && i <= 57));\n      if (m !== n) {\n        tz[++y] = \"\";\n        n = m;\n      }\n      tz[y] += j;\n    }\n    return tz;\n  }\n\n  var aa = chunkify(a);\n  var bb = chunkify(b);\n\n  for (x = 0; aa[x] && bb[x]; x++) {\n    if (aa[x] !== bb[x]) {\n      var c = Number(aa[x]),\n          d = Number(bb[x]);\n\n      if (c == aa[x] && d == bb[x]) {\n        return c - d;\n      } else {\n          return (aa[x] > bb[x]) ? 1 : -1;\n      }\n    }\n  }\n  return aa.length - bb.length;\n}\n/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.1.0\n */\n\n!function ($) {\n\n    'use strict';\n\n    var getFieldIndex = function (columns, field) {\n        var index = -1;\n\n        $.each(columns, function (i, column) {\n            if (column.field === field) {\n                index = i;\n                return false;\n            }\n            return true;\n        });\n        return index;\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        reorderableColumns: false,\n        maxMovingRows: 10,\n        onReorderColumn: function (headerFields) {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'reorder-column.bs.table': 'onReorderColumn'\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initHeader = BootstrapTable.prototype.initHeader,\n        _toggleColumn = BootstrapTable.prototype.toggleColumn,\n        _toggleView = BootstrapTable.prototype.toggleView,\n        _resetView = BootstrapTable.prototype.resetView;\n\n    BootstrapTable.prototype.initHeader = function () {\n        _initHeader.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableColumns) {\n            return;\n        }\n\n        this.makeRowsReorderable();\n    };\n\n    BootstrapTable.prototype.toggleColumn = function () {\n        _toggleColumn.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableColumns) {\n            return;\n        }\n\n        this.makeRowsReorderable();\n    };\n\n    BootstrapTable.prototype.toggleView = function () {\n        _toggleView.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableColumns) {\n            return;\n        }\n\n        if (this.options.cardView) {\n            return;\n        }\n\n        this.makeRowsReorderable();\n    };\n\n    BootstrapTable.prototype.resetView = function () {\n        _resetView.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableColumns) {\n            return;\n        }\n\n        this.makeRowsReorderable();\n    };\n\n    BootstrapTable.prototype.makeRowsReorderable = function () {\n\n        var that = this;\n        try {\n            $(this.$el).dragtable('destroy');\n        } catch (e) {}\n        $(this.$el).dragtable({\n            maxMovingRows: that.options.maxMovingRows,\n            clickDelay:200,\n            beforeStop: function() {\n                var ths = [],\n                    columns = [],\n                    columnIndex = -1;\n                that.$header.find('th').each(function (i) {\n                    ths.push($(this).data('field'));\n                });\n\n                for (var i = 0; i < ths.length; i++ ) {\n                    columnIndex = getFieldIndex(that.options.columns, ths[i]);\n                    if (columnIndex !== -1) {\n                        columns.push(that.options.columns[columnIndex]);\n                        that.options.columns.splice(columnIndex, 1);\n                    }\n                }\n\n                that.options.columns = that.options.columns.concat(columns);\n                that.header.fields = ths;\n                that.resetView();\n                that.trigger('reorder-column', ths);\n            }\n        });\n    };\n}(jQuery);\n/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.0.0\n */\n\n!function ($) {\n\n    'use strict';\n\n    var isSearch = false;\n\n    var rowAttr = function (row, index) {\n        return {\n            id: 'customId_' + index\n        };\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        reorderableRows: false,\n        onDragStyle: null,\n        onDropStyle: null,\n        onDragClass: \"reorder_rows_onDragClass\",\n        dragHandle: null,\n        useRowAttrFunc: false,\n        onReorderRowsDrag: function (table, row) {\n            return false;\n        },\n        onReorderRowsDrop: function (table, row) {\n            return false;\n        },\n        onReorderRow: function (newData) {\n             return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'reorder-row.bs.table': 'onReorderRow'\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _init = BootstrapTable.prototype.init,\n        _initSearch = BootstrapTable.prototype.initSearch;\n\n    BootstrapTable.prototype.init = function () {\n\n        _init.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableRows) {\n            return;\n        }\n\n        var that = this;\n        if (this.options.useRowAttrFunc) {\n            this.options.rowAttributes = rowAttr;\n        }\n\n        var onPostBody = this.options.onPostBody;\n        this.options.onPostBody = function () {\n            setTimeout(function () {\n                that.makeRowsReorderable();\n                onPostBody.apply();\n            }, 1);\n        };\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        _initSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableRows) {\n            return;\n        }\n\n        //Known issue after search if you reorder the rows the data is not display properly\n        //isSearch = true;\n    };\n\n    BootstrapTable.prototype.makeRowsReorderable = function () {\n        if (this.options.cardView) {\n            return;\n        }\n\n        var that = this;\n        this.$el.tableDnD({\n            onDragStyle: that.options.onDragStyle,\n            onDropStyle: that.options.onDropStyle,\n            onDragClass: that.options.onDragClass,\n            onDrop: that.onDrop,\n            onDragStart: that.options.onReorderRowsDrag,\n            dragHandle: that.options.dragHandle\n        });\n    };\n\n    BootstrapTable.prototype.onDrop = function (table, row) {\n        var tableBs = $(table),\n            tableBsData = tableBs.data('bootstrap.table'),\n            tableBsOptions = tableBs.data('bootstrap.table').options,\n            row = null,\n            newData = [];\n\n        for (var i = 0; i < table.tBodies[0].rows.length; i++) {\n            row = $(table.tBodies[0].rows[i]);\n            newData.push(tableBsOptions.data[row.data('index')]);\n            row.data('index', i).attr('data-index', i);\n        }\n\n        tableBsOptions.data = newData;\n\n        //Call the user defined function\n        tableBsOptions.onReorderRowsDrop.apply(table, row);\n\n        //Call the event reorder-row\n        tableBsData.trigger('reorder-row', newData);\n    };\n}(jQuery);\n/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.0.0\n */\n\n(function ($) {\n    'use strict';\n\n    var initResizable = function (that) {\n        //Deletes the plugin to re-create it\n        that.$el.colResizable({disable: true});\n\n        //Creates the plugin\n        that.$el.colResizable({\n            liveDrag: that.options.liveDrag,\n            fixed: that.options.fixed,\n            headerOnly: that.options.headerOnly,\n            minWidth: that.options.minWidth,\n            hoverCursor: that.options.hoverCursor,\n            dragCursor: that.options.dragCursor,\n            onResize: that.onResize,\n            onDrag: that.options.onResizableDrag\n        });\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        resizable: false,\n        liveDrag: false,\n        fixed: true,\n        headerOnly: false,\n        minWidth: 15,\n        hoverCursor: 'e-resize',\n        dragCursor: 'e-resize',\n        onResizableResize: function (e) {\n            return false;\n        },\n        onResizableDrag: function (e) {\n            return false;\n        }\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _toggleView = BootstrapTable.prototype.toggleView,\n        _resetView = BootstrapTable.prototype.resetView;\n\n    BootstrapTable.prototype.toggleView = function () {\n        _toggleView.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.resizable && this.options.cardView) {\n            //Deletes the plugin\n            $(this.$el).colResizable({disable: true});\n        }\n    };\n\n    BootstrapTable.prototype.resetView = function () {\n        var that = this;\n\n        _resetView.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.resizable) {\n            // because in fitHeader function, we use setTimeout(func, 100);\n            setTimeout(function () {\n                initResizable(that);\n            }, 100);\n        }\n    };\n\n    BootstrapTable.prototype.onResize = function (e) {\n        var that = $(e.currentTarget);\n        that.bootstrapTable('resetView');\n        that.data('bootstrap.table').options.onResizableResize.apply(e);\n    }\n})(jQuery);\n\n/**\n * @author: aperez <aperez@datadec.es>\n * @version: v2.0.0\n *\n * @update Dennis Hernández <http://djhvscf.github.io/Blog>\n */\n\n!function($) {\n    'use strict';\n\n    var firstLoad = false;\n\n    var sprintf = function(str) {\n        var args = arguments,\n            flag = true,\n            i = 1;\n\n        str = str.replace(/%s/g, function() {\n            var arg = args[i++];\n\n            if (typeof arg === 'undefined') {\n                flag = false;\n                return '';\n            }\n            return arg;\n        });\n        return flag ? str : '';\n    };\n\n    var calculateObjectValue = function (self, name, args, defaultValue) {\n        if (typeof name === 'string') {\n            // support obj.func1.func2\n            var names = name.split('.');\n\n            if (names.length > 1) {\n                name = window;\n                $.each(names, function (i, f) {\n                    name = name[f];\n                });\n            } else {\n                name = window[name];\n            }\n        }\n        if (typeof name === 'object') {\n            return name;\n        }\n        if (typeof name === 'function') {\n            return name.apply(self, args);\n        }\n        return defaultValue;\n    };\n\n    var showAvdSearch = function(pColumns, searchTitle, searchText, that) {\n        if (!$(\"#avdSearchModal\").hasClass(\"modal\")) {\n            var vModal = \"<div id=\\\"avdSearchModal\\\" class=\\\"modal fade\\\" tabindex=\\\"-1\\\" role=\\\"dialog\\\" aria-labelledby=\\\"mySmallModalLabel\\\" aria-hidden=\\\"true\\\">\";\n            vModal += \"<div class=\\\"modal-dialog modal-xs\\\">\";\n            vModal += \" <div class=\\\"modal-content\\\">\";\n            vModal += \"  <div class=\\\"modal-header\\\">\";\n            vModal += \"   <button type=\\\"button\\\" class=\\\"close\\\" data-dismiss=\\\"modal\\\" aria-hidden=\\\"true\\\" >&times;</button>\";\n            vModal += sprintf(\"   <h4 class=\\\"modal-title\\\">%s</h4>\", searchTitle);\n            vModal += \"  </div>\";\n            vModal += \"  <div class=\\\"modal-body modal-body-custom\\\">\";\n            vModal += \"   <div class=\\\"container-fluid\\\" id=\\\"avdSearchModalContent\\\" style=\\\"padding-right: 0px;padding-left: 0px;\\\" >\";\n            vModal += \"   </div>\";\n            vModal += \"  </div>\";\n            vModal += \"  </div>\";\n            vModal += \" </div>\";\n            vModal += \"</div>\";\n\n            $(\"body\").append($(vModal));\n\n            var vFormAvd = createFormAvd(pColumns, searchText, that),\n                timeoutId = 0;;\n\n            $('#avdSearchModalContent').append(vFormAvd.join(''));\n\n            $('#' + that.options.idForm).off('keyup blur', 'input').on('keyup blur', 'input', function (event) {\n                clearTimeout(timeoutId);\n                timeoutId = setTimeout(function () {\n                    that.onColumnAdvancedSearch(event);\n                }, that.options.searchTimeOut);\n            });\n\n            $(\"#btnCloseAvd\").click(function() {\n                $(\"#avdSearchModal\").modal('hide');\n            });\n\n            $(\"#avdSearchModal\").modal();\n        } else {\n            $(\"#avdSearchModal\").modal();\n        }\n    };\n\n    var createFormAvd = function(pColumns, searchText, that) {\n        var htmlForm = [];\n        htmlForm.push(sprintf('<form class=\"form-horizontal\" id=\"%s\" action=\"%s\" >', that.options.idForm, that.options.actionForm));\n        for (var i in pColumns) {\n            var vObjCol = pColumns[i];\n            if (!vObjCol.checkbox && vObjCol.visible && vObjCol.searchable) {\n                htmlForm.push('<div class=\"form-group\">');\n                htmlForm.push(sprintf('<label class=\"col-sm-4 control-label\">%s</label>', vObjCol.title));\n                htmlForm.push('<div class=\"col-sm-6\">');\n                htmlForm.push(sprintf('<input type=\"text\" class=\"form-control input-md\" name=\"%s\" placeholder=\"%s\" id=\"%s\">', vObjCol.field, vObjCol.title, vObjCol.field));\n                htmlForm.push('</div>');\n                htmlForm.push('</div>');\n            }\n        }\n\n        htmlForm.push('<div class=\"form-group\">');\n        htmlForm.push('<div class=\"col-sm-offset-9 col-sm-3\">');\n        htmlForm.push(sprintf('<button type=\"button\" id=\"btnCloseAvd\" class=\"btn btn-default\" >%s</button>', searchText));\n        htmlForm.push('</div>');\n        htmlForm.push('</div>');\n        htmlForm.push('</form>');\n\n        return htmlForm;\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        advancedSearch: false,\n        idForm: 'advancedSearch',\n        actionForm: '',\n        idTable: undefined,\n        onColumnAdvancedSearch: function (field, text) {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.defaults.icons, {\n        advancedSearchIcon: 'glyphicon-chevron-down'\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'column-advanced-search.bs.table': 'onColumnAdvancedSearch'\n    });\n\n    $.extend($.fn.bootstrapTable.locales, {\n        formatAdvancedSearch: function() {\n            return 'Advanced search';\n        },\n        formatAdvancedCloseButton: function() {\n            return \"Close\";\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initToolbar = BootstrapTable.prototype.initToolbar,        \n        _load = BootstrapTable.prototype.load,\n        _initSearch = BootstrapTable.prototype.initSearch;\n\n    BootstrapTable.prototype.initToolbar = function() {\n        _initToolbar.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.search) {\n            return;\n        }\n\n        if (!this.options.advancedSearch) {\n            return;\n        }\n\n        var that = this,\n            html = [];\n\n        html.push(sprintf('<div class=\"columns columns-%s btn-group pull-%s\" role=\"group\">', this.options.buttonsAlign, this.options.buttonsAlign));\n        html.push(sprintf('<button class=\"btn btn-default%s' + '\" type=\"button\" name=\"advancedSearch\" title=\"%s\">', that.options.iconSize === undefined ? '' : ' btn-' + that.options.iconSize, that.options.formatAdvancedSearch()));\n        html.push(sprintf('<i class=\"%s %s\"></i>', that.options.iconsPrefix, that.options.icons.advancedSearchIcon))\n        html.push('</button></div>');\n\n        that.$toolbar.prepend(html.join(''));\n\n        that.$toolbar.find('button[name=\"advancedSearch\"]')\n            .off('click').on('click', function() {\n                showAvdSearch(that.options.columns, that.options.formatAdvancedSearch(), that.options.formatAdvancedCloseButton(), that);\n            });\n    };\n\n    BootstrapTable.prototype.load = function(data) {\n        _load.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (typeof this.options.idTable === 'undefined') {\n            return;\n        } else {\n            if (!firstLoad) {\n                var height = parseInt($(\".bootstrap-table\").height());\n                height += 10;\n                $(\"#\" + this.options.idTable).bootstrapTable(\"resetView\", {height: height});\n                firstLoad = true;\n            }\n        }\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        _initSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        var that = this;\n        var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial;\n\n        this.data = fp ? $.grep(this.data, function (item, i) {\n            for (var key in fp) {\n                var fval = fp[key].toLowerCase();\n                var value = item[key];\n                value = calculateObjectValue(that.header,\n                    that.header.formatters[$.inArray(key, that.header.fields)],\n                    [value, item, i], value);\n\n                if (!($.inArray(key, that.header.fields) !== -1 &&\n                    (typeof value === 'string' || typeof value === 'number') &&\n                    (value + '').toLowerCase().indexOf(fval) !== -1)) {\n                    return false;\n                }\n            }\n            return true;\n        }) : this.data;\n    };\n\n    BootstrapTable.prototype.onColumnAdvancedSearch = function (event) {\n        var text = $.trim($(event.currentTarget).val());\n        var $field = $(event.currentTarget)[0].id;\n\n        if ($.isEmptyObject(this.filterColumnsPartial)) {\n            this.filterColumnsPartial = {};\n        }\n        if (text) {\n            this.filterColumnsPartial[$field] = text;\n        } else {\n            delete this.filterColumnsPartial[$field];\n        }\n\n        this.options.pageNumber = 1;\n        this.onSearch(event);\n        this.updatePagination();\n        this.trigger('column-advanced-search', $field, text);\n    };\n}(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/bootstrap-table-locale-all.js",
    "content": "/**\n * Bootstrap Table English translation\n * Author: Zhixin Wen<wenzhixin2010@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ar-SA'] = {\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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ar-SA']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Czech translation\n * Author: Lukas Kral (monarcha@seznam.cz)\n * Author: Jakub Svestka <svestka1999@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['cs-CZ'] = {\n        formatLoadingMessage: function () {\n            return 'Čekejte, prosím...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' položek na stránku';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Zobrazena ' + pageFrom + '. - ' + pageTo + '. položka z celkových ' + totalRows;\n        },\n        formatSearch: function () {\n            return 'Vyhledávání';\n        },\n        formatNoMatches: function () {\n            return 'Nenalezena žádná vyhovující položka';\n        },\n        formatPaginationSwitch: function () {\n            return 'Skrýt/Zobrazit stránkování';\n        },\n        formatRefresh: function () {\n            return 'Aktualizovat';\n        },\n        formatToggle: function () {\n            return 'Přepni';\n        },\n        formatColumns: function () {\n            return 'Sloupce';\n        },\n        formatAllRows: function () {\n            return 'Vše';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['cs-CZ']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table danish translation\n * Author: Your Name Jan Borup Coyle, github@coyle.dk\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['da-DK'] = {\n        formatLoadingMessage: function () {\n            return 'Indlæser, vent venligst...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' poster pr side';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Viser ' + pageFrom + ' til ' + pageTo + ' af ' + totalRows + ' rækker';\n        },\n        formatSearch: function () {\n            return 'Søg';\n        },\n        formatNoMatches: function () {\n            return 'Ingen poster fundet';\n        },\n        formatRefresh: function () {\n            return 'Opdater';\n        },\n        formatToggle: function () {\n            return 'Skift';\n        },\n        formatColumns: function () {\n            return 'Kolonner';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['da-DK']);\n\n})(jQuery);\n/**\n* Bootstrap Table German translation\n* Author: Paul Mohr - Sopamo<p.mohr@sopamo.de>\n*/\n(function ($) {\n  'use strict';\n\n  $.fn.bootstrapTable.locales['de-DE'] = {\n    formatLoadingMessage: function () {\n      return 'Lade, bitte warten...';\n    },\n    formatRecordsPerPage: function (pageNumber) {\n      return pageNumber + ' Einträge pro Seite';\n    },\n    formatShowingRows: function (pageFrom, pageTo, totalRows) {\n      return 'Zeige ' + pageFrom + ' bis ' + pageTo + ' von ' + totalRows + ' Zeile' + ((totalRows > 1) ? \"n\" : \"\");\n    },\n    formatSearch: function () {\n      return 'Suchen';\n    },\n    formatNoMatches: function () {\n      return 'Keine passenden Ergebnisse gefunden';\n    },\n    formatRefresh: function () {\n      return 'Neu laden';\n    },\n    formatToggle: function () {\n      return 'Umschalten';\n    },\n    formatColumns: function () {\n      return 'Spalten';\n    }\n  };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['de-DE']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Greek translation\n * Author: giannisdallas\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['el-GR'] = {\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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['el-GR']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table English translation\n * Author: Zhixin Wen<wenzhixin2010@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['en-US'] = {\n        formatLoadingMessage: function () {\n            return 'Loading, please wait...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' records per page';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Showing ' + pageFrom + ' to ' + pageTo + ' of ' + totalRows + ' rows';\n        },\n        formatSearch: function () {\n            return 'Search';\n        },\n        formatNoMatches: function () {\n            return 'No matching records found';\n        },\n        formatPaginationSwitch: function () {\n            return 'Hide/Show pagination';\n        },\n        formatRefresh: function () {\n            return 'Refresh';\n        },\n        formatToggle: function () {\n            return 'Toggle';\n        },\n        formatColumns: function () {\n            return 'Columns';\n        },\n        formatAllRows: function () {\n            return 'All';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['en-US']);\n\n})(jQuery);\n/**\n * Bootstrap Table Spanish (Argentina) translation\n * Author: Felix Vera (felix.vera@gmail.com)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['es-AR'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, espere por favor...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Mostrando ' + pageFrom + ' a ' + pageTo + ' de ' + totalRows + ' filas';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se encontraron registros';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-AR']);\n\n})(jQuery);\n/**\n * Bootstrap Table Spanish (Costa Rica) translation\n * Author: Dennis Hernández (http://djhvscf.github.io/Blog/)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['es-CR'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, por favor espere...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Mostrando de ' + pageFrom + ' a ' + pageTo + ' registros de ' + totalRows + ' registros en total';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se encontraron registros';\n        },\n        formatRefresh: function () {\n            return 'Refrescar';\n        },\n        formatToggle: function () {\n            return 'Alternar';\n        },\n        formatColumns: function () {\n            return 'Columnas';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-CR']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Spanish (México) translation (Obtenido de traducción de Argentina)\n * Author: Felix Vera (felix.vera@gmail.com) \n * Copiado: Mauricio Vera (mauricioa.vera@gmail.com)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['es-MX'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, espere por favor...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Mostrando ' + pageFrom + ' a ' + pageTo + ' de ' + totalRows + ' filas';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se encontraron registros';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-MX']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Spanish (Nicaragua) translation\n * Author: Dennis Hernández (http://djhvscf.github.io/Blog/)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['es-NI'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, por favor espere...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Mostrando de ' + pageFrom + ' a ' + pageTo + ' registros de ' + totalRows + ' registros en total';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se encontraron registros';\n        },\n        formatRefresh: function () {\n            return 'Refrescar';\n        },\n        formatToggle: function () {\n            return 'Alternar';\n        },\n        formatColumns: function () {\n            return 'Columnas';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-NI']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Spanish (España) translation\n * Author: Antonio Pérez <anpegar@gmail.com>\n */\n (function ($) {\n    'use strict';\n    \n    $.fn.bootstrapTable.locales['es-SP'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, por favor espera...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por p&#225;gina.';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return pageFrom + ' - ' + pageTo + ' de ' + totalRows + ' registros.';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se han encontrado registros.';\n        },\n        formatRefresh: function () {\n            return 'Actualizar';\n        },\n        formatToggle: function () {\n            return 'Alternar';\n        },\n        formatColumns: function () {\n            return 'Columnas';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-SP']);\n\n})(jQuery);\n/**\n * Bootstrap Table French (Belgium) translation\n * Author: Julien Bisconti (julien.bisconti@gmail.com)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['fr-BE'] = {\n        formatLoadingMessage: function () {\n            return 'Chargement en cours...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' entrées par page';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Affiche de' + pageFrom + ' à ' + pageTo + ' sur ' + totalRows + ' lignes';\n        },\n        formatSearch: function () {\n            return 'Recherche';\n        },\n        formatNoMatches: function () {\n            return 'Pas de fichiers trouvés';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['fr-BE']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table French (France) translation\n * Author: Dennis Hernández (http://djhvscf.github.io/Blog/)\n * Modification: Tidalf (https://github.com/TidalfFR)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['fr-FR'] = {\n        formatLoadingMessage: function () {\n            return 'Chargement en cours, patientez, s´il vous plaît ...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' lignes par page';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Affichage des lignes ' + pageFrom + ' à ' + pageTo + ' sur ' + totalRows + ' lignes au total';\n        },\n        formatSearch: function () {\n            return 'Rechercher';\n        },\n        formatNoMatches: function () {\n            return 'Aucun résultat trouvé';\n        },\n        formatRefresh: function () {\n            return 'Rafraîchir';\n        },\n        formatToggle: function () {\n            return 'Alterner';\n        },\n        formatColumns: function () {\n            return 'Colonnes';\n        },\n        formatAllRows: function () {\n            return 'Tous';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['fr-FR']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Hungarian translation\n * Author: Nagy Gergely <info@nagygergely.eu>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['hu-HU'] = {\n        formatLoadingMessage: function () {\n            return 'Betöltés, kérem várjon...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' rekord per oldal';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Megjelenítve ' + pageFrom + ' - ' + pageTo + ' / ' + totalRows + ' összesen';\n        },\n        formatSearch: function () {\n            return 'Keresés';\n        },\n        formatNoMatches: function () {\n            return 'Nincs találat';\n        },\n        formatRefresh: function () {\n            return 'Frissítés';\n        },\n        formatToggle: function () {\n            return 'Váltás';\n        },\n        formatColumns: function () {\n            return 'Oszlopok';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['hu-HU']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Italian translation\n * Author: Davide Renzi<davide.renzi@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['it-IT'] = {\n        formatLoadingMessage: function () {\n            return 'Caricamento in corso...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' records per pagina';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Pagina ' + pageFrom + ' di ' + pageTo + ' (' + totalRows + ' records)';\n        },\n        formatSearch: function () {\n            return 'Cerca';\n        },\n        formatNoMatches: function () {\n            return 'Nessun record trovato';\n        },\n        formatRefresh: function () {\n            return 'Rinfrescare';\n        },\n        formatToggle: function () {\n            return 'Alternare';\n        },\n        formatColumns: function () {\n            return 'Colonne';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['it-IT']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Japanese translation\n * Author: Azamshul Azizy <azamshul@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ja-JP'] = {\n        formatLoadingMessage: function () {\n            return '読み込み中です。少々お待ちください。';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return 'ページ当たり最大' + pageNumber + '件';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return '全' + totalRows + '件から、'+ pageFrom + 'から' + pageTo + '件目まで表示しています';\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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ja-JP']);\n\n})(jQuery);\n/**\n * Bootstrap Table Georgian translation\n * Author: Levan Lotuashvili <l.lotuashvili@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ka-GE'] = {\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    };\n    \n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ka-GE']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Korean translation\n * Author: Yi Tae-Hyeong (jsonobject@gmail.com)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ko-KR'] = {\n        formatLoadingMessage: function () {\n            return '데이터를 불러오는 중입니다...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return '페이지 당 ' + pageNumber + '개 데이터 출력';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return '전체 ' + totalRows + '개 중 ' + pageFrom + '~' + pageTo + '번째 데이터 출력,';\n        },\n        formatSearch: function () {\n            return '검색';\n        },\n        formatNoMatches: function () {\n            return '조회된 데이터가 없습니다.';\n        },\n        formatRefresh: function () {\n            return '새로 고침';\n        },\n        formatToggle: function () {\n            return '전환';\n        },\n        formatColumns: function () {\n            return '컬럼 필터링';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ko-KR']);\n\n})(jQuery);\n/**\n * Bootstrap Table Malay translation\n * Author: Azamshul Azizy <azamshul@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ms-MY'] = {\n        formatLoadingMessage: function () {\n            return 'Permintaan sedang dimuatkan. Sila tunggu sebentar...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' rekod setiap muka surat';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Sedang memaparkan rekod ' + pageFrom + ' hingga ' + pageTo + ' daripada jumlah ' + totalRows + ' rekod';\n        },\n        formatSearch: function () {\n            return 'Cari';\n        },\n        formatNoMatches: function () {\n            return 'Tiada rekod yang menyamai permintaan';\n        },\n        formatPaginationSwitch: function () {\n            return 'Tunjuk/sembunyi muka surat';\n        },\n        formatRefresh: function () {\n            return 'Muatsemula';\n        },\n        formatToggle: function () {\n            return 'Tukar';\n        },\n        formatColumns: function () {\n            return 'Lajur';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ms-MY']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table norwegian translation\n * Author: Jim Nordbø, jim@nordb.no\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['nb-NO'] = {\n        formatLoadingMessage: function () {\n            return 'Oppdaterer, vennligst vent...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' poster pr side';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Viser ' + pageFrom + ' til ' + pageTo + ' av ' + totalRows + ' rekker';\n        },\n        formatSearch: function () {\n            return 'Søk';\n        },\n        formatNoMatches: function () {\n            return 'Ingen poster funnet';\n        },\n        formatRefresh: function () {\n            return 'Oppdater';\n        },\n        formatToggle: function () {\n            return 'Endre';\n        },\n        formatColumns: function () {\n            return 'Kolonner';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['nb-NO']);\n\n})(jQuery);\n/**\n * Bootstrap Table Dutch translation\n * Author: Your Name <info@a2hankes.nl>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['nl-NL'] = {\n        formatLoadingMessage: function () {\n            return 'Laden, even geduld...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' records per pagina';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Toon ' + pageFrom + ' tot ' + pageTo + ' van ' + totalRows + ' records';\n        },\n        formatSearch: function () {\n            return 'Zoeken';\n        },\n        formatNoMatches: function () {\n            return 'Geen resultaten gevonden';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['nl-NL']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Polish translation\n * Author: zergu <michal.zagdan @ gmail com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['pl-PL'] = {\n        formatLoadingMessage: function () {\n            return 'Ładowanie, proszę czekać...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' rekordów na stronę';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Wyświetlanie rekordów od ' + pageFrom + ' do ' + pageTo + ' z ' + totalRows;\n        },\n        formatSearch: function () {\n            return 'Szukaj';\n        },\n        formatNoMatches: function () {\n            return 'Niestety, nic nie znaleziono';\n        },\n        formatRefresh: function () {\n            return 'Odśwież';\n        },\n        formatToggle: function () {\n            return 'Przełącz';\n        },\n        formatColumns: function () {\n            return 'Kolumny';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pl-PL']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Brazilian Portuguese Translation\n * Author: Eduardo Cerqueira<egcerqueira@gmail.com>\n * Update: João Mello<jmello@hotmail.com.br>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['pt-BR'] = {\n        formatLoadingMessage: function () {\n            return 'Carregando, aguarde...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Exibindo ' + pageFrom + ' até ' + pageTo + ' de ' + totalRows + ' linhas';\n        },\n        formatSearch: function () { \n            return 'Pesquisar';\n        },\n        formatRefresh: function () { \n            return 'Recarregar';\n        },\n        formatToggle: function () { \n            return 'Alternar';\n        },\n        formatColumns: function () { \n            return 'Colunas';\n        },\n        formatPaginationSwitch: function () { \n            return 'Ocultar/Exibir paginação';\n        },\n        formatNoMatches: function () {\n            return 'Nenhum registro encontrado';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pt-BR']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Portuguese Portugal Translation\n * Author: Burnspirit<burnspirit@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['pt-PT'] = {\n        formatLoadingMessage: function () {\n            return 'A carregar, aguarde...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registos por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'A mostrar ' + pageFrom + ' até ' + pageTo + ' de ' + totalRows + ' linhas';\n        },\n        formatSearch: function () {\n            return 'Pesquisa';\n        },\n        formatNoMatches: function () {\n            return 'Nenhum registo encontrado';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pt-PT']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Romanian translation\n * Author: cristake <cristianiosif@me.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ro-RO'] = {\n        formatLoadingMessage: function () {\n            return 'Se incarca, va rugam asteptati...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' inregistrari pe pagina';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Arata de la ' + pageFrom + ' pana la ' + pageTo + ' din ' + totalRows + ' randuri';\n        },\n        formatSearch: function () {\n            return 'Cauta';\n        },\n        formatNoMatches: function () {\n            return 'Nu au fost gasite inregistrari';\n        },\n        formatPaginationSwitch: function () {\n            return 'Ascunde/Arata paginatia';\n        },\n        formatRefresh: function () {\n            return 'Reincarca';\n        },\n        formatToggle: function () {\n            return 'Comuta';\n        },\n        formatColumns: function () {\n            return 'Coloane';\n        },\n        formatAllRows: function () {\n            return 'Toate';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ro-RO']);\n\n})(jQuery);\n/**\n * Bootstrap Table Russian translation\n * Author: Dunaevsky Maxim <dunmaksim@yandex.ru>\n */\n(function ($) {\n    'use strict';\n    $.fn.bootstrapTable.locales['ru-RU'] = {\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        formatRefresh: function () {\n            return 'Обновить';\n        },\n        formatToggle: function () {\n            return 'Переключить';\n        },\n        formatColumns: function () {\n            return 'Колонки';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ru-RU']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Slovak translation\n * Author: Jozef Dúc<jozef.d13@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['sk-SK'] = {\n        formatLoadingMessage: function () {\n            return 'Prosím čakajte ...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' záznamov na stranu';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Zobrazená ' + pageFrom + '. - ' + pageTo + '. položka z celkových ' + totalRows;\n        },\n        formatSearch: function () {\n            return 'Vyhľadávanie';\n        },\n        formatNoMatches: function () {\n            return 'Nenájdená žiadne vyhovujúca položka';\n        },\n        formatRefresh: function () {\n            return 'Obnoviť';\n        },\n        formatToggle: function () {\n            return 'Prepni';\n        },\n        formatColumns: function () {\n            return 'Stĺpce';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['sk-SK']);\n\n})(jQuery);\n/**\n * Bootstrap Table Swedish translation\n * Author: C Bratt <bratt@inix.se>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['sv-SE'] = {\n        formatLoadingMessage: function () {\n            return 'Laddar, vänligen vänta...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' rader per sida';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Visa ' + pageFrom + ' till ' + pageTo + ' av ' + totalRows + ' rader';\n        },\n        formatSearch: function () {\n            return 'Sök';\n        },\n        formatNoMatches: function () {\n            return 'Inga matchande resultat funna.';\n        },\n        formatRefresh: function () {\n            return 'Uppdatera';\n        },\n        formatToggle: function () {\n            return 'Skifta';\n        },\n        formatColumns: function () {\n            return 'kolumn';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['sv-SE']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Thai translation\n * Author: Monchai S.<monchais@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['th-TH'] = {\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        formatRefresh: function () {\n            return 'รีเฟรส';\n        },\n        formatToggle: function () {\n            return 'สลับมุมมอง';\n        },\n        formatColumns: function () {\n            return 'คอลัมน์';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['th-TH']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Turkish translation\n * Author: Emin Şen\n * Author: Sercan Cakir <srcnckr@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['tr-TR'] = {\n        formatLoadingMessage: function () {\n            return 'Yükleniyor, lütfen bekleyin...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return 'Sayfa başına ' + pageNumber + ' kayıt.';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return totalRows + ' kayıttan ' + pageFrom + '-' + pageTo + ' arası gösteriliyor.';\n        },\n        formatSearch: function () {\n            return 'Ara';\n        },\n        formatNoMatches: function () {\n            return 'Eşleşen kayıt bulunamadı.';\n        },\n        formatRefresh: function () {\n            return 'Yenile';\n        },\n        formatToggle: function () {\n            return 'Değiştir';\n        },\n        formatColumns: function () {\n            return 'Sütunlar';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['tr-TR']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Ukrainian translation\n * Author: Vitaliy Timchenko <vitaliy.timchenko@gmail.com>\n */\n (function ($) {\n    'use strict';\n    \n    $.fn.bootstrapTable.locales['uk-UA'] = {\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        formatRefresh: function () {\n            return 'Оновити';\n        },\n        formatToggle: function () {\n            return 'Змінити';\n        },\n        formatColumns: function () {\n            return 'Стовпці';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['uk-UA']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Urdu translation\n * Author: Malik <me@malikrizwan.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ur-PK'] = {\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        formatRefresh: function () {\n            return 'تازہ کریں';\n        },\n        formatToggle: function () {\n            return 'تبدیل کریں';\n        },\n        formatColumns: function () {\n            return 'کالم';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ur-PK']);\n\n})(jQuery);\n\n/**\n * Bootstrap Table Vietnamese translation\n * Author: Duc N. PHAM <pngduc@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['vi-VN'] = {\n        formatLoadingMessage: function () {\n            return 'Đang tải...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' bản ghi mỗi trang';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Hiển thị từ trang ' + pageFrom + ' đến ' + pageTo + ' của ' + totalRows + ' bảng ghi';\n        },\n        formatSearch: function () {\n            return 'Tìm kiếm';\n        },\n        formatNoMatches: function () {\n            return 'Không có dữ liệu';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['vi-VN']);\n\n})(jQuery);\n/**\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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-CN']);\n\n})(jQuery);\n/**\n * Bootstrap Table Chinese translation\n * Author: Zhixin Wen<wenzhixin2010@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['zh-TW'] = {\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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-TW']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/bootstrap-table.css",
    "content": "/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * version: 1.8.1\n * https://github.com/wenzhixin/bootstrap-table/\n */\n\n.bootstrap-table .table {\n    margin-bottom: 0 !important;\n    border-bottom: 1px solid #dddddd;\n    border-collapse: collapse !important;\n    border-radius: 1px;\n}\n\n.bootstrap-table .table,\n.bootstrap-table .table > tbody > tr > th,\n.bootstrap-table .table > tfoot > tr > th,\n.bootstrap-table .table > thead > tr > td,\n.bootstrap-table .table > tbody > tr > td,\n.bootstrap-table .table > tfoot > tr > td {\n    padding: 8px !important;\n}\n\n.bootstrap-table .table.table-no-bordered > thead > tr > th,\n.bootstrap-table .table.table-no-bordered > tbody > tr > td {\n    border-right: 2px solid transparent;\n}\n\n.fixed-table-container {\n    position: relative;\n    clear: both;\n    border: 1px solid #dddddd;\n    border-radius: 4px;\n    -webkit-border-radius: 4px;\n    -moz-border-radius: 4px;\n}\n\n.fixed-table-container.table-no-bordered {\n    border: 1px solid transparent;\n}\n\n.fixed-table-footer,\n.fixed-table-header {\n    height: 37px; /*cellHeight*/\n    overflow: hidden;\n    border-radius: 4px 4px 0 0;\n    -webkit-border-radius: 4px 4px 0 0;\n    -moz-border-radius: 4px 4px 0 0;\n}\n\n.fixed-table-header {\n    border-bottom: 1px solid #dddddd;\n}\n\n.fixed-table-footer {\n    border-top: 1px solid #dddddd;\n}\n\n.fixed-table-body {\n    overflow-x: auto;\n    overflow-y: auto;\n    height: 100%;\n}\n\n.fixed-table-container table {\n    width: 100%;\n}\n\n.fixed-table-container thead th {\n    height: 0;\n    padding: 0;\n    margin: 0;\n    border-left: 1px solid #dddddd;\n}\n\n.fixed-table-container thead th:first-child {\n    border-left: none;\n    border-top-left-radius: 4px;\n    -webkit-border-top-left-radius: 4px;\n    -moz-border-radius-topleft: 4px;\n}\n\n.fixed-table-container thead th .th-inner {\n    padding: 8px;\n    line-height: 24px;\n    vertical-align: top;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n}\n\n.fixed-table-container thead th .sortable {\n    cursor: pointer;\n    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC');\n    background-position: right;\n    background-repeat: no-repeat;\n    padding-right: 30px;\n}\n\n.fixed-table-container th.detail {\n    width: 30px;\n}\n\n.fixed-table-container tbody td {\n    border-left: 1px solid #dddddd;\n}\n\n.fixed-table-container tbody tr:first-child td {\n    border-top: none;\n}\n\n.fixed-table-container tbody td:first-child {\n    border-left: none;\n}\n\n/* the same color with .active */\n.fixed-table-container tbody .selected td {\n    background-color: #f5f5f5;\n}\n\n.fixed-table-container .bs-checkbox {\n    text-align: center;\n}\n\n.fixed-table-container .bs-checkbox .th-inner {\n    padding: 8px 0;\n}\n\n.fixed-table-container input[type=\"radio\"],\n.fixed-table-container input[type=\"checkbox\"] {\n    margin: 0 auto !important;\n}\n\n.fixed-table-container .no-records-found {\n    text-align: center;\n}\n\n.fixed-table-pagination div.pagination,\n.fixed-table-pagination .pagination-detail {\n    margin-top: 10px;\n    margin-bottom: 10px;\n}\n\n.fixed-table-pagination div.pagination .pagination {\n    margin: 0;\n}\n\n.fixed-table-pagination .pagination a {\n    padding: 6px 12px;\n    line-height: 1.428571429;\n}\n\n.fixed-table-pagination .pagination-info {\n    line-height: 34px;\n    margin-right: 5px;\n}\n\n.fixed-table-pagination .btn-group {\n    position: relative;\n    display: inline-block;\n    vertical-align: middle;\n}\n\n.fixed-table-pagination .dropup .dropdown-menu {\n    margin-bottom: 0;\n}\n\n.fixed-table-pagination .page-list {\n    display: inline-block;\n}\n\n.fixed-table-toolbar .columns-left {\n    margin-right: 5px;\n}\n\n.fixed-table-toolbar .columns-right {\n    margin-left: 5px;\n}\n\n.fixed-table-toolbar .columns label {\n    display: block;\n    padding: 3px 20px;\n    clear: both;\n    font-weight: normal;\n    line-height: 1.428571429;\n}\n\n.fixed-table-toolbar .bars,\n.fixed-table-toolbar .search,\n.fixed-table-toolbar .columns {\n    position: relative;\n    margin-top: 10px;\n    margin-bottom: 10px;\n    line-height: 34px;\n}\n\n.fixed-table-pagination li.disabled a {\n    pointer-events: none;\n    cursor: default;\n}\n\n.fixed-table-loading {\n    display: none;\n    position: absolute;\n    top: 42px;\n    right: 0;\n    bottom: 0;\n    left: 0;\n    z-index: 99;\n    background-color: #fff;\n    text-align: center;\n}\n\n.fixed-table-body .card-view .title {\n    font-weight: bold;\n    display: inline-block;\n    min-width: 30%;\n    text-align: left !important;\n}\n\n/* support bootstrap 2 */\n.fixed-table-body thead th .th-inner {\n    box-sizing: border-box;\n}\n\n.table th, .table td {\n    vertical-align: middle;\n    box-sizing: border-box;\n}\n\n.fixed-table-toolbar .dropdown-menu {\n    text-align: left;\n    max-height: 300px;\n    overflow: auto;\n}\n\n.fixed-table-toolbar .btn-group > .btn-group {\n    display: inline-block;\n    margin-left: -1px !important;\n}\n\n.fixed-table-toolbar .btn-group > .btn-group > .btn {\n    border-radius: 0;\n}\n\n.fixed-table-toolbar .btn-group > .btn-group:first-child > .btn {\n    border-top-left-radius: 4px;\n    border-bottom-left-radius: 4px;\n}\n\n.fixed-table-toolbar .btn-group > .btn-group:last-child > .btn {\n    border-top-right-radius: 4px;\n    border-bottom-right-radius: 4px;\n}\n\n.bootstrap-table .table > thead > tr > th {\n    vertical-align: bottom;\n    border-bottom: 2px solid #ddd;\n}\n\n/* support bootstrap 3 */\n.bootstrap-table .table thead > tr > th {\n    padding: 0;\n    margin: 0;\n}\n\n.pull-right .dropdown-menu {\n    right: 0;\n    left: auto;\n}\n\n/* calculate scrollbar width */\np.fixed-table-scroll-inner {\n    width: 100%;\n    height: 200px;\n}\n\ndiv.fixed-table-scroll-outer {\n    top: 0;\n    left: 0;\n    visibility: hidden;\n    width: 200px;\n    height: 150px;\n    overflow: hidden;\n}"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/bootstrap-table.js",
    "content": "/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * version: 1.8.1\n * https://github.com/wenzhixin/bootstrap-table/\n */\n\n!function ($) {\n    'use strict';\n\n    // TOOLS DEFINITION\n    // ======================\n\n    var cellHeight = 37, // update css if changed\n        cachedWidth = null,\n        arrowAsc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ' +\n        '0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBd' +\n        'qEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVo' +\n        'AADeemwtPcZI2wAAAABJRU5ErkJggg==',\n        arrowBoth = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X' +\n        'QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azio' +\n        'NZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4eut' +\n        's6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC',\n        arrowDesc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWj' +\n        'YBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJ' +\n        'zcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= ';\n\n    // it only does '%s', and return '' when arguments are undefined\n    var sprintf = function (str) {\n        var args = arguments,\n            flag = true,\n            i = 1;\n\n        str = str.replace(/%s/g, function () {\n            var arg = args[i++];\n\n            if (typeof arg === 'undefined') {\n                flag = false;\n                return '';\n            }\n            return arg;\n        });\n        return flag ? str : '';\n    };\n\n    var getPropertyFromOther = function (list, from, to, value) {\n        var result = '';\n        $.each(list, function (i, item) {\n            if (item[from] === value) {\n                result = item[to];\n                return false;\n            }\n            return true;\n        });\n        return result;\n    };\n\n    var getFieldIndex = function (columns, field) {\n        var index = -1;\n\n        $.each(columns, function (i, column) {\n            if (column.field === field) {\n                index = i;\n                return false;\n            }\n            return true;\n        });\n        return index;\n    };\n\n    var getScrollBarWidth = function () {\n        if (cachedWidth === null) {\n            var inner = $('<p/>').addClass('fixed-table-scroll-inner'),\n                outer = $('<div/>').addClass('fixed-table-scroll-outer'),\n                w1, w2;\n\n            outer.append(inner);\n            $('body').append(outer);\n\n            w1 = inner[0].offsetWidth;\n            outer.css('overflow', 'scroll');\n            w2 = inner[0].offsetWidth;\n\n            if (w1 === w2) {\n                w2 = outer[0].clientWidth;\n            }\n\n            outer.remove();\n            cachedWidth = w1 - w2;\n        }\n        return cachedWidth;\n    };\n\n    var calculateObjectValue = function (self, name, args, defaultValue) {\n        var func = name;\n\n        if (typeof name === 'string') {\n            // support obj.func1.func2\n            var names = name.split('.');\n\n            if (names.length > 1) {\n                func = window;\n                $.each(names, function (i, f) {\n                    func = func[f];\n                });\n            } else {\n                func = window[name];\n            }\n        }\n        if (typeof func === 'object') {\n            return func;\n        }\n        if (typeof func === 'function') {\n            return func.apply(self, args);\n        }\n        if (!func && typeof name === 'string' && sprintf.apply(this, [name].concat(args))) {\n            return sprintf.apply(this, [name].concat(args));\n        }\n        return defaultValue;\n    };\n\n    var escapeHTML = function (text) {\n        if (typeof text === 'string') {\n            return text\n                .replace(/&/g, \"&amp;\")\n                .replace(/</g, \"&lt;\")\n                .replace(/>/g, \"&gt;\")\n                .replace(/\"/g, \"&quot;\")\n                .replace(/'/g, \"&#039;\");\n        }\n        return text;\n    };\n\n    var getRealHeight = function ($el) {\n        var height = 0;\n        $el.children().each(function () {\n            if (height < $(this).outerHeight(true)) {\n                height = $(this).outerHeight(true);\n            }\n        });\n        return height;\n    };\n\n    var getRealDataAttr = function (dataAttr) {\n        for (var attr in dataAttr) {\n            var auxAttr = attr.split(/(?=[A-Z])/).join('-').toLowerCase();\n            if (auxAttr !== attr) {\n                dataAttr[auxAttr] = dataAttr[attr];\n                delete dataAttr[attr];\n            }\n        }\n\n        return dataAttr;\n    };\n\n    // BOOTSTRAP TABLE CLASS DEFINITION\n    // ======================\n\n    var BootstrapTable = function (el, options) {\n        this.options = options;\n        this.$el = $(el);\n        this.$el_ = this.$el.clone();\n        this.timeoutId_ = 0;\n        this.timeoutFooter_ = 0;\n\n        this.init();\n    };\n\n    BootstrapTable.DEFAULTS = {\n        classes: 'table table-hover',\n        height: undefined,\n        undefinedText: '-',\n        sortName: undefined,\n        sortOrder: 'asc',\n        striped: false,\n        columns: [],\n        data: [],\n        method: 'get',\n        url: undefined,\n        ajax: undefined,\n        cache: true,\n        contentType: 'application/json',\n        dataType: 'json',\n        ajaxOptions: {},\n        queryParams: function (params) {\n            return params;\n        },\n        queryParamsType: 'limit', // undefined\n        responseHandler: function (res) {\n            return res;\n        },\n        pagination: false,\n        sidePagination: 'client', // client or server\n        totalRows: 0, // server side need to set\n        pageNumber: 1,\n        pageSize: 10,\n        pageList: [10, 25, 50, 100],\n        paginationHAlign: 'right', //right, left\n        paginationVAlign: 'bottom', //bottom, top, both\n        paginationDetailHAlign: 'left', //right, left\n        paginationFirstText: '&laquo;',\n        paginationPreText: '&lsaquo;',\n        paginationNextText: '&rsaquo;',\n        paginationLastText: '&raquo;',\n        search: false,\n        searchAlign: 'right',\n        selectItemName: 'btSelectItem',\n        showHeader: true,\n        showFooter: false,\n        showColumns: false,\n        showPaginationSwitch: false,\n        showRefresh: false,\n        showToggle: false,\n        buttonsAlign: 'right',\n        smartDisplay: true,\n        minimumCountColumns: 1,\n        idField: undefined,\n        uniqueId: undefined,\n        cardView: false,\n        detailView: false,\n        detailFormatter: function (index, row) {\n            return '';\n        },\n        trimOnSearch: true,\n        clickToSelect: false,\n        singleSelect: false,\n        toolbar: undefined,\n        toolbarAlign: 'left',\n        checkboxHeader: true,\n        sortable: true,\n        maintainSelected: false,\n        searchTimeOut: 500,\n        searchText: '',\n        iconSize: undefined,\n        iconsPrefix: 'glyphicon', // glyphicon of fa (font awesome)\n        icons: {\n            paginationSwitchDown: 'glyphicon-collapse-down icon-chevron-down',\n            paginationSwitchUp: 'glyphicon-collapse-up icon-chevron-up',\n            refresh: 'glyphicon-refresh icon-refresh',\n            toggle: 'glyphicon-list-alt icon-list-alt',\n            columns: 'glyphicon-th icon-th'\n        },\n\n        rowStyle: function (row, index) {\n            return {};\n        },\n\n        rowAttributes: function (row, index) {\n            return {};\n        },\n\n        onAll: function (name, args) {\n            return false;\n        },\n        onClickCell: function (field, value, row, $element) {\n            return false;\n        },\n        onDblClickCell: function (field, value, row, $element) {\n            return false;\n        },\n        onClickRow: function (item, $element) {\n            return false;\n        },\n        onDblClickRow: function (item, $element) {\n            return false;\n        },\n        onSort: function (name, order) {\n            return false;\n        },\n        onCheck: function (row) {\n            return false;\n        },\n        onUncheck: function (row) {\n            return false;\n        },\n        onCheckAll: function (rows) {\n            return false;\n        },\n        onUncheckAll: function (rows) {\n            return false;\n        },\n        onCheckSome: function(rows){\n            return false;\n        },\n        onUncheckSome: function(rows){\n            return false;\n        },\n        onLoadSuccess: function (data) {\n            return false;\n        },\n        onLoadError: function (status) {\n            return false;\n        },\n        onColumnSwitch: function (field, checked) {\n            return false;\n        },\n        onPageChange: function (number, size) {\n            return false;\n        },\n        onSearch: function (text) {\n            return false;\n        },\n        onToggle: function (cardView) {\n            return false;\n        },\n        onPreBody: function (data) {\n            return false;\n        },\n        onPostBody: function () {\n            return false;\n        },\n        onPostHeader: function () {\n            return false;\n        },\n        onExpandRow: function (index, row, $detail) {\n            return false;\n        },\n        onCollapseRow: function (index, row) {\n            return false;\n        }\n    };\n\n    BootstrapTable.LOCALES = [];\n\n    BootstrapTable.LOCALES['en-US'] = {\n        formatLoadingMessage: function () {\n            return 'Loading, please wait...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return sprintf('%s records per page', pageNumber);\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return sprintf('Showing %s to %s of %s rows', pageFrom, pageTo, totalRows);\n        },\n        formatSearch: function () {\n            return 'Search';\n        },\n        formatNoMatches: function () {\n            return 'No matching records found';\n        },\n        formatPaginationSwitch: function () {\n            return 'Hide/Show pagination';\n        },\n        formatRefresh: function () {\n            return 'Refresh';\n        },\n        formatToggle: function () {\n            return 'Toggle';\n        },\n        formatColumns: function () {\n            return 'Columns';\n        },\n        formatAllRows: function () {\n            return 'All';\n        }\n    };\n\n    $.extend(BootstrapTable.DEFAULTS, BootstrapTable.LOCALES['en-US']);\n\n    BootstrapTable.COLUMN_DEFAULTS = {\n        radio: false,\n        checkbox: false,\n        checkboxEnabled: true,\n        field: undefined,\n        title: undefined,\n        'class': undefined,\n        align: undefined, // left, right, center\n        halign: undefined, // left, right, center\n        falign: undefined, // left, right, center\n        valign: undefined, // top, middle, bottom\n        width: undefined,\n        sortable: false,\n        order: 'asc', // asc, desc\n        visible: true,\n        switchable: true,\n        clickToSelect: true,\n        formatter: undefined,\n        footerFormatter: undefined,\n        events: undefined,\n        sorter: undefined,\n        sortName: undefined,\n        cellStyle: undefined,\n        searchable: true,\n        cardVisible: true\n    };\n\n    BootstrapTable.EVENTS = {\n        'all.bs.table': 'onAll',\n        'click-cell.bs.table': 'onClickCell',\n        'dbl-click-cell.bs.table': 'onDblClickCell',\n        'click-row.bs.table': 'onClickRow',\n        'dbl-click-row.bs.table': 'onDblClickRow',\n        'sort.bs.table': 'onSort',\n        'check.bs.table': 'onCheck',\n        'uncheck.bs.table': 'onUncheck',\n        'check-all.bs.table': 'onCheckAll',\n        'uncheck-all.bs.table': 'onUncheckAll',\n        'check-some.bs.table': 'onCheckSome',\n        'uncheck-some.bs.table': 'onUncheckSome',\n        'load-success.bs.table': 'onLoadSuccess',\n        'load-error.bs.table': 'onLoadError',\n        'column-switch.bs.table': 'onColumnSwitch',\n        'page-change.bs.table': 'onPageChange',\n        'search.bs.table': 'onSearch',\n        'toggle.bs.table': 'onToggle',\n        'pre-body.bs.table': 'onPreBody',\n        'post-body.bs.table': 'onPostBody',\n        'post-header.bs.table': 'onPostHeader',\n        'expand-row.bs.table': 'onExpandRow',\n        'collapse-row.bs.table': 'onCollapseRow'\n    };\n\n    BootstrapTable.prototype.init = function () {\n        this.initContainer();\n        this.initTable();\n        this.initHeader();\n        this.initData();\n        this.initFooter();\n        this.initToolbar();\n        this.initPagination();\n        this.initBody();\n        this.initServer();\n    };\n\n    BootstrapTable.prototype.initContainer = function () {\n        this.$container = $([\n            '<div class=\"bootstrap-table\">',\n            '<div class=\"fixed-table-toolbar\"></div>',\n            this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ?\n                '<div class=\"fixed-table-pagination\" style=\"clear: both;\"></div>' :\n                '',\n            '<div class=\"fixed-table-container\">',\n            '<div class=\"fixed-table-header\"><table></table></div>',\n            '<div class=\"fixed-table-body\">',\n            '<div class=\"fixed-table-loading\">',\n            this.options.formatLoadingMessage(),\n            '</div>',\n            '</div>',\n            '<div class=\"fixed-table-footer\"><table><tr></tr></table></div>',\n            this.options.paginationVAlign === 'bottom' || this.options.paginationVAlign === 'both' ?\n                '<div class=\"fixed-table-pagination\"></div>' :\n                '',\n            '</div>',\n            '</div>'].join(''));\n\n        this.$container.insertAfter(this.$el);\n        this.$tableContainer = this.$container.find('.fixed-table-container');\n        this.$tableHeader = this.$container.find('.fixed-table-header');\n        this.$tableBody = this.$container.find('.fixed-table-body');\n        this.$tableLoading = this.$container.find('.fixed-table-loading');\n        this.$tableFooter = this.$container.find('.fixed-table-footer');\n        this.$toolbar = this.$container.find('.fixed-table-toolbar');\n        this.$pagination = this.$container.find('.fixed-table-pagination');\n\n        this.$tableBody.append(this.$el);\n        this.$container.after('<div class=\"clearfix\"></div>');\n\n        this.$el.addClass(this.options.classes);\n        if (this.options.striped) {\n            this.$el.addClass('table-striped');\n        }\n        if ($.inArray('table-no-bordered', this.options.classes.split(' ')) !== -1) {\n            this.$tableContainer.addClass('table-no-bordered');\n        }\n    };\n\n    BootstrapTable.prototype.initTable = function () {\n        var that = this,\n            columns = [],\n            data = [];\n\n        this.$header = this.$el.find('thead');\n        if (!this.$header.length) {\n            this.$header = $('<thead></thead>').appendTo(this.$el);\n        }\n        if (!this.$header.find('tr').length) {\n            this.$header.append('<tr></tr>');\n        }\n        this.$header.find('th').each(function () {\n            var column = $.extend({}, {\n                title: $(this).html(),\n                'class': $(this).attr('class')\n            }, $(this).data());\n\n            columns.push(column);\n        });\n        this.options.columns = $.extend(true, [], columns, this.options.columns);\n        $.each(this.options.columns, function (i, column) {\n            that.options.columns[i] = $.extend({}, BootstrapTable.COLUMN_DEFAULTS,\n                {field: i}, column); // when field is undefined, use index instead\n        });\n\n        // if options.data is setting, do not process tbody data\n        if (this.options.data.length) {\n            return;\n        }\n\n        this.$el.find('tbody tr').each(function () {\n            var row = {};\n\n            // save tr's id, class and data-* attributes\n            row._id = $(this).attr('id');\n            row._class = $(this).attr('class');\n            row._data = getRealDataAttr($(this).data());\n\n            $(this).find('td').each(function (i) {\n                var field = that.options.columns[i].field;\n\n                row[field] = $(this).html();\n                // save td's id, class and data-* attributes\n                row['_' + field + '_id'] = $(this).attr('id');\n                row['_' + field + '_class'] = $(this).attr('class');\n                row['_' + field + '_rowspan'] = $(this).attr('rowspan');\n                row['_' + field + '_data'] = getRealDataAttr($(this).data());\n            });\n            data.push(row);\n        });\n        this.options.data = data;\n    };\n\n    BootstrapTable.prototype.initHeader = function () {\n        var that = this,\n            visibleColumns = [],\n            html = [],\n            timeoutId = 0;\n\n        this.header = {\n            fields: [],\n            styles: [],\n            classes: [],\n            formatters: [],\n            events: [],\n            sorters: [],\n            sortNames: [],\n            cellStyles: [],\n            clickToSelects: [],\n            searchables: []\n        };\n\n        if (!this.options.cardView && this.options.detailView) {\n            html.push('<th class=\"detail\"><div class=\"fht-cell\"></div></th>');\n            visibleColumns.push({});\n        }\n\n        $.each(this.options.columns, function (i, column) {\n            var text = '',\n                halign = '', // header align style\n                align = '', // body align style\n                style = '',\n                class_ = sprintf(' class=\"%s\"', column['class']),\n                order = that.options.sortOrder || column.order,\n                unitWidth = 'px',\n                width = column.width;\n\n            if (!column.visible) {\n                // Fix #229. Default Sort order is wrong\n                // if data-visible=\"false\" is set on the field referenced by data-sort-name.\n                if (column.field === that.options.sortName) {\n                    that.header.fields.push(column.field);\n                }\n                return;\n            }\n\n            if (that.options.cardView && (!column.cardVisible)) {\n                return;\n            }\n\n            if (column.width !== undefined && (!that.options.cardView)) {\n                if (typeof column.width === 'string') {\n                    if (column.width.indexOf('%') !== -1) {\n                        unitWidth = '%';\n                    }\n                }\n            }\n            if (column.width && typeof column.width === 'string') {\n                width = column.width.replace('%', '').replace('px', '');\n            }\n\n            halign = sprintf('text-align: %s; ', column.halign ? column.halign : column.align);\n            align = sprintf('text-align: %s; ', column.align);\n            style = sprintf('vertical-align: %s; ', column.valign);\n            style += sprintf('width: %s%s; ', column.checkbox || column.radio ? 36 : width, unitWidth);\n\n            visibleColumns.push(column);\n            that.header.fields.push(column.field);\n            that.header.styles.push(align + style);\n            that.header.classes.push(class_);\n            that.header.formatters.push(column.formatter);\n            that.header.events.push(column.events);\n            that.header.sorters.push(column.sorter);\n            that.header.sortNames.push(column.sortName);\n            that.header.cellStyles.push(column.cellStyle);\n            that.header.clickToSelects.push(column.clickToSelect);\n            that.header.searchables.push(column.searchable);\n\n            html.push('<th',\n                column.checkbox || column.radio ?\n                    sprintf(' class=\"bs-checkbox %s\"', column['class'] || '') :\n                    class_,\n                sprintf(' style=\"%s\"', halign + style),\n                '>');\n\n            html.push(sprintf('<div class=\"th-inner %s\">', that.options.sortable && column.sortable ?\n                'sortable' : ''));\n\n            text = column.title;\n\n            if (column.checkbox) {\n                if (!that.options.singleSelect && that.options.checkboxHeader) {\n                    text = '<input name=\"btSelectAll\" type=\"checkbox\" />';\n                }\n                that.header.stateField = column.field;\n            }\n            if (column.radio) {\n                text = '';\n                that.header.stateField = column.field;\n                that.options.singleSelect = true;\n            }\n\n            html.push(text);\n            html.push('</div>');\n            html.push('<div class=\"fht-cell\"></div>');\n            html.push('</div>');\n            html.push('</th>');\n        });\n\n        this.$header.find('tr').html(html.join(''));\n        this.$header.find('th').each(function (i) {\n            $(this).data(visibleColumns[i]);\n        });\n        this.$container.off('click', '.th-inner').on('click', '.th-inner', function (event) {\n            if (that.options.sortable && $(this).parent().data().sortable) {\n                that.onSort(event);\n            }\n        });\n\n        if (!this.options.showHeader || this.options.cardView) {\n            this.$header.hide();\n            this.$tableHeader.hide();\n            this.$tableLoading.css('top', 0);\n        } else {\n            this.$header.show();\n            this.$tableHeader.show();\n            this.$tableLoading.css('top', cellHeight + 'px');\n            // Assign the correct sortable arrow\n            this.getCaretHtml();\n        }\n\n        this.$selectAll = this.$header.find('[name=\"btSelectAll\"]');\n        this.$container.off('click', '[name=\"btSelectAll\"]')\n            .on('click', '[name=\"btSelectAll\"]', function () {\n                var checked = $(this).prop('checked');\n                that[checked ? 'checkAll' : 'uncheckAll']();\n            });\n    };\n\n    BootstrapTable.prototype.initFooter = function () {\n        if (!this.options.showFooter || this.options.cardView) {\n            this.$tableFooter.hide();\n        } else {\n            this.$tableFooter.show();\n        }\n    };\n\n    /**\n     * @param data\n     * @param type: append / prepend\n     */\n    BootstrapTable.prototype.initData = function (data, type) {\n        if (type === 'append') {\n            this.data = this.data.concat(data);\n        } else if (type === 'prepend') {\n            this.data = [].concat(data).concat(this.data);\n        } else {\n            this.data = data || this.options.data;\n        }\n\n        // Fix #839 Records deleted when adding new row on filtered table\n        if (type === 'append') {\n            this.options.data = this.options.data.concat(data);\n        } else if (type === 'prepend') {\n            this.options.data = [].concat(data).concat(this.options.data);\n        } else {\n            this.options.data = this.data;\n        }\n\n        if (this.options.sidePagination === 'server') {\n            return;\n        }\n        this.initSort();\n    };\n\n    BootstrapTable.prototype.initSort = function () {\n        var that = this,\n            name = this.options.sortName,\n            order = this.options.sortOrder === 'desc' ? -1 : 1,\n            index = $.inArray(this.options.sortName, this.header.fields);\n\n        if (index !== -1) {\n            this.data.sort(function (a, b) {\n                if (that.header.sortNames[index]) {\n                    name = that.header.sortNames[index];\n                }\n                var aa = a[name],\n                    bb = b[name],\n                    value = calculateObjectValue(that.header, that.header.sorters[index], [aa, bb]);\n\n                if (value !== undefined) {\n                    return order * value;\n                }\n\n                // Fix #161: undefined or null string sort bug.\n                if (aa === undefined || aa === null) {\n                    aa = '';\n                }\n                if (bb === undefined || bb === null) {\n                    bb = '';\n                }\n\n                // IF both values are numeric, do a numeric comparison\n                if ($.isNumeric(aa) && $.isNumeric(bb)) {\n                    // Convert numerical values form string to float.\n                    aa = parseFloat(aa);\n                    bb = parseFloat(bb);\n                    if (aa < bb) {\n                        return order * -1;\n                    }\n                    return order;\n                }\n\n                if (aa === bb) {\n                    return 0;\n                }\n\n                // If value is not a string, convert to string\n                if (typeof aa !== 'string') {\n                    aa = aa.toString();\n                }\n\n                if (aa.localeCompare(bb) === -1) {\n                    return order * -1;\n                }\n\n                return order;\n            });\n        }\n    };\n\n    BootstrapTable.prototype.onSort = function (event) {\n        var $this = $(event.currentTarget).parent(),\n            $this_ = this.$header.find('th').eq($this.index());\n\n        this.$header.add(this.$header_).find('span.order').remove();\n\n        if (this.options.sortName === $this.data('field')) {\n            this.options.sortOrder = this.options.sortOrder === 'asc' ? 'desc' : 'asc';\n        } else {\n            this.options.sortName = $this.data('field');\n            this.options.sortOrder = $this.data('order') === 'asc' ? 'desc' : 'asc';\n        }\n        this.trigger('sort', this.options.sortName, this.options.sortOrder);\n\n        $this.add($this_).data('order', this.options.sortOrder);\n\n        // Assign the correct sortable arrow\n        this.getCaretHtml();\n\n        if (this.options.sidePagination === 'server') {\n            this.initServer();\n            return;\n        }\n\n        this.initSort();\n        this.initBody();\n    };\n\n    BootstrapTable.prototype.initToolbar = function () {\n        var that = this,\n            html = [],\n            timeoutId = 0,\n            $keepOpen,\n            $search,\n            switchableCount = 0;\n\n        this.$toolbar.html('');\n\n        if (typeof this.options.toolbar === 'string') {\n            $(sprintf('<div class=\"bars pull-%s\"></div>', this.options.toolbarAlign))\n                .appendTo(this.$toolbar)\n                .append($(this.options.toolbar));\n        }\n\n        // showColumns, showToggle, showRefresh\n        html = [sprintf('<div class=\"columns columns-%s btn-group pull-%s\">',\n            this.options.buttonsAlign, this.options.buttonsAlign)];\n\n        if (typeof this.options.icons === 'string') {\n            this.options.icons = calculateObjectValue(null, this.options.icons);\n        }\n\n        if (this.options.showPaginationSwitch) {\n            html.push(sprintf('<button class=\"btn btn-default\" type=\"button\" name=\"paginationSwitch\" title=\"%s\">',\n                this.options.formatPaginationSwitch()),\n                sprintf('<i class=\"%s %s\"></i>', this.options.iconsPrefix, this.options.icons.paginationSwitchDown),\n                '</button>');\n        }\n\n        if (this.options.showRefresh) {\n            html.push(sprintf('<button class=\"btn btn-default' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + '\" type=\"button\" name=\"refresh\" title=\"%s\">',\n                this.options.formatRefresh()),\n                sprintf('<i class=\"%s %s\"></i>', this.options.iconsPrefix, this.options.icons.refresh),\n                '</button>');\n        }\n\n        if (this.options.showToggle) {\n            html.push(sprintf('<button class=\"btn btn-default' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + '\" type=\"button\" name=\"toggle\" title=\"%s\">',\n                this.options.formatToggle()),\n                sprintf('<i class=\"%s %s\"></i>', this.options.iconsPrefix, this.options.icons.toggle),\n                '</button>');\n        }\n\n        if (this.options.showColumns) {\n            html.push(sprintf('<div class=\"keep-open btn-group\" title=\"%s\">',\n                this.options.formatColumns()),\n                '<button type=\"button\" class=\"btn btn-default' + (this.options.iconSize == undefined ? '' : ' btn-' + this.options.iconSize) + ' dropdown-toggle\" data-toggle=\"dropdown\">',\n                sprintf('<i class=\"%s %s\"></i>', this.options.iconsPrefix, this.options.icons.columns),\n                ' <span class=\"caret\"></span>',\n                '</button>',\n                '<ul class=\"dropdown-menu\" role=\"menu\">');\n\n            $.each(this.options.columns, function (i, column) {\n                if (column.radio || column.checkbox) {\n                    return;\n                }\n\n                if (that.options.cardView && (!column.cardVisible)) {\n                    return;\n                }\n\n                var checked = column.visible ? ' checked=\"checked\"' : '';\n\n                if (column.switchable) {\n                    html.push(sprintf('<li>' +\n                        '<label><input type=\"checkbox\" data-field=\"%s\" value=\"%s\"%s> %s</label>' +\n                        '</li>', column.field, i, checked, column.title));\n                    switchableCount++;\n                }\n            });\n            html.push('</ul>',\n                '</div>');\n        }\n\n        html.push('</div>');\n\n        // Fix #188: this.showToolbar is for extentions\n        if (this.showToolbar || html.length > 2) {\n            this.$toolbar.append(html.join(''));\n        }\n\n        if (this.options.showPaginationSwitch) {\n            this.$toolbar.find('button[name=\"paginationSwitch\"]')\n                .off('click').on('click', $.proxy(this.togglePagination, this));\n        }\n\n        if (this.options.showRefresh) {\n            this.$toolbar.find('button[name=\"refresh\"]')\n                .off('click').on('click', $.proxy(this.refresh, this));\n        }\n\n        if (this.options.showToggle) {\n            this.$toolbar.find('button[name=\"toggle\"]')\n                .off('click').on('click', function () {\n                    that.toggleView();\n                });\n        }\n\n        if (this.options.showColumns) {\n            $keepOpen = this.$toolbar.find('.keep-open');\n\n            if (switchableCount <= this.options.minimumCountColumns) {\n                $keepOpen.find('input').prop('disabled', true);\n            }\n\n            $keepOpen.find('li').off('click').on('click', function (event) {\n                event.stopImmediatePropagation();\n            });\n            $keepOpen.find('input').off('click').on('click', function () {\n                var $this = $(this);\n\n                that.toggleColumn(getFieldIndex(that.options.columns, $(this).data('field')), $this.prop('checked'), false);\n                that.trigger('column-switch', $(this).data('field'), $this.prop('checked'));\n            });\n        }\n\n        if (this.options.search) {\n            html = [];\n            html.push(\n                '<div class=\"pull-' + this.options.searchAlign + ' search\">',\n                sprintf('<input class=\"form-control' + (this.options.iconSize === undefined ? '' : ' input-' + this.options.iconSize) + '\" type=\"text\" placeholder=\"%s\">',\n                    this.options.formatSearch()),\n                '</div>');\n\n            this.$toolbar.append(html.join(''));\n            $search = this.$toolbar.find('.search input');\n            $search.off('keyup drop').on('keyup drop', function (event) {\n                clearTimeout(timeoutId); // doesn't matter if it's 0\n                timeoutId = setTimeout(function () {\n                    that.onSearch(event);\n                }, that.options.searchTimeOut);\n            });\n\n            if (this.options.searchText !== '') {\n                $search.val(this.options.searchText);\n                clearTimeout(timeoutId); // doesn't matter if it's 0\n                timeoutId = setTimeout(function () {\n                    $search.trigger('keyup');\n                }, that.options.searchTimeOut);\n            }\n        }\n    };\n\n    BootstrapTable.prototype.onSearch = function (event) {\n        var text = $.trim($(event.currentTarget).val());\n\n        // trim search input\n        if (this.options.trimOnSearch && $(event.currentTarget).val() !== text) {\n            $(event.currentTarget).val(text);\n        }\n\n        if (text === this.searchText) {\n            return;\n        }\n        this.searchText = text;\n\n        this.options.pageNumber = 1;\n        this.initSearch();\n        this.updatePagination();\n        this.trigger('search', text);\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        var that = this;\n\n        if (this.options.sidePagination !== 'server') {\n            var s = this.searchText && this.searchText.toLowerCase();\n            var f = $.isEmptyObject(this.filterColumns) ? null : this.filterColumns;\n\n            // Check filter\n            this.data = f ? $.grep(this.options.data, function (item, i) {\n                for (var key in f) {\n                    if (item[key] !== f[key]) {\n                        return false;\n                    }\n                }\n                return true;\n            }) : this.options.data;\n\n            this.data = s ? $.grep(this.data, function (item, i) {\n                for (var key in item) {\n                    key = $.isNumeric(key) ? parseInt(key, 10) : key;\n                    var value = item[key],\n                        column = that.options.columns[getFieldIndex(that.options.columns, key)],\n                        j = $.inArray(key, that.header.fields);\n\n                    // Fix #142: search use formated data\n                    value = calculateObjectValue(column,\n                        that.header.formatters[j],\n                        [value, item, i], value);\n\n                    var index = $.inArray(key, that.header.fields);\n                    if (index !== -1 && that.header.searchables[index] &&\n                        (typeof value === 'string' ||\n                            typeof value === 'number') &&\n                        (value + '').toLowerCase().indexOf(s) !== -1) {\n                        return true;\n                    }\n                }\n                return false;\n            }) : this.data;\n        }\n    };\n\n    BootstrapTable.prototype.initPagination = function () {\n        if (!this.options.pagination) {\n            this.$pagination.hide();\n            return;\n        } else {\n            this.$pagination.show();\n        }\n\n        var that = this,\n            html = [],\n            $allSelected = false,\n            i, from, to,\n            $pageList,\n            $first, $pre,\n            $next, $last,\n            $number,\n            data = this.getData();\n\n        if (this.options.sidePagination !== 'server') {\n            this.options.totalRows = data.length;\n        }\n\n        this.totalPages = 0;\n        if (this.options.totalRows) {\n            if (this.options.pageSize === this.options.formatAllRows()) {\n                this.options.pageSize = this.options.totalRows;\n                $allSelected = true;\n            } else if (this.options.pageSize === this.options.totalRows) {\n                // Fix #667 Table with pagination, multiple pages and a search that matches to one page throws exception\n                var pageLst = typeof this.options.pageList === 'string' ?\n                    this.options.pageList.replace('[', '').replace(']', '').replace(/ /g, '').toLowerCase().split(',') :\n                    this.options.pageList;\n                if (pageLst.indexOf(this.options.formatAllRows().toLowerCase()) > -1) {\n                    $allSelected = true;\n                }\n            }\n\n            this.totalPages = ~~((this.options.totalRows - 1) / this.options.pageSize) + 1;\n\n            this.options.totalPages = this.totalPages;\n        }\n        if (this.totalPages > 0 && this.options.pageNumber > this.totalPages) {\n            this.options.pageNumber = this.totalPages;\n        }\n\n        this.pageFrom = (this.options.pageNumber - 1) * this.options.pageSize + 1;\n        this.pageTo = this.options.pageNumber * this.options.pageSize;\n        if (this.pageTo > this.options.totalRows) {\n            this.pageTo = this.options.totalRows;\n        }\n\n        html.push(\n            '<div class=\"pull-' + this.options.paginationDetailHAlign + ' pagination-detail\">',\n            '<span class=\"pagination-info\">',\n            this.options.formatShowingRows(this.pageFrom, this.pageTo, this.options.totalRows),\n            '</span>');\n\n        html.push('<span class=\"page-list\">');\n\n        var pageNumber = [\n                sprintf('<span class=\"btn-group %s\">', this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ?\n                    'dropdown' : 'dropup'),\n                '<button type=\"button\" class=\"btn btn-default ' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + ' dropdown-toggle\" data-toggle=\"dropdown\">',\n                '<span class=\"page-size\">',\n                $allSelected ? this.options.formatAllRows() : this.options.pageSize,\n                '</span>',\n                ' <span class=\"caret\"></span>',\n                '</button>',\n                '<ul class=\"dropdown-menu\" role=\"menu\">'],\n            pageList = this.options.pageList;\n\n        if (typeof this.options.pageList === 'string') {\n            var list = this.options.pageList.replace('[', '').replace(']', '').replace(/ /g, '').split(',');\n\n            pageList = [];\n            $.each(list, function (i, value) {\n                pageList.push(value.toUpperCase() === that.options.formatAllRows().toUpperCase() ?\n                    that.options.formatAllRows() : +value);\n            });\n        }\n\n        $.each(pageList, function (i, page) {\n            if (!that.options.smartDisplay || i === 0 || pageList[i - 1] <= that.options.totalRows) {\n                var active;\n                if ($allSelected) {\n                    active = page === that.options.formatAllRows() ? ' class=\"active\"' : '';\n                } else {\n                    active = page === that.options.pageSize ? ' class=\"active\"' : '';\n                }\n                pageNumber.push(sprintf('<li%s><a href=\"javascript:void(0)\">%s</a></li>', active, page));\n            }\n        });\n        pageNumber.push('</ul></span>');\n\n        html.push(this.options.formatRecordsPerPage(pageNumber.join('')));\n        html.push('</span>');\n\n        html.push('</div>',\n            '<div class=\"pull-' + this.options.paginationHAlign + ' pagination\">',\n            '<ul class=\"pagination' + (this.options.iconSize === undefined ? '' : ' pagination-' + this.options.iconSize) + '\">',\n            '<li class=\"page-first\"><a href=\"javascript:void(0)\">' + this.options.paginationFirstText + '</a></li>',\n            '<li class=\"page-pre\"><a href=\"javascript:void(0)\">' + this.options.paginationPreText + '</a></li>');\n\n        if (this.totalPages < 5) {\n            from = 1;\n            to = this.totalPages;\n        } else {\n            from = this.options.pageNumber - 2;\n            to = from + 4;\n            if (from < 1) {\n                from = 1;\n                to = 5;\n            }\n            if (to > this.totalPages) {\n                to = this.totalPages;\n                from = to - 4;\n            }\n        }\n        for (i = from; i <= to; i++) {\n            html.push('<li class=\"page-number' + (i === this.options.pageNumber ? ' active' : '') + '\">',\n                '<a href=\"javascript:void(0)\">', i, '</a>',\n                '</li>');\n        }\n\n        html.push(\n            '<li class=\"page-next\"><a href=\"javascript:void(0)\">' + this.options.paginationNextText + '</a></li>',\n            '<li class=\"page-last\"><a href=\"javascript:void(0)\">' + this.options.paginationLastText + '</a></li>',\n            '</ul>',\n            '</div>');\n\n        this.$pagination.html(html.join(''));\n\n        $pageList = this.$pagination.find('.page-list a');\n        $first = this.$pagination.find('.page-first');\n        $pre = this.$pagination.find('.page-pre');\n        $next = this.$pagination.find('.page-next');\n        $last = this.$pagination.find('.page-last');\n        $number = this.$pagination.find('.page-number');\n\n        if (this.options.pageNumber <= 1) {\n            $first.addClass('disabled');\n            $pre.addClass('disabled');\n        }\n        if (this.options.pageNumber >= this.totalPages) {\n            $next.addClass('disabled');\n            $last.addClass('disabled');\n        }\n        if (this.options.smartDisplay) {\n            if (this.totalPages <= 1) {\n                this.$pagination.find('div.pagination').hide();\n            }\n            if (pageList.length < 2 || this.options.totalRows <= pageList[0]) {\n                this.$pagination.find('span.page-list').hide();\n            }\n\n            // when data is empty, hide the pagination\n            this.$pagination[this.getData().length ? 'show' : 'hide']();\n        }\n        if ($allSelected) {\n            this.options.pageSize = this.options.formatAllRows();\n        }\n        $pageList.off('click').on('click', $.proxy(this.onPageListChange, this));\n        $first.off('click').on('click', $.proxy(this.onPageFirst, this));\n        $pre.off('click').on('click', $.proxy(this.onPagePre, this));\n        $next.off('click').on('click', $.proxy(this.onPageNext, this));\n        $last.off('click').on('click', $.proxy(this.onPageLast, this));\n        $number.off('click').on('click', $.proxy(this.onPageNumber, this));\n    };\n\n    BootstrapTable.prototype.updatePagination = function (event) {\n        // Fix #171: IE disabled button can be clicked bug.\n        if (event && $(event.currentTarget).hasClass('disabled')) {\n            return;\n        }\n\n        if (!this.options.maintainSelected) {\n            this.resetRows();\n        }\n\n        this.initPagination();\n        if (this.options.sidePagination === 'server') {\n            this.initServer();\n        } else {\n            this.initBody();\n        }\n\n        this.trigger('page-change', this.options.pageNumber, this.options.pageSize);\n    };\n\n    BootstrapTable.prototype.onPageListChange = function (event) {\n        var $this = $(event.currentTarget);\n\n        $this.parent().addClass('active').siblings().removeClass('active');\n        this.options.pageSize = $this.text().toUpperCase() === this.options.formatAllRows().toUpperCase() ?\n            this.options.formatAllRows() : +$this.text();\n        this.$toolbar.find('.page-size').text(this.options.pageSize);\n\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPageFirst = function (event) {\n        this.options.pageNumber = 1;\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPagePre = function (event) {\n        this.options.pageNumber--;\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPageNext = function (event) {\n        this.options.pageNumber++;\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPageLast = function (event) {\n        this.options.pageNumber = this.totalPages;\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPageNumber = function (event) {\n        if (this.options.pageNumber === +$(event.currentTarget).text()) {\n            return;\n        }\n        this.options.pageNumber = +$(event.currentTarget).text();\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.initBody = function (fixedScroll) {\n        var that = this,\n            html = [],\n            data = this.getData();\n\n        this.trigger('pre-body', data);\n\n        this.$body = this.$el.find('tbody');\n        if (!this.$body.length) {\n            this.$body = $('<tbody></tbody>').appendTo(this.$el);\n        }\n\n        //Fix #389 Bootstrap-table-flatJSON is not working\n\n        if (!this.options.pagination || this.options.sidePagination === 'server') {\n            this.pageFrom = 1;\n            this.pageTo = data.length;\n        }\n\n        for (var i = this.pageFrom - 1; i < this.pageTo; i++) {\n            var key,\n                item = data[i],\n                style = {},\n                csses = [],\n                data_ = '',\n                attributes = {},\n                htmlAttributes = [];\n\n            style = calculateObjectValue(this.options, this.options.rowStyle, [item, i], style);\n\n            if (style && style.css) {\n                for (key in style.css) {\n                    csses.push(key + ': ' + style.css[key]);\n                }\n            }\n\n            attributes = calculateObjectValue(this.options,\n                this.options.rowAttributes, [item, i], attributes);\n\n            if (attributes) {\n                for (key in attributes) {\n                    htmlAttributes.push(sprintf('%s=\"%s\"', key, escapeHTML(attributes[key])));\n                }\n            }\n\n            if (item._data && !$.isEmptyObject(item._data)) {\n                $.each(item._data, function (k, v) {\n                    // ignore data-index\n                    if (k === 'index') {\n                        return;\n                    }\n                    data_ += sprintf(' data-%s=\"%s\"', k, v);\n                });\n            }\n\n            html.push('<tr',\n                sprintf(' %s', htmlAttributes.join(' ')),\n                sprintf(' id=\"%s\"', $.isArray(item) ? undefined : item._id),\n                sprintf(' class=\"%s\"', style.classes || ($.isArray(item) ? undefined : item._class)),\n                sprintf(' data-index=\"%s\"', i),\n                sprintf(' data-uniqueid=\"%s\"', item[this.options.uniqueId]),\n                sprintf('%s', data_),\n                '>'\n            );\n\n            if (this.options.cardView) {\n                html.push(sprintf('<td colspan=\"%s\">', this.header.fields.length));\n            }\n\n            if (!this.options.cardView && this.options.detailView) {\n                html.push('<td>',\n                    '<a class=\"detail-icon\" href=\"javascript:\">',\n                    '<i class=\"glyphicon glyphicon-plus icon-plus\"></i>',\n                    '</a>',\n                    '</td>');\n            }\n\n            $.each(this.header.fields, function (j, field) {\n                var text = '',\n                    value = item[field],\n                    type = '',\n                    cellStyle = {},\n                    id_ = '',\n                    class_ = that.header.classes[j],\n                    data_ = '',\n                    rowspan_ = '',\n                    column = that.options.columns[getFieldIndex(that.options.columns, field)];\n\n                style = sprintf('style=\"%s\"', csses.concat(that.header.styles[j]).join('; '));\n\n                value = calculateObjectValue(column,\n                    that.header.formatters[j], [value, item, i], value);\n\n                // handle td's id and class\n                if (item['_' + field + '_id']) {\n                    id_ = sprintf(' id=\"%s\"', item['_' + field + '_id']);\n                }\n                if (item['_' + field + '_class']) {\n                    class_ = sprintf(' class=\"%s\"', item['_' + field + '_class']);\n                }\n                if (item['_' + field + '_rowspan']) {\n                    rowspan_ = sprintf(' rowspan=\"%s\"', item['_' + field + '_rowspan']);\n                }\n                cellStyle = calculateObjectValue(that.header,\n                    that.header.cellStyles[j], [value, item, i], cellStyle);\n                if (cellStyle.classes) {\n                    class_ = sprintf(' class=\"%s\"', cellStyle.classes);\n                }\n                if (cellStyle.css) {\n                    var csses_ = [];\n                    for (var key in cellStyle.css) {\n                        csses_.push(key + ': ' + cellStyle.css[key]);\n                    }\n                    style = sprintf('style=\"%s\"', csses_.concat(that.header.styles[j]).join('; '));\n                }\n\n                if (item['_' + field + '_data'] && !$.isEmptyObject(item['_' + field + '_data'])) {\n                    $.each(item['_' + field + '_data'], function (k, v) {\n                        // ignore data-index\n                        if (k === 'index') {\n                            return;\n                        }\n                        data_ += sprintf(' data-%s=\"%s\"', k, v);\n                    });\n                }\n\n                if (column.checkbox || column.radio) {\n                    type = column.checkbox ? 'checkbox' : type;\n                    type = column.radio ? 'radio' : type;\n\n                    text = [that.options.cardView ?\n                        '<div class=\"card-view\">' : '<td class=\"bs-checkbox\">',\n                        '<input' +\n                            sprintf(' data-index=\"%s\"', i) +\n                            sprintf(' name=\"%s\"', that.options.selectItemName) +\n                            sprintf(' type=\"%s\"', type) +\n                            sprintf(' value=\"%s\"', item[that.options.idField]) +\n                            sprintf(' checked=\"%s\"', value === true ||\n                                (value && value.checked) ? 'checked' : undefined) +\n                            sprintf(' disabled=\"%s\"', !column.checkboxEnabled ||\n                                (value && value.disabled) ? 'disabled' : undefined) +\n                            ' />',\n                        that.options.cardView ? '</div>' : '</td>'].join('');\n\n                    item[that.header.stateField] = value === true || (value && value.checked);\n                } else {\n                    value = typeof value === 'undefined' || value === null ?\n                        that.options.undefinedText : value;\n\n                    text = that.options.cardView ?\n                        ['<div class=\"card-view\">',\n                            that.options.showHeader ? sprintf('<span class=\"title\" %s>%s</span>', style,\n                                getPropertyFromOther(that.options.columns, 'field', 'title', field)) : '',\n                            sprintf('<span class=\"value\">%s</span>', value),\n                            '</div>'].join('') :\n                        [sprintf('<td%s %s %s %s %s>', id_, class_, style, data_, rowspan_),\n                            value,\n                            '</td>'].join('');\n\n                    // Hide empty data on Card view when smartDisplay is set to true.\n                    if (that.options.cardView && that.options.smartDisplay && value === '') {\n                        text = '';\n                    }\n                }\n\n                html.push(text);\n            });\n\n            if (this.options.cardView) {\n                html.push('</td>');\n            }\n\n            html.push('</tr>');\n        }\n\n        // show no records\n        if (!html.length) {\n            html.push('<tr class=\"no-records-found\">',\n                sprintf('<td colspan=\"%s\">%s</td>',\n                    this.$header.find('th').length, this.options.formatNoMatches()),\n                '</tr>');\n        }\n\n        this.$body.html(html.join(''));\n\n        if (!fixedScroll) {\n            this.scrollTo(0);\n        }\n\n        // click to select by column\n        this.$body.find('> tr > td').off('click').on('click', function () {\n            var $td = $(this),\n                $tr = $td.parent(),\n                item = that.data[$tr.data('index')],\n                cellIndex = $td[0].cellIndex,\n                $headerCell = that.$header.find('th:eq(' + cellIndex + ')'),\n                field = $headerCell.data('field'),\n                value = item[field];\n            that.trigger('click-cell', field, value, item, $td);\n            that.trigger('click-row', item, $tr);\n            // if click to select - then trigger the checkbox/radio click\n            if (that.options.clickToSelect) {\n                if (that.header.clickToSelects[$tr.children().index($(this))]) {\n                    $tr.find(sprintf('[name=\"%s\"]',\n                        that.options.selectItemName))[0].click(); // #144: .trigger('click') bug\n                }\n            }\n        });\n        this.$body.find('> tr > td').off('dblclick').on('dblclick', function () {\n            var $td = $(this),\n                $tr = $td.parent(),\n                item = that.data[$tr.data('index')],\n                cellIndex = $td[0].cellIndex,\n                $headerCell = that.$header.find('th:eq(' + cellIndex + ')'),\n                field = $headerCell.data('field'),\n                value = item[field];\n            that.trigger('dbl-click-cell', field, value, item, $td);\n            that.trigger('dbl-click-row', item, $tr);\n        });\n\n        this.$body.find('> tr > td > .detail-icon').off('click').on('click', function () {\n            var $this = $(this),\n                $tr = $this.parent().parent(),\n                index = $tr.data('index'),\n                row = that.options.data[index];\n\n            // remove and update\n            if ($tr.next().is('tr.detail-view')) {\n                $this.find('i').attr('class', 'glyphicon glyphicon-plus icon-plus');\n                $tr.next().remove();\n                that.trigger('collapse-row', index, row);\n            } else {\n                $this.find('i').attr('class', 'glyphicon glyphicon-minus icon-minus');\n                $tr.after(sprintf('<tr class=\"detail-view\"><td colspan=\"%s\">%s</td></tr>',\n                    $tr.find('td').length, calculateObjectValue(that.options,\n                        that.options.detailFormatter, [index, row], '')));\n                that.trigger('expand-row', index, row, $tr.next().find('td'));\n            }\n            that.resetView();\n        });\n\n        this.$selectItem = this.$body.find(sprintf('[name=\"%s\"]', this.options.selectItemName));\n        this.$selectItem.off('click').on('click', function (event) {\n            event.stopImmediatePropagation();\n\n            var checked = $(this).prop('checked'),\n                row = that.data[$(this).data('index')];\n\n            row[that.header.stateField] = checked;\n\n            if (that.options.singleSelect) {\n                that.$selectItem.not(this).each(function () {\n                    that.data[$(this).data('index')][that.header.stateField] = false;\n                });\n                that.$selectItem.filter(':checked').not(this).prop('checked', false);\n            }\n\n            that.updateSelected();\n            that.trigger(checked ? 'check' : 'uncheck', row);\n        });\n\n        $.each(this.header.events, function (i, events) {\n            if (!events) {\n                return;\n            }\n            // fix bug, if events is defined with namespace\n            if (typeof events === 'string') {\n                events = calculateObjectValue(null, events);\n            }\n            if (!that.options.cardView && that.options.detailView) {\n                i += 1;\n            }\n            for (var key in events) {\n                that.$body.find('tr').each(function () {\n                    var $tr = $(this),\n                        $td = $tr.find(that.options.cardView ? '.card-view' : 'td').eq(i),\n                        index = key.indexOf(' '),\n                        name = key.substring(0, index),\n                        el = key.substring(index + 1),\n                        func = events[key];\n\n                    $td.find(el).off(name).on(name, function (e) {\n                        var index = $tr.data('index'),\n                            row = that.data[index],\n                            value = row[that.header.fields[i]];\n\n                        func.apply(this, [e, value, row, index]);\n                    });\n                });\n            }\n        });\n\n        this.updateSelected();\n        this.resetView();\n\n        this.trigger('post-body');\n    };\n\n    BootstrapTable.prototype.initServer = function (silent, query) {\n        var that = this,\n            data = {},\n            params = {\n                pageSize: this.options.pageSize === this.options.formatAllRows() ?\n                    this.options.totalRows : this.options.pageSize,\n                pageNumber: this.options.pageNumber,\n                searchText: this.searchText,\n                sortName: this.options.sortName,\n                sortOrder: this.options.sortOrder\n            },\n            request;\n\n        if (!this.options.url && !this.options.ajax) {\n            return;\n        }\n\n        if (this.options.queryParamsType === 'limit') {\n            params = {\n                search: params.searchText,\n                sort: params.sortName,\n                order: params.sortOrder\n            };\n            if (this.options.pagination) {\n                params.limit = this.options.pageSize === this.options.formatAllRows() ?\n                    this.options.totalRows : this.options.pageSize;\n                params.offset = this.options.pageSize === this.options.formatAllRows() ?\n                    0 : this.options.pageSize * (this.options.pageNumber - 1);\n            }\n        }\n\n        if (!($.isEmptyObject(this.filterColumnsPartial))) {\n            params['filter'] = JSON.stringify(this.filterColumnsPartial, null);\n        }\n\n        data = calculateObjectValue(this.options, this.options.queryParams, [params], data);\n\n        $.extend(data, query || {});\n\n        // false to stop request\n        if (data === false) {\n            return;\n        }\n\n        if (!silent) {\n            this.$tableLoading.show();\n        }\n        request = $.extend({}, calculateObjectValue(null, this.options.ajaxOptions), {\n            type: this.options.method,\n            url: this.options.url,\n            data: this.options.contentType === 'application/json' && this.options.method === 'post' ?\n                JSON.stringify(data) : data,\n            cache: this.options.cache,\n            contentType: this.options.contentType,\n            dataType: this.options.dataType,\n            success: function (res) {\n                res = calculateObjectValue(that.options, that.options.responseHandler, [res], res);\n\n                that.load(res);\n                that.trigger('load-success', res);\n            },\n            error: function (res) {\n                that.trigger('load-error', res.status);\n            },\n            complete: function () {\n                if (!silent) {\n                    that.$tableLoading.hide();\n                }\n            }\n        });\n\n        if (this.options.ajax) {\n            calculateObjectValue(this, this.options.ajax, [request], null);\n        } else {\n            $.ajax(request);\n        }\n    };\n\n    BootstrapTable.prototype.getCaretHtml = function () {\n        var that = this;\n\n        $.each(this.$header.find('th'), function (i, th) {\n            if ($(th).data('field') === that.options.sortName) {\n                $(th).find('.sortable').css('background-image', 'url(' + (that.options.sortOrder === 'desc' ? arrowDesc : arrowAsc) + ')');\n            } else {\n                $(th).find('.sortable').css('background-image', 'url(' + arrowBoth +')');\n            }\n        });\n    };\n\n    BootstrapTable.prototype.updateSelected = function () {\n        var checkAll = this.$selectItem.filter(':enabled').length ===\n            this.$selectItem.filter(':enabled').filter(':checked').length;\n\n        this.$selectAll.add(this.$selectAll_).prop('checked', checkAll);\n\n        this.$selectItem.each(function () {\n            $(this).parents('tr')[$(this).prop('checked') ? 'addClass' : 'removeClass']('selected');\n        });\n    };\n\n    BootstrapTable.prototype.updateRows = function () {\n        var that = this;\n\n        this.$selectItem.each(function () {\n            that.data[$(this).data('index')][that.header.stateField] = $(this).prop('checked');\n        });\n    };\n\n    BootstrapTable.prototype.resetRows = function () {\n        var that = this;\n\n        $.each(this.data, function (i, row) {\n            that.$selectAll.prop('checked', false);\n            that.$selectItem.prop('checked', false);\n            row[that.header.stateField] = false;\n        });\n    };\n\n    BootstrapTable.prototype.trigger = function (name) {\n        var args = Array.prototype.slice.call(arguments, 1);\n\n        name += '.bs.table';\n        this.options[BootstrapTable.EVENTS[name]].apply(this.options, args);\n        this.$el.trigger($.Event(name), args);\n\n        this.options.onAll(name, args);\n        this.$el.trigger($.Event('all.bs.table'), [name, args]);\n    };\n\n    BootstrapTable.prototype.resetHeader = function () {\n        // fix #61: the hidden table reset header bug.\n        // fix bug: get $el.css('width') error sometime (height = 500)\n        clearTimeout(this.timeoutId_);\n        this.timeoutId_ = setTimeout($.proxy(this.fitHeader, this), this.$el.is(':hidden') ? 100 : 0);\n    };\n\n    BootstrapTable.prototype.fitHeader = function () {\n        var that = this,\n            fixedBody,\n            scrollWidth;\n\n        if (that.$el.is(':hidden')) {\n            that.timeoutFooter_ = setTimeout($.proxy(that.fitHeader, that), 100);\n            return;\n        }\n        fixedBody = this.$tableBody.get(0);\n\n        scrollWidth = fixedBody.scrollWidth > fixedBody.clientWidth &&\n            fixedBody.scrollHeight > fixedBody.clientHeight + this.$header.height() ?\n            getScrollBarWidth() : 0;\n\n        this.$el.css('margin-top', -this.$header.height());\n        this.$header_ = this.$header.clone(true, true);\n        this.$selectAll_ = this.$header_.find('[name=\"btSelectAll\"]');\n        this.$tableHeader.css({\n            'margin-right': scrollWidth\n        }).find('table').css('width', this.$el.css('width'))\n            .html('').attr('class', this.$el.attr('class'))\n            .append(this.$header_);\n\n        // fix bug: $.data() is not working as expected after $.append()\n        this.$header.find('th').each(function (i) {\n            that.$header_.find('th').eq(i).data($(this).data());\n        });\n\n        this.$body.find('tr:first-child:not(.no-records-found) > *').each(function (i) {\n            that.$header_.find('div.fht-cell').eq(i).width($(this).innerWidth());\n        });\n        // horizontal scroll event\n        // TODO: it's probably better improving the layout than binding to scroll event\n        this.$tableBody.off('scroll').on('scroll', function () {\n            that.$tableHeader.scrollLeft($(this).scrollLeft());\n        });\n        that.trigger('post-header');\n    };\n\n    BootstrapTable.prototype.resetFooter = function () {\n        var that = this,\n            data = that.getData(),\n            html = [];\n\n        if (!this.options.showFooter || this.options.cardView) { //do nothing\n            return;\n        }\n\n        if (!this.options.cardView && this.options.detailView) {\n            html.push('<td></td>');\n        }\n\n        $.each(this.options.columns, function (i, column) {\n            var falign = '', // footer align style\n                style = '',\n                class_ = sprintf(' class=\"%s\"', column['class']);\n\n            if (!column.visible) {\n                return;\n            }\n\n            if (that.options.cardView && (!column.cardVisible)) {\n                return;\n            }\n\n            falign = sprintf('text-align: %s; ', column.falign ? column.falign : column.align);\n            style = sprintf('vertical-align: %s; ', column.valign);\n\n            html.push('<td', class_, sprintf(' style=\"%s\"', falign + style), '>');\n\n            html.push(calculateObjectValue(column, column.footerFormatter, [data], '&nbsp;') || '&nbsp;');\n            html.push('</td>');\n        });\n\n        this.$tableFooter.find('tr').html(html.join(''));\n        clearTimeout(this.timeoutFooter_);\n        this.timeoutFooter_ = setTimeout($.proxy(this.fitFooter, this),\n            this.$el.is(':hidden') ? 100 : 0);\n    };\n\n    BootstrapTable.prototype.fitFooter = function () {\n        var that = this,\n            $footerTd,\n            elWidth,\n            scrollWidth;\n\n        clearTimeout(this.timeoutFooter_);\n        if (this.$el.is(':hidden')) {\n            this.timeoutFooter_ = setTimeout($.proxy(this.fitFooter, this), 100);\n            return;\n        }\n\n        elWidth = this.$el.css('width');\n        scrollWidth = elWidth > this.$tableBody.width() ? getScrollBarWidth() : 0;\n\n        this.$tableFooter.css({\n            'margin-right': scrollWidth\n        }).find('table').css('width', elWidth)\n            .attr('class', this.$el.attr('class'));\n\n        $footerTd = this.$tableFooter.find('td');\n\n        this.$tableBody.find('tbody tr:first-child:not(.no-records-found) > td').each(function (i) {\n            $footerTd.eq(i).outerWidth($(this).outerWidth());\n        });\n    };\n\n    BootstrapTable.prototype.toggleColumn = function (index, checked, needUpdate) {\n        if (index === -1) {\n            return;\n        }\n        this.options.columns[index].visible = checked;\n        this.initHeader();\n        this.initSearch();\n        this.initPagination();\n        this.initBody();\n\n        if (this.options.showColumns) {\n            var $items = this.$toolbar.find('.keep-open input').prop('disabled', false);\n\n            if (needUpdate) {\n                $items.filter(sprintf('[value=\"%s\"]', index)).prop('checked', checked);\n            }\n\n            if ($items.filter(':checked').length <= this.options.minimumCountColumns) {\n                $items.filter(':checked').prop('disabled', true);\n            }\n        }\n    };\n\n    BootstrapTable.prototype.toggleRow = function (index, isIdField, visible) {\n        if (index === -1) {\n            return;\n        }\n\n        $(this.$body[0]).children().filter(sprintf(isIdField ? '[data-uniqueid=\"%s\"]' : '[data-index=\"%s\"]', index))\n            [visible ? 'show' : 'hide']();\n    };\n\n    // PUBLIC FUNCTION DEFINITION\n    // =======================\n\n    BootstrapTable.prototype.resetView = function (params) {\n        var padding = 0;\n\n        if (params && params.height) {\n            this.options.height = params.height;\n        }\n\n        this.$selectAll.prop('checked', this.$selectItem.length > 0 &&\n            this.$selectItem.length === this.$selectItem.filter(':checked').length);\n\n        if (this.options.height) {\n            var toolbarHeight = getRealHeight(this.$toolbar),\n                paginationHeight = getRealHeight(this.$pagination),\n                height = this.options.height - toolbarHeight - paginationHeight;\n\n            this.$tableContainer.css('height', height + 'px');\n        }\n\n        if (this.options.cardView) {\n            // remove the element css\n            this.$el.css('margin-top', '0');\n            this.$tableContainer.css('padding-bottom', '0');\n            return;\n        }\n\n        if (this.options.showHeader && this.options.height) {\n            this.$tableHeader.show();\n            this.resetHeader();\n            padding += cellHeight;\n        } else {\n            this.$tableHeader.hide();\n            this.trigger('post-header');\n        }\n\n        if (this.options.showFooter) {\n            this.resetFooter();\n            if (this.options.height) {\n                padding += cellHeight;\n            }\n        }\n\n        // Assign the correct sortable arrow\n        this.getCaretHtml();\n        this.$tableContainer.css('padding-bottom', padding + 'px');\n    };\n\n    BootstrapTable.prototype.getData = function (useCurrentPage) {\n        return (this.searchText\n            || !$.isEmptyObject(this.filterColumns)\n            || !$.isEmptyObject(this.filterColumnsPartial)) ?\n            (useCurrentPage ? this.data.slice(this.pageFrom -1, this.pageTo)\n                : this.data) :\n            (useCurrentPage ? this.options.data.slice(this.pageFrom - 1, this.pageTo)\n                : this.options.data);\n    };\n\n    BootstrapTable.prototype.load = function (data) {\n        var fixedScroll = false;\n\n        // #431: support pagination\n        if (this.options.sidePagination === 'server') {\n            this.options.totalRows = data.total;\n            fixedScroll = data.fixedScroll;\n            data = data.rows;\n        } else if (!$.isArray(data)) { // support fixedScroll\n            fixedScroll = data.fixedScroll;\n            data = data.data;\n        }\n\n        this.initData(data);\n        this.initSearch();\n        this.initPagination();\n        this.initBody(fixedScroll);\n    };\n\n    BootstrapTable.prototype.append = function (data) {\n        this.initData(data, 'append');\n        this.initSearch();\n        this.initPagination();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.prepend = function (data) {\n        this.initData(data, 'prepend');\n        this.initSearch();\n        this.initPagination();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.remove = function (params) {\n        var len = this.options.data.length,\n            i, row;\n\n        if (!params.hasOwnProperty('field') || !params.hasOwnProperty('values')) {\n            return;\n        }\n\n        for (i = len - 1; i >= 0; i--) {\n            row = this.options.data[i];\n\n            if (!row.hasOwnProperty(params.field)) {\n                continue;\n            }\n            if ($.inArray(row[params.field], params.values) !== -1) {\n                this.options.data.splice(i, 1);\n            }\n        }\n\n        if (len === this.options.data.length) {\n            return;\n        }\n\n        this.initSearch();\n        this.initPagination();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.removeAll = function () {\n        if (this.options.data.length > 0) {\n            this.options.data.splice(0, this.options.data.length);\n            this.initSearch();\n            this.initPagination();\n            this.initBody(true);\n        }\n    };\n\n    BootstrapTable.prototype.removeByUniqueId = function (id) {\n        var uniqueId = this.options.uniqueId,\n            len = this.options.data.length,\n            i, row;\n\n        for (i = len - 1; i >= 0; i--) {\n            row = this.options.data[i];\n\n            if (!row.hasOwnProperty(uniqueId)) {\n                continue;\n            }\n\n            if (typeof row[uniqueId] === 'string') {\n                id = id.toString();\n            } else if (typeof row[uniqueId] === 'number') {\n                if ((Number(row[uniqueId]) === row[uniqueId]) && (row[uniqueId] % 1 === 0)) {\n                    id = parseInt(id);\n                } else if ((row[uniqueId] === Number(row[uniqueId])) && (row[uniqueId] !== 0)) {\n                    id = parseFloat(id);\n                }\n            }\n\n            if (row[uniqueId] === id) {\n                this.options.data.splice(i, 1);\n            }\n        }\n\n        if (len === this.options.data.length) {\n            return;\n        }\n\n        this.initSearch();\n        this.initPagination();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.insertRow = function (params) {\n        if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {\n            return;\n        }\n        this.data.splice(params.index, 0, params.row);\n        this.initSearch();\n        this.initPagination();\n        this.initSort();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.updateRow = function (params) {\n        if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {\n            return;\n        }\n        $.extend(this.data[params.index], params.row);\n        this.initSort();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.showRow = function (params) {\n        if (!params.hasOwnProperty('index')) {\n            return;\n        }\n\n        this.toggleRow(params.index, params.isIdField === undefined ? false : true, true);\n    };\n\n    BootstrapTable.prototype.hideRow = function (params) {\n        if (!params.hasOwnProperty('index')) {\n            return;\n        }\n\n        this.toggleRow(params.index, params.isIdField === undefined ? false : true, false);\n    };\n\n    BootstrapTable.prototype.getRowsHidden = function (show) {\n        var rows = $(this.$body[0]).children().filter(':hidden'),\n            i = 0;\n        if (show) {\n            for (; i < rows.length; i++) {\n                $(rows[i]).show();\n            }\n        }\n        return rows;\n    };\n\n    BootstrapTable.prototype.mergeCells = function (options) {\n        var row = options.index,\n            col = $.inArray(options.field, this.header.fields),\n            rowspan = options.rowspan || 1,\n            colspan = options.colspan || 1,\n            i, j,\n            $tr = this.$body.find('tr'),\n            $td = $tr.eq(row).find('td').eq(col);\n\n        if (!this.options.cardView && this.options.detailView) {\n            col += 1;\n        }\n        $td = $tr.eq(row).find('td').eq(col);\n\n        if (row < 0 || col < 0 || row >= this.data.length) {\n            return;\n        }\n\n        for (i = row; i < row + rowspan; i++) {\n            for (j = col; j < col + colspan; j++) {\n                $tr.eq(i).find('td').eq(j).hide();\n            }\n        }\n\n        $td.attr('rowspan', rowspan).attr('colspan', colspan).show();\n    };\n\n    BootstrapTable.prototype.updateCell = function (params) {\n        if (!params.hasOwnProperty('rowIndex') || !params.hasOwnProperty('fieldName') || !params.hasOwnProperty('fieldValue')) {\n            return;\n        }\n        this.data[params.rowIndex][params.fieldName] = params.fieldValue;\n        this.initSort();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.getOptions = function () {\n        return this.options;\n    };\n\n    BootstrapTable.prototype.getSelections = function () {\n        var that = this;\n\n        return $.grep(this.data, function (row) {\n            return row[that.header.stateField];\n        });\n    };\n\n    BootstrapTable.prototype.getAllSelections = function () {\n        var that = this;\n\n        return $.grep(this.options.data, function (row) {\n            return row[that.header.stateField];\n        });\n    };\n\n    BootstrapTable.prototype.checkAll = function () {\n        this.checkAll_(true);\n    };\n\n    BootstrapTable.prototype.uncheckAll = function () {\n        this.checkAll_(false);\n    };\n\n    BootstrapTable.prototype.checkAll_ = function (checked) {\n        var rows;\n        if (!checked) {\n            rows = this.getSelections();\n        }\n        this.$selectItem.filter(':enabled').prop('checked', checked);\n        this.updateRows();\n        this.updateSelected();\n        if (checked) {\n            rows = this.getSelections();\n        }\n        this.trigger(checked ? 'check-all' : 'uncheck-all', rows);\n    };\n\n    BootstrapTable.prototype.check = function (index) {\n        this.check_(true, index);\n    };\n\n    BootstrapTable.prototype.uncheck = function (index) {\n        this.check_(false, index);\n    };\n\n    BootstrapTable.prototype.check_ = function (checked, index) {\n        this.$selectItem.filter(sprintf('[data-index=\"%s\"]', index)).prop('checked', checked);\n        this.data[index][this.header.stateField] = checked;\n        this.updateSelected();\n        this.trigger(checked ? 'check' : 'uncheck', this.data[index]);\n    };\n\n    BootstrapTable.prototype.checkBy = function (obj) {\n        this.checkBy_(true, obj);\n    };\n\n    BootstrapTable.prototype.uncheckBy = function (obj) {\n        this.checkBy_(false, obj);\n    };\n\n    BootstrapTable.prototype.checkBy_ = function (checked, obj) {\n        if (!obj.hasOwnProperty('field') || !obj.hasOwnProperty('values')) {\n            return;\n        }\n\n        var that = this,\n            rows = [];\n        $.each(this.options.data, function (index, row) {\n            if (!row.hasOwnProperty(obj.field)) {\n                return false;\n            }\n            if ($.inArray(row[obj.field], obj.values) !== -1) {\n                that.$selectItem.filter(sprintf('[data-index=\"%s\"]', index)).prop('checked', checked);\n                row[that.header.stateField] = checked;\n                rows.push(row);\n                that.trigger(checked ? 'check' : 'uncheck', row);\n            }\n        });\n        this.updateSelected();\n        this.trigger(checked ? 'check-some' : 'uncheck-some', rows);\n    };\n\n    BootstrapTable.prototype.destroy = function () {\n        this.$el.insertBefore(this.$container);\n        $(this.options.toolbar).insertBefore(this.$el);\n        this.$container.next().remove();\n        this.$container.remove();\n        this.$el.html(this.$el_.html())\n            .css('margin-top', '0')\n            .attr('class', this.$el_.attr('class') || ''); // reset the class\n    };\n\n    BootstrapTable.prototype.showLoading = function () {\n        this.$tableLoading.show();\n    };\n\n    BootstrapTable.prototype.hideLoading = function () {\n        this.$tableLoading.hide();\n    };\n\n    BootstrapTable.prototype.togglePagination = function () {\n        this.options.pagination = !this.options.pagination;\n        var button = this.$toolbar.find('button[name=\"paginationSwitch\"] i');\n        if (this.options.pagination) {\n            button.attr(\"class\", this.options.iconsPrefix + \" \" + this.options.icons.paginationSwitchDown);\n        } else {\n            button.attr(\"class\", this.options.iconsPrefix + \" \" + this.options.icons.paginationSwitchUp);\n        }\n        this.updatePagination();\n    };\n\n    BootstrapTable.prototype.refresh = function (params) {\n        if (params && params.url) {\n            this.options.url = params.url;\n            this.options.pageNumber = 1;\n        }\n        this.initServer(params && params.silent, params && params.query);\n    };\n\n    BootstrapTable.prototype.resetWidth = function () {\n        if (this.options.showHeader && this.options.height) {\n            this.fitHeader();\n        }\n        if (this.options.showFooter) {\n            this.fitFooter();\n        }\n    };\n\n    BootstrapTable.prototype.showColumn = function (field) {\n        this.toggleColumn(getFieldIndex(this.options.columns, field), true, true);\n    };\n\n    BootstrapTable.prototype.hideColumn = function (field) {\n        this.toggleColumn(getFieldIndex(this.options.columns, field), false, true);\n    };\n\n    BootstrapTable.prototype.filterBy = function (columns) {\n        this.filterColumns = $.isEmptyObject(columns) ? {} : columns;\n        this.options.pageNumber = 1;\n        this.initSearch();\n        this.updatePagination();\n    };\n\n    BootstrapTable.prototype.scrollTo = function (value) {\n        if (typeof value === 'string') {\n            value = value === 'bottom' ? this.$tableBody[0].scrollHeight : 0;\n        }\n        if (typeof value === 'number') {\n            this.$tableBody.scrollTop(value);\n        }\n        if (typeof value === 'undefined') {\n            return this.$tableBody.scrollTop();\n        }\n    };\n\n    BootstrapTable.prototype.getScrollPosition = function () {\n        return this.scrollTo();\n    }\n\n    BootstrapTable.prototype.selectPage = function (page) {\n        if (page > 0 && page <= this.options.totalPages) {\n            this.options.pageNumber = page;\n            this.updatePagination();\n        }\n    };\n\n    BootstrapTable.prototype.prevPage = function () {\n        if (this.options.pageNumber > 1) {\n            this.options.pageNumber--;\n            this.updatePagination();\n        }\n    };\n\n    BootstrapTable.prototype.nextPage = function () {\n        if (this.options.pageNumber < this.options.totalPages) {\n            this.options.pageNumber++;\n            this.updatePagination();\n        }\n    };\n\n    BootstrapTable.prototype.toggleView = function () {\n        this.options.cardView = !this.options.cardView;\n        this.initHeader();\n        // Fixed remove toolbar when click cardView button.\n        //that.initToolbar();\n        this.initBody();\n        this.trigger('toggle', this.options.cardView);\n    };\n\n    // BOOTSTRAP TABLE PLUGIN DEFINITION\n    // =======================\n\n    var allowedMethods = [\n        'getOptions',\n        'getSelections', 'getAllSelections', 'getData',\n        'load', 'append', 'prepend', 'remove', 'removeAll',\n        'insertRow', 'updateRow', 'updateCell', 'removeByUniqueId',\n        'showRow', 'hideRow', 'getRowsHidden',\n        'mergeCells',\n        'checkAll', 'uncheckAll',\n        'check', 'uncheck',\n        'checkBy', 'uncheckBy',\n        'refresh',\n        'resetView',\n        'resetWidth',\n        'destroy',\n        'showLoading', 'hideLoading',\n        'showColumn', 'hideColumn',\n        'filterBy',\n        'scrollTo',\n        'getScrollPosition',\n        'selectPage', 'prevPage', 'nextPage',\n        'togglePagination',\n        'toggleView'\n    ];\n\n    $.fn.bootstrapTable = function (option) {\n        var value,\n            args = Array.prototype.slice.call(arguments, 1);\n\n        this.each(function () {\n            var $this = $(this),\n                data = $this.data('bootstrap.table'),\n                options = $.extend({}, BootstrapTable.DEFAULTS, $this.data(),\n                    typeof option === 'object' && option);\n\n            if (typeof option === 'string') {\n                if ($.inArray(option, allowedMethods) < 0) {\n                    throw new Error(\"Unknown method: \" + option);\n                }\n\n                if (!data) {\n                    return;\n                }\n\n                value = data[option].apply(data, args);\n\n                if (option === 'destroy') {\n                    $this.removeData('bootstrap.table');\n                }\n            }\n\n            if (!data) {\n                $this.data('bootstrap.table', (data = new BootstrapTable(this, options)));\n            }\n        });\n\n        return typeof value === 'undefined' ? this : value;\n    };\n\n    $.fn.bootstrapTable.Constructor = BootstrapTable;\n    $.fn.bootstrapTable.defaults = BootstrapTable.DEFAULTS;\n    $.fn.bootstrapTable.columnDefaults = BootstrapTable.COLUMN_DEFAULTS;\n    $.fn.bootstrapTable.locales = BootstrapTable.LOCALES;\n    $.fn.bootstrapTable.methods = allowedMethods;\n\n    // BOOTSTRAP TABLE INIT\n    // =======================\n\n    $(function () {\n        $('[data-toggle=\"table\"]').bootstrapTable();\n    });\n\n}(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/cookie/bootstrap-table-cookie.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.1.0\n *\n * @update zhixin wen <wenzhixin2010@gmail.com>\n */\n\n(function ($) {\n    'use strict';\n\n    var idsStateSaveList = {\n        sortOrder: 'bs.table.sortOrder',\n        sortName: 'bs.table.sortName',\n        pageNumber: 'bs.table.pageNumber',\n        pageList: 'bs.table.pageList',\n        columns: 'bs.table.columns',\n        searchText: 'bs.table.searchText'\n    };\n\n    var cookieEnabled = function () {\n        return (navigator.cookieEnabled) ? true : false;\n    };\n\n    var setCookie = function (that, cookieName, sValue, sPath, sDomain, bSecure) {\n        if ((!that.options.stateSave) || (!cookieEnabled()) || (that.options.stateSaveIdTable === '')) {\n            return;\n        }\n\n        var tableName = that.options.stateSaveIdTable,\n            vEnd = that.options.stateSaveExpire;\n\n        cookieName = tableName + '.' + cookieName;\n        if (!cookieName || /^(?:expires|max\\-age|path|domain|secure)$/i.test(cookieName)) {\n            return false;\n        }\n\n        document.cookie = encodeURIComponent(cookieName) + '=' + encodeURIComponent(sValue) + calculateExpiration(vEnd) + (sDomain ? '; domain=' + sDomain : '') + (sPath ? '; path=' + sPath : '') + (bSecure ? '; secure' : '');\n        return true;\n    };\n\n    var getCookie = function (tableName, cookieName) {\n        cookieName = tableName + '.' + cookieName;\n        if (!cookieName) {\n            return null;\n        }\n        return decodeURIComponent(document.cookie.replace(new RegExp('(?:(?:^|.*;)\\\\s*' + encodeURIComponent(cookieName).replace(/[\\-\\.\\+\\*]/g, '\\\\$&') + '\\\\s*\\\\=\\\\s*([^;]*).*$)|^.*$'), '$1')) || null;\n    };\n\n    var hasCookie = function (cookieName) {\n        if (!cookieName) {\n            return false;\n        }\n        return (new RegExp('(?:^|;\\\\s*)' + encodeURIComponent(cookieName).replace(/[\\-\\.\\+\\*]/g, '\\\\$&') + '\\\\s*\\\\=')).test(document.cookie);\n    };\n\n    var deleteCookie = function (tableName, cookieName, sPath, sDomain) {\n        cookieName = tableName + '.' + cookieName;\n        if (!hasCookie(cookieName)) {\n            return false;\n        }\n        document.cookie = encodeURIComponent(cookieName) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT' + (sDomain ? '; domain=' + sDomain : '') + (sPath ? '; path=' + sPath : '');\n        return true;\n    };\n\n    var calculateExpiration = function(vEnd) {\n        var time = vEnd.replace(/[0-9]/, ''); //s,mi,h,d,m,y\n        vEnd = vEnd.replace(/[A-Za-z]/, ''); //number\n\n        switch (time.toLowerCase()) {\n            case 's':\n                vEnd = +vEnd;\n                break;\n            case 'mi':\n                vEnd = vEnd * 60;\n                break;\n            case 'h':\n                vEnd = vEnd * 60 * 60;\n                break;\n            case 'd':\n                vEnd = vEnd * 24 * 60 * 60;\n                break;\n            case 'm':\n                vEnd = vEnd * 30 * 24 * 60 * 60;\n                break;\n            case 'y':\n                vEnd = vEnd * 365 * 30 * 24 * 60 * 60;\n                break;\n            default:\n                vEnd = undefined;\n                break;\n        }\n\n        return vEnd === undefined ? '' : '; max-age=' + vEnd;\n    }\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        stateSave: false,\n        stateSaveExpire: '2h',\n        stateSaveIdTable: ''\n    });\n\n    $.fn.bootstrapTable.methods.push('deleteCookie');\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initTable = BootstrapTable.prototype.initTable,\n        _onSort = BootstrapTable.prototype.onSort,\n        _onPageNumber = BootstrapTable.prototype.onPageNumber,\n        _onPageListChange = BootstrapTable.prototype.onPageListChange,\n        _onPageFirst = BootstrapTable.prototype.onPageFirst,\n        _onPagePre = BootstrapTable.prototype.onPagePre,\n        _onPageNext = BootstrapTable.prototype.onPageNext,\n        _onPageLast = BootstrapTable.prototype.onPageLast,\n        _toggleColumn = BootstrapTable.prototype.toggleColumn,\n        _onSearch = BootstrapTable.prototype.onSearch;\n\n    // init save data after initTable function\n    BootstrapTable.prototype.initTable = function () {\n        _initTable.apply(this, Array.prototype.slice.apply(arguments));\n        this.initStateSave();\n    };\n\n    BootstrapTable.prototype.initStateSave = function () {\n        if (!this.options.stateSave) {\n            return;\n        }\n\n        if (!cookieEnabled()) {\n            return;\n        }\n\n        if (this.options.stateSaveIdTable === '') {\n            return;\n        }\n\n        var sortOrderStateSave = getCookie(this.options.stateSaveIdTable, idsStateSaveList.sortOrder),\n            sortOrderStateName = getCookie(this.options.stateSaveIdTable, idsStateSaveList.sortName),\n            pageNumberStateSave = getCookie(this.options.stateSaveIdTable, idsStateSaveList.pageNumber),\n            pageListStateSave = getCookie(this.options.stateSaveIdTable, idsStateSaveList.pageList),\n            columnsStateSave = JSON.parse(getCookie(this.options.stateSaveIdTable, idsStateSaveList.columns)),\n            searchStateSave = getCookie(this.options.stateSaveIdTable, idsStateSaveList.searchText);\n\n        if (sortOrderStateSave) {\n            this.options.sortOrder = sortOrderStateSave;\n            this.options.sortName = sortOrderStateName;\n        }\n\n        if (pageNumberStateSave) {\n            this.options.pageNumber = +pageNumberStateSave;\n        }\n\n        if (pageListStateSave) {\n            this.options.pageSize = pageListStateSave ===\n                this.options.formatAllRows() ? pageListStateSave : +pageListStateSave;\n        }\n\n        if (columnsStateSave) {\n            $.each(this.options.columns, function (i, column) {\n                column.visible = columnsStateSave.indexOf(i) !== -1;\n            });\n        }\n\n        if (searchStateSave) {\n            this.options.searchText = searchStateSave;\n        }\n    };\n\n    BootstrapTable.prototype.onSort = function () {\n        _onSort.apply(this, Array.prototype.slice.apply(arguments));\n\n        setCookie(this, idsStateSaveList.sortOrder, this.options.sortOrder);\n        setCookie(this, idsStateSaveList.sortName, this.options.sortName);\n    };\n\n    BootstrapTable.prototype.onPageNumber = function () {\n        _onPageNumber.apply(this, Array.prototype.slice.apply(arguments));\n\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.onPageListChange = function () {\n        _onPageListChange.apply(this, Array.prototype.slice.apply(arguments));\n\n        setCookie(this, idsStateSaveList.pageList, this.options.pageSize);\n    };\n\n    BootstrapTable.prototype.onPageFirst = function () {\n        _onPageFirst.apply(this, Array.prototype.slice.apply(arguments));\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.onPagePre = function () {\n        _onPagePre.apply(this, Array.prototype.slice.apply(arguments));\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.onPageNext = function () {\n        _onPageNext.apply(this, Array.prototype.slice.apply(arguments));\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.onPageLast = function () {\n        _onPageLast.apply(this, Array.prototype.slice.apply(arguments));\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.toggleColumn = function () {\n        _toggleColumn.apply(this, Array.prototype.slice.apply(arguments));\n\n        var visibleColumns = [];\n\n        $.each(this.options.columns, function (i) {\n            if (this.visible) {\n                visibleColumns.push(i);\n            }\n        });\n\n        setCookie(this, idsStateSaveList.columns, JSON.stringify(visibleColumns));\n    };\n\n    BootstrapTable.prototype.onSearch = function () {\n        _onSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        setCookie(this, idsStateSaveList.searchText, this.searchText);\n    };\n\n    BootstrapTable.prototype.deleteCookie = function (cookieName) {\n        if ((cookieName === '') || (!cookieEnabled())) {\n            return;\n        }\n\n        deleteCookie(idsStateSaveList[cookieName]);\n    };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/editable/bootstrap-table-editable.js",
    "content": "/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * extensions: https://github.com/vitalets/x-editable\n */\n\n!function ($) {\n\n    'use strict';\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        editable: true,\n        onEditableInit: function () {\n            return false;\n        },\n        onEditableSave: function (field, row, oldValue, $el) {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'editable-init.bs.table': 'onEditableInit',\n        'editable-save.bs.table': 'onEditableSave'\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initTable = BootstrapTable.prototype.initTable,\n        _initBody = BootstrapTable.prototype.initBody;\n\n    BootstrapTable.prototype.initTable = function () {\n        var that = this;\n        _initTable.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.editable) {\n            return;\n        }\n\n        $.each(this.options.columns, function (i, column) {\n            if (!column.editable) {\n                return;\n            }\n\n            var _formatter = column.formatter;\n            column.formatter = function (value, row, index) {\n                var result = _formatter ? _formatter(value, row, index) : value;\n\n                return ['<a href=\"javascript:void(0)\"',\n                    ' data-name=\"' + column.field + '\"',\n                    ' data-pk=\"' + row[that.options.idField] + '\"',\n                    ' data-value=\"' + result + '\"',\n                    '>' + '</a>'\n                ].join('');\n            };\n        });\n    };\n\n    BootstrapTable.prototype.initBody = function () {\n        var that = this;\n        _initBody.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.editable) {\n            return;\n        }\n\n        $.each(this.options.columns, function (i, column) {\n            if (!column.editable) {\n                return;\n            }\n\n            that.$body.find('a[data-name=\"' + column.field + '\"]').editable(column.editable)\n                .off('save').on('save', function (e, params) {\n                    var data = that.getData(),\n                        index = $(this).parents('tr[data-index]').data('index'),\n                        row = data[index],\n                        oldValue = row[column.field];\n\n                    row[column.field] = params.submitValue;\n                    that.trigger('editable-save', column.field, row, oldValue, $(this));\n                });\n        });\n        this.trigger('editable-init');\n    };\n\n}(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/export/bootstrap-table-export.js",
    "content": "/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * extensions: https://github.com/kayalshri/tableExport.jquery.plugin\n */\n\n(function ($) {\n    'use strict';\n\n    var TYPE_NAME = {\n        json: 'JSON',\n        xml: 'XML',\n        png: 'PNG',\n        csv: 'CSV',\n        txt: 'TXT',\n        sql: 'SQL',\n        doc: 'MS-Word',\n        excel: 'Ms-Excel',\n        powerpoint: 'Ms-Powerpoint',\n        pdf: 'PDF'\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        showExport: false,\n        // 'json', 'xml', 'png', 'csv', 'txt', 'sql', 'doc', 'excel', 'powerpoint', 'pdf'\n        exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'],\n        exportOptions: {}\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initToolbar = BootstrapTable.prototype.initToolbar;\n\n    BootstrapTable.prototype.initToolbar = function () {\n        this.showToolbar = this.options.showExport;\n\n        _initToolbar.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.showExport) {\n            var that = this,\n                $btnGroup = this.$toolbar.find('>.btn-group'),\n                $export = $btnGroup.find('div.export');\n\n            if (!$export.length) {\n                $export = $([\n                    '<div class=\"export btn-group\">',\n                        '<button class=\"btn btn-default dropdown-toggle\" ' +\n                            'data-toggle=\"dropdown\" type=\"button\">',\n                            '<i class=\"glyphicon glyphicon-export icon-share\"></i> ',\n                            '<span class=\"caret\"></span>',\n                        '</button>',\n                        '<ul class=\"dropdown-menu\" role=\"menu\">',\n                        '</ul>',\n                    '</div>'].join('')).appendTo($btnGroup);\n\n                var $menu = $export.find('.dropdown-menu'),\n                    exportTypes = this.options.exportTypes;\n\n                if (typeof this.options.exportTypes === 'string') {\n                    var types = this.options.exportTypes.slice(1, -1).replace(/ /g, '').split(',');\n\n                    exportTypes = [];\n                    $.each(types, function (i, value) {\n                        exportTypes.push(value.slice(1, -1));\n                    });\n                }\n                $.each(exportTypes, function (i, type) {\n                    if (TYPE_NAME.hasOwnProperty(type)) {\n                        $menu.append(['<li data-type=\"' + type + '\">',\n                                '<a href=\"javascript:void(0)\">',\n                                    TYPE_NAME[type],\n                                '</a>',\n                            '</li>'].join(''));\n                    }\n                });\n\n                $menu.find('li').click(function () {\n                    that.$el.tableExport($.extend({}, that.options.exportOptions, {\n                        type: $(this).data('type'),\n                        escape: false\n                    }));\n                });\n            }\n        }\n    };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/filter/bootstrap-table-filter.js",
    "content": "/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * extensions: https://github.com/lukaskral/bootstrap-table-filter\n */\n\n!function($) {\n\n    'use strict';\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        showFilter: false\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _init = BootstrapTable.prototype.init,\n        _initSearch = BootstrapTable.prototype.initSearch;\n\n    BootstrapTable.prototype.init = function () {\n        _init.apply(this, Array.prototype.slice.apply(arguments));\n\n        var that = this;\n        this.$el.on('load-success.bs.table', function () {\n            if (that.options.showFilter) {\n                $(that.options.toolbar).bootstrapTableFilter({\n                    connectTo: that.$el\n                });\n            }\n        });\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        _initSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.sidePagination !== 'server') {\n            if (typeof this.searchCallback === 'function') {\n                this.data = $.grep(this.options.data, this.searchCallback);\n            }\n        }\n    };\n\n    BootstrapTable.prototype.getData = function () {\n        return (this.searchText || this.searchCallback) ? this.data : this.options.data;\n    };\n\n    BootstrapTable.prototype.getColumns = function () {\n        return this.options.columns;\n    };\n\n    BootstrapTable.prototype.registerSearchCallback = function (callback) {\n        this.searchCallback = callback;\n    };\n\n    BootstrapTable.prototype.updateSearch = function () {\n        this.options.pageNumber = 1;\n        this.initSearch();\n        this.updatePagination();\n    };\n\n    BootstrapTable.prototype.getServerUrl = function () {\n        return (this.options.sidePagination === 'server') ? this.options.url : false;\n    };\n\n    $.fn.bootstrapTable.methods.push('getColumns',\n        'registerSearchCallback', 'updateSearch',\n        'getServerUrl');\n\n}(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/filter-control/bootstrap-table-filter-control.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.0.0\n */\n\n!function ($) {\n\n    'use strict';\n\n    var sprintf = function (str) {\n        var args = arguments,\n            flag = true,\n            i = 1;\n\n        str = str.replace(/%s/g, function () {\n            var arg = args[i++];\n\n            if (typeof arg === 'undefined') {\n                flag = false;\n                return '';\n            }\n            return arg;\n        });\n        return flag ? str : '';\n    };\n\n    var getFieldIndex = function (columns, field) {\n        var index = -1;\n\n        $.each(columns, function (i, column) {\n            if (column.field === field) {\n                index = i;\n                return false;\n            }\n            return true;\n        });\n        return index;\n    };\n\n    var calculateObjectValue = function (self, name, args, defaultValue) {\n        if (typeof name === 'string') {\n            // support obj.func1.func2\n            var names = name.split('.');\n\n            if (names.length > 1) {\n                name = window;\n                $.each(names, function (i, f) {\n                    name = name[f];\n                });\n            } else {\n                name = window[name];\n            }\n        }\n        if (typeof name === 'object') {\n            return name;\n        }\n        if (typeof name === 'function') {\n            return name.apply(self, args);\n        }\n        return defaultValue;\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        filterControl: false,\n        onColumnSearch: function (field, text) {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {\n        filterControl: undefined,\n        filterData: undefined\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'column-search.bs.table': 'onColumnSearch'\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initHeader = BootstrapTable.prototype.initHeader,\n        _initBody = BootstrapTable.prototype.initBody,\n        _initSearch = BootstrapTable.prototype.initSearch;\n\n    BootstrapTable.prototype.initHeader = function () {\n        _initHeader.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.filterControl) {\n            return;\n        }\n\n        var addedFilterControl = false,\n            that = this,\n            isVisible,\n            html,\n            timeoutId = 0;\n\n        $.each(this.options.columns, function (i, column) {\n            isVisible = 'hidden';\n            html = [];\n\n            if (!column.visible) {\n                return;\n            }\n\n            if (!column.filterControl) {\n                html.push('<div style=\"height: 34px;\"></div>');\n            } else {\n                html.push('<div style=\"margin: 0px 2px 2px 2px;\" class=\"filterControl\">');\n\n                if (column.filterControl && column.searchable) {\n                    addedFilterControl = true;\n                    isVisible = 'visible'\n                }\n                switch (column.filterControl.toLowerCase()) {\n                    case 'input' :\n                        html.push(sprintf('<input type=\"text\" class=\"form-control\" style=\"width: 100%; visibility: %s\">', isVisible));\n                        break;\n                    case 'select':\n                        html.push(sprintf('<select class=\"%s form-control\" style=\"width: 100%; visibility: %s\"></select>',\n                            column.field, isVisible))\n                        break;\n                }\n            }\n\n            that.$header.find(sprintf('.th-inner:eq(\"%s\")', i)).next().append(html.join(''));\n            if (column.filterData !== undefined && column.filterData.toLowerCase() !== 'column') {\n                var filterDataType = column.filterData.substring(0, 3);\n                var filterDataSource = column.filterData.substring(4, column.filterData.length);\n                var selectControl = $('.' + column.field);\n                selectControl.append($(\"<option></option>\")\n                    .attr(\"value\", '')\n                    .text(''));\n                switch (filterDataType) {\n                    case 'url':\n                        $.ajax({\n                            url: filterDataSource,\n                            dataType: 'json',\n                            success: function (data) {\n                                $.each(data, function (key, value) {\n                                    selectControl.append($(\"<option></option>\")\n                                        .attr(\"value\", key)\n                                        .text(value));\n                                });\n                            }\n                        });\n                        break;\n                    case 'var':\n                        var variableValues = window[filterDataSource];\n                        for (var key in variableValues) {\n                            selectControl.append($(\"<option></option>\")\n                                .attr(\"value\", key)\n                                .text(variableValues[key]));\n                        };\n                        break;\n                }\n            }\n        });\n\n        if (addedFilterControl) {\n            this.$header.off('keyup', 'input').on('keyup', 'input', function (event) {\n                clearTimeout(timeoutId);\n                timeoutId = setTimeout(function () {\n                    that.onColumnSearch(event);\n                }, that.options.searchTimeOut);\n            });\n\n            this.$header.off('change', 'select').on('change', 'select', function (event) {\n                clearTimeout(timeoutId);\n                timeoutId = setTimeout(function () {\n                    that.onColumnSearch(event);\n                }, that.options.searchTimeOut);\n            });\n        } else {\n            this.$header.find('.filterControl').hide();\n        }\n    };\n\n    BootstrapTable.prototype.initBody = function () {\n        _initBody.apply(this, Array.prototype.slice.apply(arguments));\n\n        var that = this,\n            data = this.getData();\n\n        for (var i = this.pageFrom - 1; i < this.pageTo; i++) {\n            var key,\n                item = data[i];\n\n            $.each(this.header.fields, function (j, field) {\n                var value = item[field],\n                    column = that.options.columns[getFieldIndex(that.options.columns, field)];\n\n                value = calculateObjectValue(that.header,\n                    that.header.formatters[j], [value, item, i], value);\n\n                if ((!column.checkbox) || (!column.radio)) {\n                    if (column.filterControl !== undefined && column.filterControl.toLowerCase() === 'select'\n                            && column.searchable) {\n\n                        if (column.filterData === undefined || column.filterData.toLowerCase() === 'column') {\n                            var selectControl = $('.' + column.field),\n                                    iOpt = 0,\n                                    exitsOpt = false,\n                                    options;\n                            if (selectControl !== undefined) {\n                                options = selectControl.get(0).options;\n\n                                if (options.length === 0) {\n\n                                    //Added the default option\n                                    selectControl.append($(\"<option></option>\")\n                                        .attr(\"value\", '')\n                                        .text(''));\n\n                                    selectControl.append($(\"<option></option>\")\n                                        .attr(\"value\", value)\n                                        .text(value));\n                                } else {\n                                    for (; iOpt < options.length; iOpt++) {\n                                        if (options[iOpt].value === value) {\n                                            exitsOpt = true;\n                                            break;\n                                        }\n                                    }\n\n                                    if (!exitsOpt) {\n                                        selectControl.append($(\"<option></option>\")\n                                            .attr(\"value\", value)\n                                            .text(value));\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            });\n        }\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        _initSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        var that = this;\n        var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial;\n\n        //Check partial column filter\n        this.data = fp ? $.grep(this.data, function (item, i) {\n            for (var key in fp) {\n                var fval = fp[key].toLowerCase();\n                var value = item[key];\n                value = calculateObjectValue(that.header,\n                    that.header.formatters[$.inArray(key, that.header.fields)],\n                    [value, item, i], value);\n\n                if (!($.inArray(key, that.header.fields) !== -1 &&\n                    (typeof value === 'string' || typeof value === 'number') &&\n                    (value + '').toLowerCase().indexOf(fval) !== -1)) {\n                    return false;\n                }\n            }\n            return true;\n        }) : this.data;\n    };\n\n    BootstrapTable.prototype.onColumnSearch = function (event) {\n        var text = $.trim($(event.currentTarget).val());\n        var $field = $(event.currentTarget).parent().parent().parent().data('field')\n\n        if ($.isEmptyObject(this.filterColumnsPartial)) {\n            this.filterColumnsPartial = {};\n        }\n        if (text) {\n            this.filterColumnsPartial[$field] = text;\n        } else {\n            delete this.filterColumnsPartial[$field];\n        }\n\n        this.options.pageNumber = 1;\n        this.onSearch(event);\n        this.updatePagination();\n        this.trigger('column-search', $field, text);\n    };\n}(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/flat-json/bootstrap-table-flat-json.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.2.0\n */\n\n\n(function ($) {\n    'use strict';\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        flat: false\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initData = BootstrapTable.prototype.initData;\n\n    BootstrapTable.prototype.initData = function (data, type) {\n        if( this.options.flat ){\n            data = data === undefined ? this.options.data : data;\n            data = sd.flatHelper(data);\n        }\n        _initData.apply(this, [data, type]);\n    };\n\n    //Main functions\n    var sd = {\n        flat: function (element) {\n            var result = {};\n\n            function recurse(cur, prop) {\n                if (Object(cur) !== cur) {\n                    result[prop] = cur;\n                } else if ($.isArray(cur)) {\n                    for (var i = 0, l = cur.length; i < l; i++) {\n                        recurse(cur[i], prop ? prop + \".\" + i : \"\" + i);\n                        if (l == 0) {\n                            result[prop] = [];\n                        }\n                    }\n                } else {\n                    var isEmpty = true;\n                    for (var p in cur) {\n                        isEmpty = false;\n                        recurse(cur[p], prop ? prop + \".\" + p : p);\n                    }\n                    if (isEmpty) {\n                        result[prop] = {};\n                    }\n                }\n            }\n\n            recurse(element, \"\");\n            return result;\n        },\n\n        flatHelper: function (data) {\n            var flatArray = [],\n                arrayHelper = [];\n            if (!$.isArray(data)) {\n                arrayHelper.push(data);\n                data = arrayHelper;\n            }\n            $.each(data, function (i, element) {\n                flatArray.push(sd.flat(element));\n            });\n            return flatArray;\n        }\n    };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/key-events/bootstrap-table-key-events.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.0.0\n *\n * @update zhixin wen <wenzhixin2010@gmail.com>\n */\n\n!function ($) {\n\n    'use strict';\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        keyEvents: false\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _init = BootstrapTable.prototype.init;\n\n    BootstrapTable.prototype.init = function () {\n        _init.apply(this, Array.prototype.slice.apply(arguments));\n\n        this.initKeyEvents();\n    };\n\n    BootstrapTable.prototype.initKeyEvents = function () {\n        if (this.options.keyEvents) {\n            var that = this;\n\n            $(document).off('keydown').on('keydown', function (e) {\n                var $search = that.$toolbar.find('.search input'),\n                    $refresh = that.$toolbar.find('button[name=\"refresh\"]'),\n                    $toggle = that.$toolbar.find('button[name=\"toggle\"]'),\n                    $paginationSwitch = that.$toolbar.find('button[name=\"paginationSwitch\"]');\n\n                if (document.activeElement === $search.get(0)) {\n                    return true;\n                }\n\n                switch (e.keyCode) {\n                    case 83: //s\n                        if (!that.options.search) {\n                            return;\n                        }\n                        $search.focus();\n                        return false;\n                    case 82: //r\n                        if (!that.options.showRefresh) {\n                            return;\n                        }\n                        $refresh.click();\n                        return false;\n                    case 84: //t\n                        if (!that.options.showToggle) {\n                            return;\n                        }\n                        $toggle.click();\n                        return false;\n                    case 80: //p\n                        if (!that.options.showPaginationSwitch) {\n                            return;\n                        }\n                        $paginationSwitch.click();\n                        return false;\n                    case 37: // left\n                        if (!that.options.pagination) {\n                            return;\n                        }\n                        that.prevPage();\n                        return false;\n                    case 39: // right\n                        if (!that.options.pagination) {\n                            return;\n                        }\n                        that.nextPage();\n                        return;\n                }\n            });\n        }\n    };\n}(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/mobile/bootstrap-table-mobile.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.1.0\n */\n\n!function ($) {\n\n    'use strict';\n\n    var resetView = function (that) {\n        if (that.options.height || that.options.showFooter) {\n            setTimeout(that.resetView(), 1);\n        }\n    };\n\n    var changeView = function (that, width, height) {\n        if (that.options.minHeight) {\n            if (checkValuesLessEqual(width, that.options.minWidth) && checkValuesLessEqual(height, that.options.minHeight)) {\n                conditionCardView(that);\n            } else if (checkValuesGreater(width, that.options.minWidth) && checkValuesGreater(height, that.options.minHeight)) {\n                conditionFullView(that);\n            }\n        } else {\n            if (checkValuesLessEqual(width, that.options.minWidth)) {\n                conditionCardView(that);\n            } else if (checkValuesGreater(width, that.options.minWidth)) {\n                conditionFullView(that);\n            }\n        }\n\n        resetView(that);\n    };\n\n    var checkValuesLessEqual = function (currentValue, targetValue) {\n        return currentValue <= targetValue;\n    };\n\n    var checkValuesGreater = function (currentValue, targetValue) {\n        return currentValue > targetValue;\n    };\n\n    var conditionCardView = function (that) {\n        changeTableView(that, false);\n    };\n\n    var conditionFullView = function (that) {\n        changeTableView(that, true);\n    };\n\n    var changeTableView = function (that, cardViewState) {\n        that.options.cardView = cardViewState;\n        that.toggleView();\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        mobileResponsive: false,\n        minWidth: 562,\n        minHeight: undefined,\n        checkOnInit: true,\n        toggled: false\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _init = BootstrapTable.prototype.init;\n\n    BootstrapTable.prototype.init = function () {\n        _init.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.mobileResponsive) {\n            return;\n        }\n\n        if (!this.options.minWidth) {\n            return;\n        }\n\n        var that = this;\n        $(window).resize(function () {\n            changeView(that, $(this).width(), $(this).height())\n        });\n\n        if (this.options.checkOnInit) {\n            changeView(this, $(window).width(), $(window).height());\n        }\n    };\n}(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/multiple-sort/bootstrap-table-multiple-sort.js",
    "content": "/**\n * @author Nadim Basalamah <dimbslmh@gmail.com>\n * @version: v1.0.0\n * https://github.com/dimbslmh/bootstrap-table/tree/master/src/extensions/multiple-sort/bootstrap-table-multiple-sort.js\n */\n\n(function($) {\n    'use strict';\n\n    var isSingleSort = false;\n\n    var sort_order = {\n            asc: 'Ascending',\n            desc: 'Descending'\n        },\n        arrowAsc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ' +\n        '0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBd' +\n        'qEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVo' +\n        'AADeemwtPcZI2wAAAABJRU5ErkJggg==',\n        arrowDesc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWj' +\n        'YBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJ' +\n        'zcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= ';\n\n    var showSortModal = function(that) {\n        if (!$(\"#sortModal\").hasClass(\"modal\")) {\n            var sModal = '  <div class=\"modal fade\" id=\"sortModal\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"sortModalLabel\" aria-hidden=\"true\">';\n            sModal += '         <div class=\"modal-dialog\">';\n            sModal += '             <div class=\"modal-content\">';\n            sModal += '                 <div class=\"modal-header\">';\n            sModal += '                     <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\"><span aria-hidden=\"true\">&times;</span></button>';\n            sModal += '                     <h4 class=\"modal-title\" id=\"sortModalLabel\">' + that.options.formatMultipleSort() + '</h4>';\n            sModal += '                 </div>';\n            sModal += '                 <div class=\"modal-body\">';\n            sModal += '                     <div class=\"bootstrap-table\">';\n            sModal += '                         <div class=\"fixed-table-toolbar\">';\n            sModal += '                             <div class=\"bars\">';\n            sModal += '                                 <div id=\"toolbar\">';\n            sModal += '                                     <button id=\"add\" type=\"button\" class=\"btn btn-default\"><i class=\"' + that.options.iconsPrefix + ' ' + that.options.icons.plus + '\"></i> ' + that.options.formatAddLevel() + '</button>';\n            sModal += '                                     <button id=\"delete\" type=\"button\" class=\"btn btn-default\" disabled><i class=\"' + that.options.iconsPrefix + ' ' + that.options.icons.minus + '\"></i> ' + that.options.formatDeleteLevel() + '</button>';\n            sModal += '                                 </div>';\n            sModal += '                             </div>';\n            sModal += '                         </div>';\n            sModal += '                         <div class=\"fixed-table-container\">';\n            sModal += '                             <table id=\"multi-sort\" class=\"table\">';\n            sModal += '                                 <thead>';\n            sModal += '                                     <tr>';\n            sModal += '                                         <th></th>';\n            sModal += '                                         <th><div class=\"th-inner\">' + that.options.formatColumn() + '</div></th>';\n            sModal += '                                         <th><div class=\"th-inner\">' + that.options.formatOrder() + '</div></th>';\n            sModal += '                                     </tr>';\n            sModal += '                                 </thead>';\n            sModal += '                                 <tbody></tbody>';\n            sModal += '                             </table>';\n            sModal += '                         </div>';\n            sModal += '                     </div>';\n            sModal += '                 </div>';\n            sModal += '                 <div class=\"modal-footer\">';\n            sModal += '                     <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">' + that.options.formatCancel() + '</button>';\n            sModal += '                     <button type=\"button\" class=\"btn btn-primary\">' + that.options.formatSort() + '</button>';\n            sModal += '                 </div>';\n            sModal += '             </div>';\n            sModal += '         </div>';\n            sModal += '     </div>';\n\n            $(\"body\").append($(sModal));\n\n            var $sortModal = $('#sortModal'),\n                $rows = $sortModal.find(\"tbody > tr\");\n\n            $sortModal.off('click', '#add').on('click', '#add', function() {\n                var total = $sortModal.find('.multi-sort-name:first option').length,\n                    current = $sortModal.find('tbody tr').length;\n\n                if (current < total) {\n                    current++;\n                    that.addLevel();\n                    that.setButtonStates();\n                }\n            });\n\n            $sortModal.off('click', '#delete').on('click', '#delete', function() {\n                var total = $sortModal.find('.multi-sort-name:first option').length,\n                    current = $sortModal.find('tbody tr').length;\n\n                if (current > 1 && current <= total) {\n                    current--;\n                    $sortModal.find('tbody tr:last').remove();\n                    that.setButtonStates();\n                }\n            });\n\n            $sortModal.off('click', '.btn-primary').on('click', '.btn-primary', function() {\n                var $rows = $sortModal.find(\"tbody > tr\"),\n                    $alert = $sortModal.find('div.alert'),\n                    fields = [],\n                    results = [];\n\n\n                that.options.sortPriority = $.map($rows, function(row) {\n                    var $row = $(row),\n                        name = $row.find('.multi-sort-name').val(),\n                        order = $row.find('.multi-sort-order').val();\n\n                    fields.push(name);\n\n                    return {\n                        sortName: name,\n                        sortOrder: order\n                    };\n                });\n\n                var sorted_fields = fields.sort();\n\n                for (var i = 0; i < fields.length - 1; i++) {\n                    if (sorted_fields[i + 1] == sorted_fields[i]) {\n                        results.push(sorted_fields[i]);\n                    }\n                }\n\n                if (results.length > 0) {\n                    if ($alert.length === 0) {\n                        $alert = '<div class=\"alert alert-danger\" role=\"alert\"><strong>' + that.options.formatDuplicateAlertTitle() + '</strong> ' + that.options.formatDuplicateAlertDescription() + '</div>';\n                        $($alert).insertBefore($sortModal.find('.bars'));\n                    }\n                } else {\n                    if ($alert.length === 1) {\n                        $($alert).remove();\n                    }\n\n                    that.options.sortName = \"\";\n                    that.onMultipleSort();\n                    $sortModal.modal('hide');\n                }\n            });\n\n            if (that.options.sortPriority === null) {\n                if (that.options.sortName) {\n                    that.options.sortPriority = [{\n                        sortName: that.options.sortName,\n                        sortOrder: that.options.sortOrder\n                    }];\n                }\n            }\n            \n            if (that.options.sortPriority !== null) {\n                if ($rows.length < that.options.sortPriority.length && typeof that.options.sortPriority === 'object') {\n                    for (var i = 0; i < that.options.sortPriority.length; i++) {\n                        that.addLevel(i, that.options.sortPriority[i]);\n                    }\n                }\n            } else {\n                that.addLevel(0);\n            }\n\n            that.setButtonStates();\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        showMultiSort: false,\n        sortPriority: null,\n        onMultipleSort: function() {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.defaults.icons, {\n        sort: 'glyphicon-sort',\n        plus: 'glyphicon-plus',\n        minus: 'glyphicon-minus'\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'multiple-sort.bs.table': 'onMultipleSort'\n    });\n\n    $.extend($.fn.bootstrapTable.locales, {\n        formatMultipleSort: function() {\n            return 'Multiple Sort';\n        },\n        formatAddLevel: function() {\n            return \"Add Level\";\n        },\n        formatDeleteLevel: function() {\n            return \"Delete Level\";\n        },\n        formatColumn: function() {\n            return \"Column\";\n        },\n        formatOrder: function() {\n            return \"Order\";\n        },\n        formatSortBy: function() {\n            return \"Sort by\";\n        },\n        formatThenBy: function() {\n            return \"Then by\";\n        },\n        formatSort: function() {\n            return \"Sort\";\n        },\n        formatCancel: function() {\n            return \"Cancel\";\n        },\n        formatDuplicateAlertTitle: function() {\n            return \"Duplicate(s) detected!\";\n        },\n        formatDuplicateAlertDescription: function() {\n            return \"Please remove or change any duplicate column.\";\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initToolbar = BootstrapTable.prototype.initToolbar;\n\n    BootstrapTable.prototype.initToolbar = function() {\n        this.showToolbar = true;\n        var that = this;\n\n        _initToolbar.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.showMultiSort) {\n            var $btnGroup = this.$toolbar.find('>.btn-group'),\n                $multiSortBtn = $btnGroup.find('div.multi-sort');\n\n            if (!$multiSortBtn.length) {\n                $multiSortBtn = '  <button class=\"multi-sort btn btn-default' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + '\" type=\"button\" data-toggle=\"modal\" data-target=\"#sortModal\" title=\"' + this.options.formatMultipleSort() + '\">';\n                $multiSortBtn += '     <i class=\"' + this.options.iconsPrefix + ' ' + this.options.icons.sort + '\"></i>';\n                $multiSortBtn += '</button>';\n\n                $btnGroup.append($multiSortBtn);\n\n                showSortModal(that);\n            }\n\n            this.$el.one('sort.bs.table', function() {\n                isSingleSort = true;\n            });\n\n            this.$el.on('multiple-sort.bs.table', function() {\n                isSingleSort = false;\n            });\n\n            this.$el.on('load-success.bs.table', function() {\n                if (!isSingleSort && that.options.sortPriority !== null && typeof that.options.sortPriority === 'object') {\n                    that.onMultipleSort();\n                }\n            });\n\n            this.$el.on('column-switch.bs.table', function() {\n                that.options.sortPriority = null;\n                $('#sortModal').remove();\n                showSortModal(that);\n            });\n        }\n    };\n\n    BootstrapTable.prototype.onMultipleSort = function() {\n        var that = this;\n        \n        var cmp = function(x, y) {\n            return x > y ? 1 : x < y ? -1 : 0;\n        };\n\n        var arrayCmp = function(a, b) {\n            var arr1 = [],\n                arr2 = [];\n\n            for (var i = 0; i < that.options.sortPriority.length; i++) {\n                var order = that.options.sortPriority[i].sortOrder === 'desc' ? -1 : 1,\n                    aa = a[that.options.sortPriority[i].sortName],\n                    bb = b[that.options.sortPriority[i].sortName];\n\n                if (aa === undefined || aa === null) {\n                    aa = '';\n                }\n                if (bb === undefined || bb === null) {\n                    bb = '';\n                }\n                if ($.isNumeric(aa) && $.isNumeric(bb)) {\n                    aa = parseFloat(aa);\n                    bb = parseFloat(bb);\n                }\n                if (typeof aa !== 'string') {\n                    aa = aa.toString();\n                }\n\n                arr1.push(\n                    order * cmp(aa, bb));\n                arr2.push(\n                    order * cmp(bb, aa));\n            }\n\n            return cmp(arr1, arr2);\n        };\n\n        this.data.sort(function(a, b) {\n            return arrayCmp(a, b);\n        });\n\n        this.initBody();\n        this.assignSortableArrows();\n        this.trigger('multiple-sort');\n    };\n\n    BootstrapTable.prototype.addLevel = function(index, sortPriority) {\n        var $sortModal = $(\"#sortModal\"),\n            text = index === 0 ? this.options.formatSortBy() : this.options.formatThenBy();\n\n        $sortModal.find('tbody')\n            .append($('<tr>')\n                .append($('<td>').text(text))\n                .append($('<td>').append($('<select class=\"form-control multi-sort-name\">')))\n                .append($('<td>').append($('<select class=\"form-control multi-sort-order\">')))\n            );\n\n        var $multiSortName = $sortModal.find('.multi-sort-name').last(),\n            $multiSortOrder = $sortModal.find('.multi-sort-order').last();\n\n        this.options.columns.forEach(function(column) {\n            if (column.sortable === false || column.visible === false) {\n                return true;\n            }\n            $multiSortName.append('<option value=\"' + column.field + '\">' + column.title + '</option>');\n        });\n\n        $.each(sort_order, function(value, order) {\n            $multiSortOrder.append('<option value=\"' + value + '\">' + order + '</option>');\n        });\n\n        if (sortPriority !== undefined) {\n            $multiSortName.find('option[value=\"' + sortPriority.sortName + '\"]').attr(\"selected\", true);\n            $multiSortOrder.find('option[value=\"' + sortPriority.sortOrder + '\"]').attr(\"selected\", true);\n        }\n    };\n\n    BootstrapTable.prototype.assignSortableArrows = function() {\n        var that = this,\n            headers = that.$header.find('th');\n\n        for (var i = 0; i < headers.length; i++) {\n            for (var c = 0; c < that.options.sortPriority.length; c++) {\n                if ($(headers[i]).data('field') === that.options.sortPriority[c].sortName) {\n                    $(headers[i]).find('.sortable').css('background-image', 'url(' + (that.options.sortPriority[c].sortOrder === 'desc' ? arrowDesc : arrowAsc) + ')');\n                }\n            }\n        }\n    };\n\n    BootstrapTable.prototype.setButtonStates = function() {\n        var $sortModal = $('#sortModal'),\n            total = $sortModal.find('.multi-sort-name:first option').length,\n            current = $sortModal.find('tbody tr').length;\n\n        if (current == total) {\n            $sortModal.find('#add').attr('disabled', 'disabled');\n        }\n        if (current > 1) {\n            $sortModal.find('#delete').removeAttr('disabled');\n        }\n        if (current < total) {\n            $sortModal.find('#add').removeAttr('disabled');\n        }\n        if (current == 1) {\n            $sortModal.find('#delete').attr('disabled', 'disabled');\n        }\n    };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/natural-sorting/bootstrap-table-natural-sorting.js",
    "content": "/**\n * @author: Brian Huisman\n * @webSite: http://www.greywyvern.com\n * @version: v1.0.0\n * JS function to allow natural sorting on bootstrap-table columns\n * just add data-sorter=\"alphanum\" to any th\n *\n * @update Dennis Hernández <http://djhvscf.github.io/Blog>\n */\n\nfunction alphanum(a, b) {\n  function chunkify(t) {\n    var tz = [],\n        x = 0,\n        y = -1,\n        n = 0,\n        i,\n        j;\n\n    while (i = (j = t.charAt(x++)).charCodeAt(0)) {\n      var m = (i === 46 || (i >= 48 && i <= 57));\n      if (m !== n) {\n        tz[++y] = \"\";\n        n = m;\n      }\n      tz[y] += j;\n    }\n    return tz;\n  }\n\n  var aa = chunkify(a);\n  var bb = chunkify(b);\n\n  for (x = 0; aa[x] && bb[x]; x++) {\n    if (aa[x] !== bb[x]) {\n      var c = Number(aa[x]),\n          d = Number(bb[x]);\n\n      if (c == aa[x] && d == bb[x]) {\n        return c - d;\n      } else {\n          return (aa[x] > bb[x]) ? 1 : -1;\n      }\n    }\n  }\n  return aa.length - bb.length;\n}"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/reorder-columns/bootstrap-table-reorder-columns.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.1.0\n */\n\n!function ($) {\n\n    'use strict';\n\n    var getFieldIndex = function (columns, field) {\n        var index = -1;\n\n        $.each(columns, function (i, column) {\n            if (column.field === field) {\n                index = i;\n                return false;\n            }\n            return true;\n        });\n        return index;\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        reorderableColumns: false,\n        maxMovingRows: 10,\n        onReorderColumn: function (headerFields) {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'reorder-column.bs.table': 'onReorderColumn'\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initHeader = BootstrapTable.prototype.initHeader,\n        _toggleColumn = BootstrapTable.prototype.toggleColumn,\n        _toggleView = BootstrapTable.prototype.toggleView,\n        _resetView = BootstrapTable.prototype.resetView;\n\n    BootstrapTable.prototype.initHeader = function () {\n        _initHeader.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableColumns) {\n            return;\n        }\n\n        this.makeRowsReorderable();\n    };\n\n    BootstrapTable.prototype.toggleColumn = function () {\n        _toggleColumn.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableColumns) {\n            return;\n        }\n\n        this.makeRowsReorderable();\n    };\n\n    BootstrapTable.prototype.toggleView = function () {\n        _toggleView.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableColumns) {\n            return;\n        }\n\n        if (this.options.cardView) {\n            return;\n        }\n\n        this.makeRowsReorderable();\n    };\n\n    BootstrapTable.prototype.resetView = function () {\n        _resetView.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableColumns) {\n            return;\n        }\n\n        this.makeRowsReorderable();\n    };\n\n    BootstrapTable.prototype.makeRowsReorderable = function () {\n\n        var that = this;\n        try {\n            $(this.$el).dragtable('destroy');\n        } catch (e) {}\n        $(this.$el).dragtable({\n            maxMovingRows: that.options.maxMovingRows,\n            clickDelay:200,\n            beforeStop: function() {\n                var ths = [],\n                    columns = [],\n                    columnIndex = -1;\n                that.$header.find('th').each(function (i) {\n                    ths.push($(this).data('field'));\n                });\n\n                for (var i = 0; i < ths.length; i++ ) {\n                    columnIndex = getFieldIndex(that.options.columns, ths[i]);\n                    if (columnIndex !== -1) {\n                        columns.push(that.options.columns[columnIndex]);\n                        that.options.columns.splice(columnIndex, 1);\n                    }\n                }\n\n                that.options.columns = that.options.columns.concat(columns);\n                that.header.fields = ths;\n                that.resetView();\n                that.trigger('reorder-column', ths);\n            }\n        });\n    };\n}(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/reorder-rows/bootstrap-table-reorder-rows.css",
    "content": ".reorder_rows_onDragClass td {\n    background-color: #eee;\n    -webkit-box-shadow: 11px 5px 12px 2px #333, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;\n    -webkit-box-shadow: 6px 3px 5px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;\n    -moz-box-shadow: 6px 4px 5px 1px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;\n    -box-shadow: 6px 4px 5px 1px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;\n}\n\n.reorder_rows_onDragClass td:last-child {\n    -webkit-box-shadow: 8px 7px 12px 0 #333, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;\n    -webkit-box-shadow: 1px 8px 6px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;\n    -moz-box-shadow: 0 9px 4px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset, -1px 0 0 #ccc inset;\n    -box-shadow: 0 9px 4px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset, -1px 0 0 #ccc inset;\n}"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/reorder-rows/bootstrap-table-reorder-rows.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.0.0\n */\n\n!function ($) {\n\n    'use strict';\n\n    var isSearch = false;\n\n    var rowAttr = function (row, index) {\n        return {\n            id: 'customId_' + index\n        };\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        reorderableRows: false,\n        onDragStyle: null,\n        onDropStyle: null,\n        onDragClass: \"reorder_rows_onDragClass\",\n        dragHandle: null,\n        useRowAttrFunc: false,\n        onReorderRowsDrag: function (table, row) {\n            return false;\n        },\n        onReorderRowsDrop: function (table, row) {\n            return false;\n        },\n        onReorderRow: function (newData) {\n             return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'reorder-row.bs.table': 'onReorderRow'\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _init = BootstrapTable.prototype.init,\n        _initSearch = BootstrapTable.prototype.initSearch;\n\n    BootstrapTable.prototype.init = function () {\n\n        _init.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableRows) {\n            return;\n        }\n\n        var that = this;\n        if (this.options.useRowAttrFunc) {\n            this.options.rowAttributes = rowAttr;\n        }\n\n        var onPostBody = this.options.onPostBody;\n        this.options.onPostBody = function () {\n            setTimeout(function () {\n                that.makeRowsReorderable();\n                onPostBody.apply();\n            }, 1);\n        };\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        _initSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableRows) {\n            return;\n        }\n\n        //Known issue after search if you reorder the rows the data is not display properly\n        //isSearch = true;\n    };\n\n    BootstrapTable.prototype.makeRowsReorderable = function () {\n        if (this.options.cardView) {\n            return;\n        }\n\n        var that = this;\n        this.$el.tableDnD({\n            onDragStyle: that.options.onDragStyle,\n            onDropStyle: that.options.onDropStyle,\n            onDragClass: that.options.onDragClass,\n            onDrop: that.onDrop,\n            onDragStart: that.options.onReorderRowsDrag,\n            dragHandle: that.options.dragHandle\n        });\n    };\n\n    BootstrapTable.prototype.onDrop = function (table, row) {\n        var tableBs = $(table),\n            tableBsData = tableBs.data('bootstrap.table'),\n            tableBsOptions = tableBs.data('bootstrap.table').options,\n            row = null,\n            newData = [];\n\n        for (var i = 0; i < table.tBodies[0].rows.length; i++) {\n            row = $(table.tBodies[0].rows[i]);\n            newData.push(tableBsOptions.data[row.data('index')]);\n            row.data('index', i).attr('data-index', i);\n        }\n\n        tableBsOptions.data = newData;\n\n        //Call the user defined function\n        tableBsOptions.onReorderRowsDrop.apply(table, row);\n\n        //Call the event reorder-row\n        tableBsData.trigger('reorder-row', newData);\n    };\n}(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/resizable/bootstrap-table-resizable.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.0.0\n */\n\n(function ($) {\n    'use strict';\n\n    var initResizable = function (that) {\n        //Deletes the plugin to re-create it\n        that.$el.colResizable({disable: true});\n\n        //Creates the plugin\n        that.$el.colResizable({\n            liveDrag: that.options.liveDrag,\n            fixed: that.options.fixed,\n            headerOnly: that.options.headerOnly,\n            minWidth: that.options.minWidth,\n            hoverCursor: that.options.hoverCursor,\n            dragCursor: that.options.dragCursor,\n            onResize: that.onResize,\n            onDrag: that.options.onResizableDrag\n        });\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        resizable: false,\n        liveDrag: false,\n        fixed: true,\n        headerOnly: false,\n        minWidth: 15,\n        hoverCursor: 'e-resize',\n        dragCursor: 'e-resize',\n        onResizableResize: function (e) {\n            return false;\n        },\n        onResizableDrag: function (e) {\n            return false;\n        }\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _toggleView = BootstrapTable.prototype.toggleView,\n        _resetView = BootstrapTable.prototype.resetView;\n\n    BootstrapTable.prototype.toggleView = function () {\n        _toggleView.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.resizable && this.options.cardView) {\n            //Deletes the plugin\n            $(this.$el).colResizable({disable: true});\n        }\n    };\n\n    BootstrapTable.prototype.resetView = function () {\n        var that = this;\n\n        _resetView.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.resizable) {\n            // because in fitHeader function, we use setTimeout(func, 100);\n            setTimeout(function () {\n                initResizable(that);\n            }, 100);\n        }\n    };\n\n    BootstrapTable.prototype.onResize = function (e) {\n        var that = $(e.currentTarget);\n        that.bootstrapTable('resetView');\n        that.data('bootstrap.table').options.onResizableResize.apply(e);\n    }\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/extensions/toolbar/bootstrap-table-toolbar.js",
    "content": "/**\n * @author: aperez <aperez@datadec.es>\n * @version: v2.0.0\n *\n * @update Dennis Hernández <http://djhvscf.github.io/Blog>\n */\n\n!function($) {\n    'use strict';\n\n    var firstLoad = false;\n\n    var sprintf = function(str) {\n        var args = arguments,\n            flag = true,\n            i = 1;\n\n        str = str.replace(/%s/g, function() {\n            var arg = args[i++];\n\n            if (typeof arg === 'undefined') {\n                flag = false;\n                return '';\n            }\n            return arg;\n        });\n        return flag ? str : '';\n    };\n\n    var calculateObjectValue = function (self, name, args, defaultValue) {\n        if (typeof name === 'string') {\n            // support obj.func1.func2\n            var names = name.split('.');\n\n            if (names.length > 1) {\n                name = window;\n                $.each(names, function (i, f) {\n                    name = name[f];\n                });\n            } else {\n                name = window[name];\n            }\n        }\n        if (typeof name === 'object') {\n            return name;\n        }\n        if (typeof name === 'function') {\n            return name.apply(self, args);\n        }\n        return defaultValue;\n    };\n\n    var showAvdSearch = function(pColumns, searchTitle, searchText, that) {\n        if (!$(\"#avdSearchModal\").hasClass(\"modal\")) {\n            var vModal = \"<div id=\\\"avdSearchModal\\\" class=\\\"modal fade\\\" tabindex=\\\"-1\\\" role=\\\"dialog\\\" aria-labelledby=\\\"mySmallModalLabel\\\" aria-hidden=\\\"true\\\">\";\n            vModal += \"<div class=\\\"modal-dialog modal-xs\\\">\";\n            vModal += \" <div class=\\\"modal-content\\\">\";\n            vModal += \"  <div class=\\\"modal-header\\\">\";\n            vModal += \"   <button type=\\\"button\\\" class=\\\"close\\\" data-dismiss=\\\"modal\\\" aria-hidden=\\\"true\\\" >&times;</button>\";\n            vModal += sprintf(\"   <h4 class=\\\"modal-title\\\">%s</h4>\", searchTitle);\n            vModal += \"  </div>\";\n            vModal += \"  <div class=\\\"modal-body modal-body-custom\\\">\";\n            vModal += \"   <div class=\\\"container-fluid\\\" id=\\\"avdSearchModalContent\\\" style=\\\"padding-right: 0px;padding-left: 0px;\\\" >\";\n            vModal += \"   </div>\";\n            vModal += \"  </div>\";\n            vModal += \"  </div>\";\n            vModal += \" </div>\";\n            vModal += \"</div>\";\n\n            $(\"body\").append($(vModal));\n\n            var vFormAvd = createFormAvd(pColumns, searchText, that),\n                timeoutId = 0;;\n\n            $('#avdSearchModalContent').append(vFormAvd.join(''));\n\n            $('#' + that.options.idForm).off('keyup blur', 'input').on('keyup blur', 'input', function (event) {\n                clearTimeout(timeoutId);\n                timeoutId = setTimeout(function () {\n                    that.onColumnAdvancedSearch(event);\n                }, that.options.searchTimeOut);\n            });\n\n            $(\"#btnCloseAvd\").click(function() {\n                $(\"#avdSearchModal\").modal('hide');\n            });\n\n            $(\"#avdSearchModal\").modal();\n        } else {\n            $(\"#avdSearchModal\").modal();\n        }\n    };\n\n    var createFormAvd = function(pColumns, searchText, that) {\n        var htmlForm = [];\n        htmlForm.push(sprintf('<form class=\"form-horizontal\" id=\"%s\" action=\"%s\" >', that.options.idForm, that.options.actionForm));\n        for (var i in pColumns) {\n            var vObjCol = pColumns[i];\n            if (!vObjCol.checkbox && vObjCol.visible && vObjCol.searchable) {\n                htmlForm.push('<div class=\"form-group\">');\n                htmlForm.push(sprintf('<label class=\"col-sm-4 control-label\">%s</label>', vObjCol.title));\n                htmlForm.push('<div class=\"col-sm-6\">');\n                htmlForm.push(sprintf('<input type=\"text\" class=\"form-control input-md\" name=\"%s\" placeholder=\"%s\" id=\"%s\">', vObjCol.field, vObjCol.title, vObjCol.field));\n                htmlForm.push('</div>');\n                htmlForm.push('</div>');\n            }\n        }\n\n        htmlForm.push('<div class=\"form-group\">');\n        htmlForm.push('<div class=\"col-sm-offset-9 col-sm-3\">');\n        htmlForm.push(sprintf('<button type=\"button\" id=\"btnCloseAvd\" class=\"btn btn-default\" >%s</button>', searchText));\n        htmlForm.push('</div>');\n        htmlForm.push('</div>');\n        htmlForm.push('</form>');\n\n        return htmlForm;\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        advancedSearch: false,\n        idForm: 'advancedSearch',\n        actionForm: '',\n        idTable: undefined,\n        onColumnAdvancedSearch: function (field, text) {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.defaults.icons, {\n        advancedSearchIcon: 'glyphicon-chevron-down'\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'column-advanced-search.bs.table': 'onColumnAdvancedSearch'\n    });\n\n    $.extend($.fn.bootstrapTable.locales, {\n        formatAdvancedSearch: function() {\n            return 'Advanced search';\n        },\n        formatAdvancedCloseButton: function() {\n            return \"Close\";\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initToolbar = BootstrapTable.prototype.initToolbar,        \n        _load = BootstrapTable.prototype.load,\n        _initSearch = BootstrapTable.prototype.initSearch;\n\n    BootstrapTable.prototype.initToolbar = function() {\n        _initToolbar.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.search) {\n            return;\n        }\n\n        if (!this.options.advancedSearch) {\n            return;\n        }\n\n        var that = this,\n            html = [];\n\n        html.push(sprintf('<div class=\"columns columns-%s btn-group pull-%s\" role=\"group\">', this.options.buttonsAlign, this.options.buttonsAlign));\n        html.push(sprintf('<button class=\"btn btn-default%s' + '\" type=\"button\" name=\"advancedSearch\" title=\"%s\">', that.options.iconSize === undefined ? '' : ' btn-' + that.options.iconSize, that.options.formatAdvancedSearch()));\n        html.push(sprintf('<i class=\"%s %s\"></i>', that.options.iconsPrefix, that.options.icons.advancedSearchIcon))\n        html.push('</button></div>');\n\n        that.$toolbar.prepend(html.join(''));\n\n        that.$toolbar.find('button[name=\"advancedSearch\"]')\n            .off('click').on('click', function() {\n                showAvdSearch(that.options.columns, that.options.formatAdvancedSearch(), that.options.formatAdvancedCloseButton(), that);\n            });\n    };\n\n    BootstrapTable.prototype.load = function(data) {\n        _load.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (typeof this.options.idTable === 'undefined') {\n            return;\n        } else {\n            if (!firstLoad) {\n                var height = parseInt($(\".bootstrap-table\").height());\n                height += 10;\n                $(\"#\" + this.options.idTable).bootstrapTable(\"resetView\", {height: height});\n                firstLoad = true;\n            }\n        }\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        _initSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        var that = this;\n        var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial;\n\n        this.data = fp ? $.grep(this.data, function (item, i) {\n            for (var key in fp) {\n                var fval = fp[key].toLowerCase();\n                var value = item[key];\n                value = calculateObjectValue(that.header,\n                    that.header.formatters[$.inArray(key, that.header.fields)],\n                    [value, item, i], value);\n\n                if (!($.inArray(key, that.header.fields) !== -1 &&\n                    (typeof value === 'string' || typeof value === 'number') &&\n                    (value + '').toLowerCase().indexOf(fval) !== -1)) {\n                    return false;\n                }\n            }\n            return true;\n        }) : this.data;\n    };\n\n    BootstrapTable.prototype.onColumnAdvancedSearch = function (event) {\n        var text = $.trim($(event.currentTarget).val());\n        var $field = $(event.currentTarget)[0].id;\n\n        if ($.isEmptyObject(this.filterColumnsPartial)) {\n            this.filterColumnsPartial = {};\n        }\n        if (text) {\n            this.filterColumnsPartial[$field] = text;\n        } else {\n            delete this.filterColumnsPartial[$field];\n        }\n\n        this.options.pageNumber = 1;\n        this.onSearch(event);\n        this.updatePagination();\n        this.trigger('column-advanced-search', $field, text);\n    };\n}(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-ar-SA.js",
    "content": "/**\n * Bootstrap Table English translation\n * Author: Zhixin Wen<wenzhixin2010@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ar-SA'] = {\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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ar-SA']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-cs-CZ.js",
    "content": "/**\n * Bootstrap Table Czech translation\n * Author: Lukas Kral (monarcha@seznam.cz)\n * Author: Jakub Svestka <svestka1999@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['cs-CZ'] = {\n        formatLoadingMessage: function () {\n            return 'Čekejte, prosím...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' položek na stránku';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Zobrazena ' + pageFrom + '. - ' + pageTo + '. položka z celkových ' + totalRows;\n        },\n        formatSearch: function () {\n            return 'Vyhledávání';\n        },\n        formatNoMatches: function () {\n            return 'Nenalezena žádná vyhovující položka';\n        },\n        formatPaginationSwitch: function () {\n            return 'Skrýt/Zobrazit stránkování';\n        },\n        formatRefresh: function () {\n            return 'Aktualizovat';\n        },\n        formatToggle: function () {\n            return 'Přepni';\n        },\n        formatColumns: function () {\n            return 'Sloupce';\n        },\n        formatAllRows: function () {\n            return 'Vše';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['cs-CZ']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-da-DK.js",
    "content": "/**\n * Bootstrap Table danish translation\n * Author: Your Name Jan Borup Coyle, github@coyle.dk\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['da-DK'] = {\n        formatLoadingMessage: function () {\n            return 'Indlæser, vent venligst...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' poster pr side';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Viser ' + pageFrom + ' til ' + pageTo + ' af ' + totalRows + ' rækker';\n        },\n        formatSearch: function () {\n            return 'Søg';\n        },\n        formatNoMatches: function () {\n            return 'Ingen poster fundet';\n        },\n        formatRefresh: function () {\n            return 'Opdater';\n        },\n        formatToggle: function () {\n            return 'Skift';\n        },\n        formatColumns: function () {\n            return 'Kolonner';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['da-DK']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-de-DE.js",
    "content": "/**\n* Bootstrap Table German translation\n* Author: Paul Mohr - Sopamo<p.mohr@sopamo.de>\n*/\n(function ($) {\n  'use strict';\n\n  $.fn.bootstrapTable.locales['de-DE'] = {\n    formatLoadingMessage: function () {\n      return 'Lade, bitte warten...';\n    },\n    formatRecordsPerPage: function (pageNumber) {\n      return pageNumber + ' Einträge pro Seite';\n    },\n    formatShowingRows: function (pageFrom, pageTo, totalRows) {\n      return 'Zeige ' + pageFrom + ' bis ' + pageTo + ' von ' + totalRows + ' Zeile' + ((totalRows > 1) ? \"n\" : \"\");\n    },\n    formatSearch: function () {\n      return 'Suchen';\n    },\n    formatNoMatches: function () {\n      return 'Keine passenden Ergebnisse gefunden';\n    },\n    formatRefresh: function () {\n      return 'Neu laden';\n    },\n    formatToggle: function () {\n      return 'Umschalten';\n    },\n    formatColumns: function () {\n      return 'Spalten';\n    }\n  };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['de-DE']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-el-GR.js",
    "content": "/**\n * Bootstrap Table Greek translation\n * Author: giannisdallas\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['el-GR'] = {\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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['el-GR']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-en-US.js",
    "content": "/**\n * Bootstrap Table English translation\n * Author: Zhixin Wen<wenzhixin2010@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['en-US'] = {\n        formatLoadingMessage: function () {\n            return 'Loading, please wait...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' records per page';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Showing ' + pageFrom + ' to ' + pageTo + ' of ' + totalRows + ' rows';\n        },\n        formatSearch: function () {\n            return 'Search';\n        },\n        formatNoMatches: function () {\n            return 'No matching records found';\n        },\n        formatPaginationSwitch: function () {\n            return 'Hide/Show pagination';\n        },\n        formatRefresh: function () {\n            return 'Refresh';\n        },\n        formatToggle: function () {\n            return 'Toggle';\n        },\n        formatColumns: function () {\n            return 'Columns';\n        },\n        formatAllRows: function () {\n            return 'All';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['en-US']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-es-AR.js",
    "content": "/**\n * Bootstrap Table Spanish (Argentina) translation\n * Author: Felix Vera (felix.vera@gmail.com)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['es-AR'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, espere por favor...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Mostrando ' + pageFrom + ' a ' + pageTo + ' de ' + totalRows + ' filas';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se encontraron registros';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-AR']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-es-CR.js",
    "content": "/**\n * Bootstrap Table Spanish (Costa Rica) translation\n * Author: Dennis Hernández (http://djhvscf.github.io/Blog/)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['es-CR'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, por favor espere...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Mostrando de ' + pageFrom + ' a ' + pageTo + ' registros de ' + totalRows + ' registros en total';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se encontraron registros';\n        },\n        formatRefresh: function () {\n            return 'Refrescar';\n        },\n        formatToggle: function () {\n            return 'Alternar';\n        },\n        formatColumns: function () {\n            return 'Columnas';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-CR']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-es-MX.js",
    "content": "/**\n * Bootstrap Table Spanish (México) translation (Obtenido de traducción de Argentina)\n * Author: Felix Vera (felix.vera@gmail.com) \n * Copiado: Mauricio Vera (mauricioa.vera@gmail.com)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['es-MX'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, espere por favor...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Mostrando ' + pageFrom + ' a ' + pageTo + ' de ' + totalRows + ' filas';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se encontraron registros';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-MX']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-es-NI.js",
    "content": "/**\n * Bootstrap Table Spanish (Nicaragua) translation\n * Author: Dennis Hernández (http://djhvscf.github.io/Blog/)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['es-NI'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, por favor espere...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Mostrando de ' + pageFrom + ' a ' + pageTo + ' registros de ' + totalRows + ' registros en total';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se encontraron registros';\n        },\n        formatRefresh: function () {\n            return 'Refrescar';\n        },\n        formatToggle: function () {\n            return 'Alternar';\n        },\n        formatColumns: function () {\n            return 'Columnas';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-NI']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-es-SP.js",
    "content": "/**\n * Bootstrap Table Spanish (España) translation\n * Author: Antonio Pérez <anpegar@gmail.com>\n */\n (function ($) {\n    'use strict';\n    \n    $.fn.bootstrapTable.locales['es-SP'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, por favor espera...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por p&#225;gina.';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return pageFrom + ' - ' + pageTo + ' de ' + totalRows + ' registros.';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se han encontrado registros.';\n        },\n        formatRefresh: function () {\n            return 'Actualizar';\n        },\n        formatToggle: function () {\n            return 'Alternar';\n        },\n        formatColumns: function () {\n            return 'Columnas';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-SP']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-fr-BE.js",
    "content": "/**\n * Bootstrap Table French (Belgium) translation\n * Author: Julien Bisconti (julien.bisconti@gmail.com)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['fr-BE'] = {\n        formatLoadingMessage: function () {\n            return 'Chargement en cours...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' entrées par page';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Affiche de' + pageFrom + ' à ' + pageTo + ' sur ' + totalRows + ' lignes';\n        },\n        formatSearch: function () {\n            return 'Recherche';\n        },\n        formatNoMatches: function () {\n            return 'Pas de fichiers trouvés';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['fr-BE']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-fr-FR.js",
    "content": "/**\n * Bootstrap Table French (France) translation\n * Author: Dennis Hernández (http://djhvscf.github.io/Blog/)\n * Modification: Tidalf (https://github.com/TidalfFR)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['fr-FR'] = {\n        formatLoadingMessage: function () {\n            return 'Chargement en cours, patientez, s´il vous plaît ...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' lignes par page';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Affichage des lignes ' + pageFrom + ' à ' + pageTo + ' sur ' + totalRows + ' lignes au total';\n        },\n        formatSearch: function () {\n            return 'Rechercher';\n        },\n        formatNoMatches: function () {\n            return 'Aucun résultat trouvé';\n        },\n        formatRefresh: function () {\n            return 'Rafraîchir';\n        },\n        formatToggle: function () {\n            return 'Alterner';\n        },\n        formatColumns: function () {\n            return 'Colonnes';\n        },\n        formatAllRows: function () {\n            return 'Tous';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['fr-FR']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-hu-HU.js",
    "content": "/**\n * Bootstrap Table Hungarian translation\n * Author: Nagy Gergely <info@nagygergely.eu>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['hu-HU'] = {\n        formatLoadingMessage: function () {\n            return 'Betöltés, kérem várjon...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' rekord per oldal';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Megjelenítve ' + pageFrom + ' - ' + pageTo + ' / ' + totalRows + ' összesen';\n        },\n        formatSearch: function () {\n            return 'Keresés';\n        },\n        formatNoMatches: function () {\n            return 'Nincs találat';\n        },\n        formatRefresh: function () {\n            return 'Frissítés';\n        },\n        formatToggle: function () {\n            return 'Váltás';\n        },\n        formatColumns: function () {\n            return 'Oszlopok';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['hu-HU']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-it-IT.js",
    "content": "/**\n * Bootstrap Table Italian translation\n * Author: Davide Renzi<davide.renzi@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['it-IT'] = {\n        formatLoadingMessage: function () {\n            return 'Caricamento in corso...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' records per pagina';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Pagina ' + pageFrom + ' di ' + pageTo + ' (' + totalRows + ' records)';\n        },\n        formatSearch: function () {\n            return 'Cerca';\n        },\n        formatNoMatches: function () {\n            return 'Nessun record trovato';\n        },\n        formatRefresh: function () {\n            return 'Rinfrescare';\n        },\n        formatToggle: function () {\n            return 'Alternare';\n        },\n        formatColumns: function () {\n            return 'Colonne';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['it-IT']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-ja-JP.js",
    "content": "/**\n * Bootstrap Table Japanese translation\n * Author: Azamshul Azizy <azamshul@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ja-JP'] = {\n        formatLoadingMessage: function () {\n            return '読み込み中です。少々お待ちください。';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return 'ページ当たり最大' + pageNumber + '件';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return '全' + totalRows + '件から、'+ pageFrom + 'から' + pageTo + '件目まで表示しています';\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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ja-JP']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-ka-GE.js",
    "content": "/**\n * Bootstrap Table Georgian translation\n * Author: Levan Lotuashvili <l.lotuashvili@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ka-GE'] = {\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    };\n    \n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ka-GE']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-ko-KR.js",
    "content": "/**\n * Bootstrap Table Korean translation\n * Author: Yi Tae-Hyeong (jsonobject@gmail.com)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ko-KR'] = {\n        formatLoadingMessage: function () {\n            return '데이터를 불러오는 중입니다...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return '페이지 당 ' + pageNumber + '개 데이터 출력';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return '전체 ' + totalRows + '개 중 ' + pageFrom + '~' + pageTo + '번째 데이터 출력,';\n        },\n        formatSearch: function () {\n            return '검색';\n        },\n        formatNoMatches: function () {\n            return '조회된 데이터가 없습니다.';\n        },\n        formatRefresh: function () {\n            return '새로 고침';\n        },\n        formatToggle: function () {\n            return '전환';\n        },\n        formatColumns: function () {\n            return '컬럼 필터링';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ko-KR']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-ms-MY.js",
    "content": "/**\n * Bootstrap Table Malay translation\n * Author: Azamshul Azizy <azamshul@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ms-MY'] = {\n        formatLoadingMessage: function () {\n            return 'Permintaan sedang dimuatkan. Sila tunggu sebentar...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' rekod setiap muka surat';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Sedang memaparkan rekod ' + pageFrom + ' hingga ' + pageTo + ' daripada jumlah ' + totalRows + ' rekod';\n        },\n        formatSearch: function () {\n            return 'Cari';\n        },\n        formatNoMatches: function () {\n            return 'Tiada rekod yang menyamai permintaan';\n        },\n        formatPaginationSwitch: function () {\n            return 'Tunjuk/sembunyi muka surat';\n        },\n        formatRefresh: function () {\n            return 'Muatsemula';\n        },\n        formatToggle: function () {\n            return 'Tukar';\n        },\n        formatColumns: function () {\n            return 'Lajur';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ms-MY']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-nb-NO.js",
    "content": "/**\n * Bootstrap Table norwegian translation\n * Author: Jim Nordbø, jim@nordb.no\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['nb-NO'] = {\n        formatLoadingMessage: function () {\n            return 'Oppdaterer, vennligst vent...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' poster pr side';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Viser ' + pageFrom + ' til ' + pageTo + ' av ' + totalRows + ' rekker';\n        },\n        formatSearch: function () {\n            return 'Søk';\n        },\n        formatNoMatches: function () {\n            return 'Ingen poster funnet';\n        },\n        formatRefresh: function () {\n            return 'Oppdater';\n        },\n        formatToggle: function () {\n            return 'Endre';\n        },\n        formatColumns: function () {\n            return 'Kolonner';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['nb-NO']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-nl-NL.js",
    "content": "/**\n * Bootstrap Table Dutch translation\n * Author: Your Name <info@a2hankes.nl>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['nl-NL'] = {\n        formatLoadingMessage: function () {\n            return 'Laden, even geduld...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' records per pagina';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Toon ' + pageFrom + ' tot ' + pageTo + ' van ' + totalRows + ' records';\n        },\n        formatSearch: function () {\n            return 'Zoeken';\n        },\n        formatNoMatches: function () {\n            return 'Geen resultaten gevonden';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['nl-NL']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-pl-PL.js",
    "content": "/**\n * Bootstrap Table Polish translation\n * Author: zergu <michal.zagdan @ gmail com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['pl-PL'] = {\n        formatLoadingMessage: function () {\n            return 'Ładowanie, proszę czekać...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' rekordów na stronę';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Wyświetlanie rekordów od ' + pageFrom + ' do ' + pageTo + ' z ' + totalRows;\n        },\n        formatSearch: function () {\n            return 'Szukaj';\n        },\n        formatNoMatches: function () {\n            return 'Niestety, nic nie znaleziono';\n        },\n        formatRefresh: function () {\n            return 'Odśwież';\n        },\n        formatToggle: function () {\n            return 'Przełącz';\n        },\n        formatColumns: function () {\n            return 'Kolumny';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pl-PL']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-pt-BR.js",
    "content": "/**\n * Bootstrap Table Brazilian Portuguese Translation\n * Author: Eduardo Cerqueira<egcerqueira@gmail.com>\n * Update: João Mello<jmello@hotmail.com.br>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['pt-BR'] = {\n        formatLoadingMessage: function () {\n            return 'Carregando, aguarde...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Exibindo ' + pageFrom + ' até ' + pageTo + ' de ' + totalRows + ' linhas';\n        },\n        formatSearch: function () { \n            return 'Pesquisar';\n        },\n        formatRefresh: function () { \n            return 'Recarregar';\n        },\n        formatToggle: function () { \n            return 'Alternar';\n        },\n        formatColumns: function () { \n            return 'Colunas';\n        },\n        formatPaginationSwitch: function () { \n            return 'Ocultar/Exibir paginação';\n        },\n        formatNoMatches: function () {\n            return 'Nenhum registro encontrado';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pt-BR']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-pt-PT.js",
    "content": "/**\n * Bootstrap Table Portuguese Portugal Translation\n * Author: Burnspirit<burnspirit@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['pt-PT'] = {\n        formatLoadingMessage: function () {\n            return 'A carregar, aguarde...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registos por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'A mostrar ' + pageFrom + ' até ' + pageTo + ' de ' + totalRows + ' linhas';\n        },\n        formatSearch: function () {\n            return 'Pesquisa';\n        },\n        formatNoMatches: function () {\n            return 'Nenhum registo encontrado';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pt-PT']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-ro-RO.js",
    "content": "/**\n * Bootstrap Table Romanian translation\n * Author: cristake <cristianiosif@me.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ro-RO'] = {\n        formatLoadingMessage: function () {\n            return 'Se incarca, va rugam asteptati...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' inregistrari pe pagina';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Arata de la ' + pageFrom + ' pana la ' + pageTo + ' din ' + totalRows + ' randuri';\n        },\n        formatSearch: function () {\n            return 'Cauta';\n        },\n        formatNoMatches: function () {\n            return 'Nu au fost gasite inregistrari';\n        },\n        formatPaginationSwitch: function () {\n            return 'Ascunde/Arata paginatia';\n        },\n        formatRefresh: function () {\n            return 'Reincarca';\n        },\n        formatToggle: function () {\n            return 'Comuta';\n        },\n        formatColumns: function () {\n            return 'Coloane';\n        },\n        formatAllRows: function () {\n            return 'Toate';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ro-RO']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-ru-RU.js",
    "content": "/**\n * Bootstrap Table Russian translation\n * Author: Dunaevsky Maxim <dunmaksim@yandex.ru>\n */\n(function ($) {\n    'use strict';\n    $.fn.bootstrapTable.locales['ru-RU'] = {\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        formatRefresh: function () {\n            return 'Обновить';\n        },\n        formatToggle: function () {\n            return 'Переключить';\n        },\n        formatColumns: function () {\n            return 'Колонки';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ru-RU']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-sk-SK.js",
    "content": "/**\n * Bootstrap Table Slovak translation\n * Author: Jozef Dúc<jozef.d13@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['sk-SK'] = {\n        formatLoadingMessage: function () {\n            return 'Prosím čakajte ...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' záznamov na stranu';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Zobrazená ' + pageFrom + '. - ' + pageTo + '. položka z celkových ' + totalRows;\n        },\n        formatSearch: function () {\n            return 'Vyhľadávanie';\n        },\n        formatNoMatches: function () {\n            return 'Nenájdená žiadne vyhovujúca položka';\n        },\n        formatRefresh: function () {\n            return 'Obnoviť';\n        },\n        formatToggle: function () {\n            return 'Prepni';\n        },\n        formatColumns: function () {\n            return 'Stĺpce';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['sk-SK']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-sv-SE.js",
    "content": "/**\n * Bootstrap Table Swedish translation\n * Author: C Bratt <bratt@inix.se>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['sv-SE'] = {\n        formatLoadingMessage: function () {\n            return 'Laddar, vänligen vänta...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' rader per sida';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Visa ' + pageFrom + ' till ' + pageTo + ' av ' + totalRows + ' rader';\n        },\n        formatSearch: function () {\n            return 'Sök';\n        },\n        formatNoMatches: function () {\n            return 'Inga matchande resultat funna.';\n        },\n        formatRefresh: function () {\n            return 'Uppdatera';\n        },\n        formatToggle: function () {\n            return 'Skifta';\n        },\n        formatColumns: function () {\n            return 'kolumn';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['sv-SE']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-th-TH.js",
    "content": "/**\n * Bootstrap Table Thai translation\n * Author: Monchai S.<monchais@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['th-TH'] = {\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        formatRefresh: function () {\n            return 'รีเฟรส';\n        },\n        formatToggle: function () {\n            return 'สลับมุมมอง';\n        },\n        formatColumns: function () {\n            return 'คอลัมน์';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['th-TH']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-tr-TR.js",
    "content": "/**\n * Bootstrap Table Turkish translation\n * Author: Emin Şen\n * Author: Sercan Cakir <srcnckr@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['tr-TR'] = {\n        formatLoadingMessage: function () {\n            return 'Yükleniyor, lütfen bekleyin...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return 'Sayfa başına ' + pageNumber + ' kayıt.';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return totalRows + ' kayıttan ' + pageFrom + '-' + pageTo + ' arası gösteriliyor.';\n        },\n        formatSearch: function () {\n            return 'Ara';\n        },\n        formatNoMatches: function () {\n            return 'Eşleşen kayıt bulunamadı.';\n        },\n        formatRefresh: function () {\n            return 'Yenile';\n        },\n        formatToggle: function () {\n            return 'Değiştir';\n        },\n        formatColumns: function () {\n            return 'Sütunlar';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['tr-TR']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-uk-UA.js",
    "content": "/**\n * Bootstrap Table Ukrainian translation\n * Author: Vitaliy Timchenko <vitaliy.timchenko@gmail.com>\n */\n (function ($) {\n    'use strict';\n    \n    $.fn.bootstrapTable.locales['uk-UA'] = {\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        formatRefresh: function () {\n            return 'Оновити';\n        },\n        formatToggle: function () {\n            return 'Змінити';\n        },\n        formatColumns: function () {\n            return 'Стовпці';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['uk-UA']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-ur-PK.js",
    "content": "/**\n * Bootstrap Table Urdu translation\n * Author: Malik <me@malikrizwan.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ur-PK'] = {\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        formatRefresh: function () {\n            return 'تازہ کریں';\n        },\n        formatToggle: function () {\n            return 'تبدیل کریں';\n        },\n        formatColumns: function () {\n            return 'کالم';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ur-PK']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-vi-VN.js",
    "content": "/**\n * Bootstrap Table Vietnamese translation\n * Author: Duc N. PHAM <pngduc@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['vi-VN'] = {\n        formatLoadingMessage: function () {\n            return 'Đang tải...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' bản ghi mỗi trang';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Hiển thị từ trang ' + pageFrom + ' đến ' + pageTo + ' của ' + totalRows + ' bảng ghi';\n        },\n        formatSearch: function () {\n            return 'Tìm kiếm';\n        },\n        formatNoMatches: function () {\n            return 'Không có dữ liệu';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['vi-VN']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-CN']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/dist/locale/bootstrap-table-zh-TW.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-TW'] = {\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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-TW']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/bootstrap-table.css",
    "content": "/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * version: 1.8.1\n * https://github.com/wenzhixin/bootstrap-table/\n */\n\n.bootstrap-table .table {\n    margin-bottom: 0 !important;\n    border-bottom: 1px solid #dddddd;\n    border-collapse: collapse !important;\n    border-radius: 1px;\n}\n\n.bootstrap-table .table,\n.bootstrap-table .table > tbody > tr > th,\n.bootstrap-table .table > tfoot > tr > th,\n.bootstrap-table .table > thead > tr > td,\n.bootstrap-table .table > tbody > tr > td,\n.bootstrap-table .table > tfoot > tr > td {\n    padding: 8px !important;\n}\n\n.bootstrap-table .table.table-no-bordered > thead > tr > th,\n.bootstrap-table .table.table-no-bordered > tbody > tr > td {\n    border-right: 2px solid transparent;\n}\n\n.fixed-table-container {\n    position: relative;\n    clear: both;\n    border: 1px solid #dddddd;\n    border-radius: 4px;\n    -webkit-border-radius: 4px;\n    -moz-border-radius: 4px;\n}\n\n.fixed-table-container.table-no-bordered {\n    border: 1px solid transparent;\n}\n\n.fixed-table-footer,\n.fixed-table-header {\n    height: 37px; /*cellHeight*/\n    overflow: hidden;\n    border-radius: 4px 4px 0 0;\n    -webkit-border-radius: 4px 4px 0 0;\n    -moz-border-radius: 4px 4px 0 0;\n}\n\n.fixed-table-header {\n    border-bottom: 1px solid #dddddd;\n}\n\n.fixed-table-footer {\n    border-top: 1px solid #dddddd;\n}\n\n.fixed-table-body {\n    overflow-x: auto;\n    overflow-y: auto;\n    height: 100%;\n}\n\n.fixed-table-container table {\n    width: 100%;\n}\n\n.fixed-table-container thead th {\n    height: 0;\n    padding: 0;\n    margin: 0;\n    border-left: 1px solid #dddddd;\n}\n\n.fixed-table-container thead th:first-child {\n    border-left: none;\n    border-top-left-radius: 4px;\n    -webkit-border-top-left-radius: 4px;\n    -moz-border-radius-topleft: 4px;\n}\n\n.fixed-table-container thead th .th-inner {\n    padding: 8px;\n    line-height: 24px;\n    vertical-align: top;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n}\n\n.fixed-table-container thead th .sortable {\n    cursor: pointer;\n    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC');\n    background-position: right;\n    background-repeat: no-repeat;\n    padding-right: 30px;\n}\n\n.fixed-table-container th.detail {\n    width: 30px;\n}\n\n.fixed-table-container tbody td {\n    border-left: 1px solid #dddddd;\n}\n\n.fixed-table-container tbody tr:first-child td {\n    border-top: none;\n}\n\n.fixed-table-container tbody td:first-child {\n    border-left: none;\n}\n\n/* the same color with .active */\n.fixed-table-container tbody .selected td {\n    background-color: #f5f5f5;\n}\n\n.fixed-table-container .bs-checkbox {\n    text-align: center;\n}\n\n.fixed-table-container .bs-checkbox .th-inner {\n    padding: 8px 0;\n}\n\n.fixed-table-container input[type=\"radio\"],\n.fixed-table-container input[type=\"checkbox\"] {\n    margin: 0 auto !important;\n}\n\n.fixed-table-container .no-records-found {\n    text-align: center;\n}\n\n.fixed-table-pagination div.pagination,\n.fixed-table-pagination .pagination-detail {\n    margin-top: 10px;\n    margin-bottom: 10px;\n}\n\n.fixed-table-pagination div.pagination .pagination {\n    margin: 0;\n}\n\n.fixed-table-pagination .pagination a {\n    padding: 6px 12px;\n    line-height: 1.428571429;\n}\n\n.fixed-table-pagination .pagination-info {\n    line-height: 34px;\n    margin-right: 5px;\n}\n\n.fixed-table-pagination .btn-group {\n    position: relative;\n    display: inline-block;\n    vertical-align: middle;\n}\n\n.fixed-table-pagination .dropup .dropdown-menu {\n    margin-bottom: 0;\n}\n\n.fixed-table-pagination .page-list {\n    display: inline-block;\n}\n\n.fixed-table-toolbar .columns-left {\n    margin-right: 5px;\n}\n\n.fixed-table-toolbar .columns-right {\n    margin-left: 5px;\n}\n\n.fixed-table-toolbar .columns label {\n    display: block;\n    padding: 3px 20px;\n    clear: both;\n    font-weight: normal;\n    line-height: 1.428571429;\n}\n\n.fixed-table-toolbar .bars,\n.fixed-table-toolbar .search,\n.fixed-table-toolbar .columns {\n    position: relative;\n    margin-top: 10px;\n    margin-bottom: 10px;\n    line-height: 34px;\n}\n\n.fixed-table-pagination li.disabled a {\n    pointer-events: none;\n    cursor: default;\n}\n\n.fixed-table-loading {\n    display: none;\n    position: absolute;\n    top: 42px;\n    right: 0;\n    bottom: 0;\n    left: 0;\n    z-index: 99;\n    background-color: #fff;\n    text-align: center;\n}\n\n.fixed-table-body .card-view .title {\n    font-weight: bold;\n    display: inline-block;\n    min-width: 30%;\n    text-align: left !important;\n}\n\n/* support bootstrap 2 */\n.fixed-table-body thead th .th-inner {\n    box-sizing: border-box;\n}\n\n.table th, .table td {\n    vertical-align: middle;\n    box-sizing: border-box;\n}\n\n.fixed-table-toolbar .dropdown-menu {\n    text-align: left;\n    max-height: 300px;\n    overflow: auto;\n}\n\n.fixed-table-toolbar .btn-group > .btn-group {\n    display: inline-block;\n    margin-left: -1px !important;\n}\n\n.fixed-table-toolbar .btn-group > .btn-group > .btn {\n    border-radius: 0;\n}\n\n.fixed-table-toolbar .btn-group > .btn-group:first-child > .btn {\n    border-top-left-radius: 4px;\n    border-bottom-left-radius: 4px;\n}\n\n.fixed-table-toolbar .btn-group > .btn-group:last-child > .btn {\n    border-top-right-radius: 4px;\n    border-bottom-right-radius: 4px;\n}\n\n.bootstrap-table .table > thead > tr > th {\n    vertical-align: bottom;\n    border-bottom: 2px solid #ddd;\n}\n\n/* support bootstrap 3 */\n.bootstrap-table .table thead > tr > th {\n    padding: 0;\n    margin: 0;\n}\n\n.pull-right .dropdown-menu {\n    right: 0;\n    left: auto;\n}\n\n/* calculate scrollbar width */\np.fixed-table-scroll-inner {\n    width: 100%;\n    height: 200px;\n}\n\ndiv.fixed-table-scroll-outer {\n    top: 0;\n    left: 0;\n    visibility: hidden;\n    width: 200px;\n    height: 150px;\n    overflow: hidden;\n}"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/bootstrap-table.js",
    "content": "/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * version: 1.8.1\n * https://github.com/wenzhixin/bootstrap-table/\n */\n\n!function ($) {\n    'use strict';\n\n    // TOOLS DEFINITION\n    // ======================\n\n    var cellHeight = 37, // update css if changed\n        cachedWidth = null,\n        arrowAsc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ' +\n        '0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBd' +\n        'qEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVo' +\n        'AADeemwtPcZI2wAAAABJRU5ErkJggg==',\n        arrowBoth = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X' +\n        'QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azio' +\n        'NZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4eut' +\n        's6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC',\n        arrowDesc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWj' +\n        'YBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJ' +\n        'zcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= ';\n\n    // it only does '%s', and return '' when arguments are undefined\n    var sprintf = function (str) {\n        var args = arguments,\n            flag = true,\n            i = 1;\n\n        str = str.replace(/%s/g, function () {\n            var arg = args[i++];\n\n            if (typeof arg === 'undefined') {\n                flag = false;\n                return '';\n            }\n            return arg;\n        });\n        return flag ? str : '';\n    };\n\n    var getPropertyFromOther = function (list, from, to, value) {\n        var result = '';\n        $.each(list, function (i, item) {\n            if (item[from] === value) {\n                result = item[to];\n                return false;\n            }\n            return true;\n        });\n        return result;\n    };\n\n    var getFieldIndex = function (columns, field) {\n        var index = -1;\n\n        $.each(columns, function (i, column) {\n            if (column.field === field) {\n                index = i;\n                return false;\n            }\n            return true;\n        });\n        return index;\n    };\n\n    var getScrollBarWidth = function () {\n        if (cachedWidth === null) {\n            var inner = $('<p/>').addClass('fixed-table-scroll-inner'),\n                outer = $('<div/>').addClass('fixed-table-scroll-outer'),\n                w1, w2;\n\n            outer.append(inner);\n            $('body').append(outer);\n\n            w1 = inner[0].offsetWidth;\n            outer.css('overflow', 'scroll');\n            w2 = inner[0].offsetWidth;\n\n            if (w1 === w2) {\n                w2 = outer[0].clientWidth;\n            }\n\n            outer.remove();\n            cachedWidth = w1 - w2;\n        }\n        return cachedWidth;\n    };\n\n    var calculateObjectValue = function (self, name, args, defaultValue) {\n        var func = name;\n\n        if (typeof name === 'string') {\n            // support obj.func1.func2\n            var names = name.split('.');\n\n            if (names.length > 1) {\n                func = window;\n                $.each(names, function (i, f) {\n                    func = func[f];\n                });\n            } else {\n                func = window[name];\n            }\n        }\n        if (typeof func === 'object') {\n            return func;\n        }\n        if (typeof func === 'function') {\n            return func.apply(self, args);\n        }\n        if (!func && typeof name === 'string' && sprintf.apply(this, [name].concat(args))) {\n            return sprintf.apply(this, [name].concat(args));\n        }\n        return defaultValue;\n    };\n\n    var escapeHTML = function (text) {\n        if (typeof text === 'string') {\n            return text\n                .replace(/&/g, \"&amp;\")\n                .replace(/</g, \"&lt;\")\n                .replace(/>/g, \"&gt;\")\n                .replace(/\"/g, \"&quot;\")\n                .replace(/'/g, \"&#039;\");\n        }\n        return text;\n    };\n\n    var getRealHeight = function ($el) {\n        var height = 0;\n        $el.children().each(function () {\n            if (height < $(this).outerHeight(true)) {\n                height = $(this).outerHeight(true);\n            }\n        });\n        return height;\n    };\n\n    var getRealDataAttr = function (dataAttr) {\n        for (var attr in dataAttr) {\n            var auxAttr = attr.split(/(?=[A-Z])/).join('-').toLowerCase();\n            if (auxAttr !== attr) {\n                dataAttr[auxAttr] = dataAttr[attr];\n                delete dataAttr[attr];\n            }\n        }\n\n        return dataAttr;\n    };\n\n    // BOOTSTRAP TABLE CLASS DEFINITION\n    // ======================\n\n    var BootstrapTable = function (el, options) {\n        this.options = options;\n        this.$el = $(el);\n        this.$el_ = this.$el.clone();\n        this.timeoutId_ = 0;\n        this.timeoutFooter_ = 0;\n\n        this.init();\n    };\n\n    BootstrapTable.DEFAULTS = {\n        classes: 'table table-hover',\n        height: undefined,\n        undefinedText: '-',\n        sortName: undefined,\n        sortOrder: 'asc',\n        striped: false,\n        columns: [],\n        data: [],\n        method: 'get',\n        url: undefined,\n        ajax: undefined,\n        cache: true,\n        contentType: 'application/json',\n        dataType: 'json',\n        ajaxOptions: {},\n        queryParams: function (params) {\n            return params;\n        },\n        queryParamsType: 'limit', // undefined\n        responseHandler: function (res) {\n            return res;\n        },\n        pagination: false,\n        sidePagination: 'client', // client or server\n        totalRows: 0, // server side need to set\n        pageNumber: 1,\n        pageSize: 10,\n        pageList: [10, 25, 50, 100],\n        paginationHAlign: 'right', //right, left\n        paginationVAlign: 'bottom', //bottom, top, both\n        paginationDetailHAlign: 'left', //right, left\n        paginationFirstText: '&laquo;',\n        paginationPreText: '&lsaquo;',\n        paginationNextText: '&rsaquo;',\n        paginationLastText: '&raquo;',\n        search: false,\n        searchAlign: 'right',\n        selectItemName: 'btSelectItem',\n        showHeader: true,\n        showFooter: false,\n        showColumns: false,\n        showPaginationSwitch: false,\n        showRefresh: false,\n        showToggle: false,\n        buttonsAlign: 'right',\n        smartDisplay: true,\n        minimumCountColumns: 1,\n        idField: undefined,\n        uniqueId: undefined,\n        cardView: false,\n        detailView: false,\n        detailFormatter: function (index, row) {\n            return '';\n        },\n        trimOnSearch: true,\n        clickToSelect: false,\n        singleSelect: false,\n        toolbar: undefined,\n        toolbarAlign: 'left',\n        checkboxHeader: true,\n        sortable: true,\n        maintainSelected: false,\n        searchTimeOut: 500,\n        searchText: '',\n        iconSize: undefined,\n        iconsPrefix: 'glyphicon', // glyphicon of fa (font awesome)\n        icons: {\n            paginationSwitchDown: 'glyphicon-collapse-down icon-chevron-down',\n            paginationSwitchUp: 'glyphicon-collapse-up icon-chevron-up',\n            refresh: 'glyphicon-refresh icon-refresh',\n            toggle: 'glyphicon-list-alt icon-list-alt',\n            columns: 'glyphicon-th icon-th'\n        },\n\n        rowStyle: function (row, index) {\n            return {};\n        },\n\n        rowAttributes: function (row, index) {\n            return {};\n        },\n\n        onAll: function (name, args) {\n            return false;\n        },\n        onClickCell: function (field, value, row, $element) {\n            return false;\n        },\n        onDblClickCell: function (field, value, row, $element) {\n            return false;\n        },\n        onClickRow: function (item, $element) {\n            return false;\n        },\n        onDblClickRow: function (item, $element) {\n            return false;\n        },\n        onSort: function (name, order) {\n            return false;\n        },\n        onCheck: function (row) {\n            return false;\n        },\n        onUncheck: function (row) {\n            return false;\n        },\n        onCheckAll: function (rows) {\n            return false;\n        },\n        onUncheckAll: function (rows) {\n            return false;\n        },\n        onCheckSome: function(rows){\n            return false;\n        },\n        onUncheckSome: function(rows){\n            return false;\n        },\n        onLoadSuccess: function (data) {\n            return false;\n        },\n        onLoadError: function (status) {\n            return false;\n        },\n        onColumnSwitch: function (field, checked) {\n            return false;\n        },\n        onPageChange: function (number, size) {\n            return false;\n        },\n        onSearch: function (text) {\n            return false;\n        },\n        onToggle: function (cardView) {\n            return false;\n        },\n        onPreBody: function (data) {\n            return false;\n        },\n        onPostBody: function () {\n            return false;\n        },\n        onPostHeader: function () {\n            return false;\n        },\n        onExpandRow: function (index, row, $detail) {\n            return false;\n        },\n        onCollapseRow: function (index, row) {\n            return false;\n        }\n    };\n\n    BootstrapTable.LOCALES = [];\n\n    BootstrapTable.LOCALES['en-US'] = {\n        formatLoadingMessage: function () {\n            return 'Loading, please wait...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return sprintf('%s records per page', pageNumber);\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return sprintf('Showing %s to %s of %s rows', pageFrom, pageTo, totalRows);\n        },\n        formatSearch: function () {\n            return 'Search';\n        },\n        formatNoMatches: function () {\n            return 'No matching records found';\n        },\n        formatPaginationSwitch: function () {\n            return 'Hide/Show pagination';\n        },\n        formatRefresh: function () {\n            return 'Refresh';\n        },\n        formatToggle: function () {\n            return 'Toggle';\n        },\n        formatColumns: function () {\n            return 'Columns';\n        },\n        formatAllRows: function () {\n            return 'All';\n        }\n    };\n\n    $.extend(BootstrapTable.DEFAULTS, BootstrapTable.LOCALES['en-US']);\n\n    BootstrapTable.COLUMN_DEFAULTS = {\n        radio: false,\n        checkbox: false,\n        checkboxEnabled: true,\n        field: undefined,\n        title: undefined,\n        'class': undefined,\n        align: undefined, // left, right, center\n        halign: undefined, // left, right, center\n        falign: undefined, // left, right, center\n        valign: undefined, // top, middle, bottom\n        width: undefined,\n        sortable: false,\n        order: 'asc', // asc, desc\n        visible: true,\n        switchable: true,\n        clickToSelect: true,\n        formatter: undefined,\n        footerFormatter: undefined,\n        events: undefined,\n        sorter: undefined,\n        sortName: undefined,\n        cellStyle: undefined,\n        searchable: true,\n        cardVisible: true\n    };\n\n    BootstrapTable.EVENTS = {\n        'all.bs.table': 'onAll',\n        'click-cell.bs.table': 'onClickCell',\n        'dbl-click-cell.bs.table': 'onDblClickCell',\n        'click-row.bs.table': 'onClickRow',\n        'dbl-click-row.bs.table': 'onDblClickRow',\n        'sort.bs.table': 'onSort',\n        'check.bs.table': 'onCheck',\n        'uncheck.bs.table': 'onUncheck',\n        'check-all.bs.table': 'onCheckAll',\n        'uncheck-all.bs.table': 'onUncheckAll',\n        'check-some.bs.table': 'onCheckSome',\n        'uncheck-some.bs.table': 'onUncheckSome',\n        'load-success.bs.table': 'onLoadSuccess',\n        'load-error.bs.table': 'onLoadError',\n        'column-switch.bs.table': 'onColumnSwitch',\n        'page-change.bs.table': 'onPageChange',\n        'search.bs.table': 'onSearch',\n        'toggle.bs.table': 'onToggle',\n        'pre-body.bs.table': 'onPreBody',\n        'post-body.bs.table': 'onPostBody',\n        'post-header.bs.table': 'onPostHeader',\n        'expand-row.bs.table': 'onExpandRow',\n        'collapse-row.bs.table': 'onCollapseRow'\n    };\n\n    BootstrapTable.prototype.init = function () {\n        this.initContainer();\n        this.initTable();\n        this.initHeader();\n        this.initData();\n        this.initFooter();\n        this.initToolbar();\n        this.initPagination();\n        this.initBody();\n        this.initServer();\n    };\n\n    BootstrapTable.prototype.initContainer = function () {\n        this.$container = $([\n            '<div class=\"bootstrap-table\">',\n            '<div class=\"fixed-table-toolbar\"></div>',\n            this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ?\n                '<div class=\"fixed-table-pagination\" style=\"clear: both;\"></div>' :\n                '',\n            '<div class=\"fixed-table-container\">',\n            '<div class=\"fixed-table-header\"><table></table></div>',\n            '<div class=\"fixed-table-body\">',\n            '<div class=\"fixed-table-loading\">',\n            this.options.formatLoadingMessage(),\n            '</div>',\n            '</div>',\n            '<div class=\"fixed-table-footer\"><table><tr></tr></table></div>',\n            this.options.paginationVAlign === 'bottom' || this.options.paginationVAlign === 'both' ?\n                '<div class=\"fixed-table-pagination\"></div>' :\n                '',\n            '</div>',\n            '</div>'].join(''));\n\n        this.$container.insertAfter(this.$el);\n        this.$tableContainer = this.$container.find('.fixed-table-container');\n        this.$tableHeader = this.$container.find('.fixed-table-header');\n        this.$tableBody = this.$container.find('.fixed-table-body');\n        this.$tableLoading = this.$container.find('.fixed-table-loading');\n        this.$tableFooter = this.$container.find('.fixed-table-footer');\n        this.$toolbar = this.$container.find('.fixed-table-toolbar');\n        this.$pagination = this.$container.find('.fixed-table-pagination');\n\n        this.$tableBody.append(this.$el);\n        this.$container.after('<div class=\"clearfix\"></div>');\n\n        this.$el.addClass(this.options.classes);\n        if (this.options.striped) {\n            this.$el.addClass('table-striped');\n        }\n        if ($.inArray('table-no-bordered', this.options.classes.split(' ')) !== -1) {\n            this.$tableContainer.addClass('table-no-bordered');\n        }\n    };\n\n    BootstrapTable.prototype.initTable = function () {\n        var that = this,\n            columns = [],\n            data = [];\n\n        this.$header = this.$el.find('thead');\n        if (!this.$header.length) {\n            this.$header = $('<thead></thead>').appendTo(this.$el);\n        }\n        if (!this.$header.find('tr').length) {\n            this.$header.append('<tr></tr>');\n        }\n        this.$header.find('th').each(function () {\n            var column = $.extend({}, {\n                title: $(this).html(),\n                'class': $(this).attr('class')\n            }, $(this).data());\n\n            columns.push(column);\n        });\n        this.options.columns = $.extend(true, [], columns, this.options.columns);\n        $.each(this.options.columns, function (i, column) {\n            that.options.columns[i] = $.extend({}, BootstrapTable.COLUMN_DEFAULTS,\n                {field: i}, column); // when field is undefined, use index instead\n        });\n\n        // if options.data is setting, do not process tbody data\n        if (this.options.data.length) {\n            return;\n        }\n\n        this.$el.find('tbody tr').each(function () {\n            var row = {};\n\n            // save tr's id, class and data-* attributes\n            row._id = $(this).attr('id');\n            row._class = $(this).attr('class');\n            row._data = getRealDataAttr($(this).data());\n\n            $(this).find('td').each(function (i) {\n                var field = that.options.columns[i].field;\n\n                row[field] = $(this).html();\n                // save td's id, class and data-* attributes\n                row['_' + field + '_id'] = $(this).attr('id');\n                row['_' + field + '_class'] = $(this).attr('class');\n                row['_' + field + '_rowspan'] = $(this).attr('rowspan');\n                row['_' + field + '_data'] = getRealDataAttr($(this).data());\n            });\n            data.push(row);\n        });\n        this.options.data = data;\n    };\n\n    BootstrapTable.prototype.initHeader = function () {\n        var that = this,\n            visibleColumns = [],\n            html = [],\n            timeoutId = 0;\n\n        this.header = {\n            fields: [],\n            styles: [],\n            classes: [],\n            formatters: [],\n            events: [],\n            sorters: [],\n            sortNames: [],\n            cellStyles: [],\n            clickToSelects: [],\n            searchables: []\n        };\n\n        if (!this.options.cardView && this.options.detailView) {\n            html.push('<th class=\"detail\"><div class=\"fht-cell\"></div></th>');\n            visibleColumns.push({});\n        }\n\n        $.each(this.options.columns, function (i, column) {\n            var text = '',\n                halign = '', // header align style\n                align = '', // body align style\n                style = '',\n                class_ = sprintf(' class=\"%s\"', column['class']),\n                order = that.options.sortOrder || column.order,\n                unitWidth = 'px',\n                width = column.width;\n\n            if (!column.visible) {\n                // Fix #229. Default Sort order is wrong\n                // if data-visible=\"false\" is set on the field referenced by data-sort-name.\n                if (column.field === that.options.sortName) {\n                    that.header.fields.push(column.field);\n                }\n                return;\n            }\n\n            if (that.options.cardView && (!column.cardVisible)) {\n                return;\n            }\n\n            if (column.width !== undefined && (!that.options.cardView)) {\n                if (typeof column.width === 'string') {\n                    if (column.width.indexOf('%') !== -1) {\n                        unitWidth = '%';\n                    }\n                }\n            }\n            if (column.width && typeof column.width === 'string') {\n                width = column.width.replace('%', '').replace('px', '');\n            }\n\n            halign = sprintf('text-align: %s; ', column.halign ? column.halign : column.align);\n            align = sprintf('text-align: %s; ', column.align);\n            style = sprintf('vertical-align: %s; ', column.valign);\n            style += sprintf('width: %s%s; ', column.checkbox || column.radio ? 36 : width, unitWidth);\n\n            visibleColumns.push(column);\n            that.header.fields.push(column.field);\n            that.header.styles.push(align + style);\n            that.header.classes.push(class_);\n            that.header.formatters.push(column.formatter);\n            that.header.events.push(column.events);\n            that.header.sorters.push(column.sorter);\n            that.header.sortNames.push(column.sortName);\n            that.header.cellStyles.push(column.cellStyle);\n            that.header.clickToSelects.push(column.clickToSelect);\n            that.header.searchables.push(column.searchable);\n\n            html.push('<th',\n                column.checkbox || column.radio ?\n                    sprintf(' class=\"bs-checkbox %s\"', column['class'] || '') :\n                    class_,\n                sprintf(' style=\"%s\"', halign + style),\n                '>');\n\n            html.push(sprintf('<div class=\"th-inner %s\">', that.options.sortable && column.sortable ?\n                'sortable' : ''));\n\n            text = column.title;\n\n            if (column.checkbox) {\n                if (!that.options.singleSelect && that.options.checkboxHeader) {\n                    text = '<input name=\"btSelectAll\" type=\"checkbox\" />';\n                }\n                that.header.stateField = column.field;\n            }\n            if (column.radio) {\n                text = '';\n                that.header.stateField = column.field;\n                that.options.singleSelect = true;\n            }\n\n            html.push(text);\n            html.push('</div>');\n            html.push('<div class=\"fht-cell\"></div>');\n            html.push('</div>');\n            html.push('</th>');\n        });\n\n        this.$header.find('tr').html(html.join(''));\n        this.$header.find('th').each(function (i) {\n            $(this).data(visibleColumns[i]);\n        });\n        this.$container.off('click', '.th-inner').on('click', '.th-inner', function (event) {\n            if (that.options.sortable && $(this).parent().data().sortable) {\n                that.onSort(event);\n            }\n        });\n\n        if (!this.options.showHeader || this.options.cardView) {\n            this.$header.hide();\n            this.$tableHeader.hide();\n            this.$tableLoading.css('top', 0);\n        } else {\n            this.$header.show();\n            this.$tableHeader.show();\n            this.$tableLoading.css('top', cellHeight + 'px');\n            // Assign the correct sortable arrow\n            this.getCaretHtml();\n        }\n\n        this.$selectAll = this.$header.find('[name=\"btSelectAll\"]');\n        this.$container.off('click', '[name=\"btSelectAll\"]')\n            .on('click', '[name=\"btSelectAll\"]', function () {\n                var checked = $(this).prop('checked');\n                that[checked ? 'checkAll' : 'uncheckAll']();\n            });\n    };\n\n    BootstrapTable.prototype.initFooter = function () {\n        if (!this.options.showFooter || this.options.cardView) {\n            this.$tableFooter.hide();\n        } else {\n            this.$tableFooter.show();\n        }\n    };\n\n    /**\n     * @param data\n     * @param type: append / prepend\n     */\n    BootstrapTable.prototype.initData = function (data, type) {\n        if (type === 'append') {\n            this.data = this.data.concat(data);\n        } else if (type === 'prepend') {\n            this.data = [].concat(data).concat(this.data);\n        } else {\n            this.data = data || this.options.data;\n        }\n\n        // Fix #839 Records deleted when adding new row on filtered table\n        if (type === 'append') {\n            this.options.data = this.options.data.concat(data);\n        } else if (type === 'prepend') {\n            this.options.data = [].concat(data).concat(this.options.data);\n        } else {\n            this.options.data = this.data;\n        }\n\n        if (this.options.sidePagination === 'server') {\n            return;\n        }\n        this.initSort();\n    };\n\n    BootstrapTable.prototype.initSort = function () {\n        var that = this,\n            name = this.options.sortName,\n            order = this.options.sortOrder === 'desc' ? -1 : 1,\n            index = $.inArray(this.options.sortName, this.header.fields);\n\n        if (index !== -1) {\n            this.data.sort(function (a, b) {\n                if (that.header.sortNames[index]) {\n                    name = that.header.sortNames[index];\n                }\n                var aa = a[name],\n                    bb = b[name],\n                    value = calculateObjectValue(that.header, that.header.sorters[index], [aa, bb]);\n\n                if (value !== undefined) {\n                    return order * value;\n                }\n\n                // Fix #161: undefined or null string sort bug.\n                if (aa === undefined || aa === null) {\n                    aa = '';\n                }\n                if (bb === undefined || bb === null) {\n                    bb = '';\n                }\n\n                // IF both values are numeric, do a numeric comparison\n                if ($.isNumeric(aa) && $.isNumeric(bb)) {\n                    // Convert numerical values form string to float.\n                    aa = parseFloat(aa);\n                    bb = parseFloat(bb);\n                    if (aa < bb) {\n                        return order * -1;\n                    }\n                    return order;\n                }\n\n                if (aa === bb) {\n                    return 0;\n                }\n\n                // If value is not a string, convert to string\n                if (typeof aa !== 'string') {\n                    aa = aa.toString();\n                }\n\n                if (aa.localeCompare(bb) === -1) {\n                    return order * -1;\n                }\n\n                return order;\n            });\n        }\n    };\n\n    BootstrapTable.prototype.onSort = function (event) {\n        var $this = $(event.currentTarget).parent(),\n            $this_ = this.$header.find('th').eq($this.index());\n\n        this.$header.add(this.$header_).find('span.order').remove();\n\n        if (this.options.sortName === $this.data('field')) {\n            this.options.sortOrder = this.options.sortOrder === 'asc' ? 'desc' : 'asc';\n        } else {\n            this.options.sortName = $this.data('field');\n            this.options.sortOrder = $this.data('order') === 'asc' ? 'desc' : 'asc';\n        }\n        this.trigger('sort', this.options.sortName, this.options.sortOrder);\n\n        $this.add($this_).data('order', this.options.sortOrder);\n\n        // Assign the correct sortable arrow\n        this.getCaretHtml();\n\n        if (this.options.sidePagination === 'server') {\n            this.initServer();\n            return;\n        }\n\n        this.initSort();\n        this.initBody();\n    };\n\n    BootstrapTable.prototype.initToolbar = function () {\n        var that = this,\n            html = [],\n            timeoutId = 0,\n            $keepOpen,\n            $search,\n            switchableCount = 0;\n\n        this.$toolbar.html('');\n\n        if (typeof this.options.toolbar === 'string') {\n            $(sprintf('<div class=\"bars pull-%s\"></div>', this.options.toolbarAlign))\n                .appendTo(this.$toolbar)\n                .append($(this.options.toolbar));\n        }\n\n        // showColumns, showToggle, showRefresh\n        html = [sprintf('<div class=\"columns columns-%s btn-group pull-%s\">',\n            this.options.buttonsAlign, this.options.buttonsAlign)];\n\n        if (typeof this.options.icons === 'string') {\n            this.options.icons = calculateObjectValue(null, this.options.icons);\n        }\n\n        if (this.options.showPaginationSwitch) {\n            html.push(sprintf('<button class=\"btn btn-default\" type=\"button\" name=\"paginationSwitch\" title=\"%s\">',\n                this.options.formatPaginationSwitch()),\n                sprintf('<i class=\"%s %s\"></i>', this.options.iconsPrefix, this.options.icons.paginationSwitchDown),\n                '</button>');\n        }\n\n        if (this.options.showRefresh) {\n            html.push(sprintf('<button class=\"btn btn-default' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + '\" type=\"button\" name=\"refresh\" title=\"%s\">',\n                this.options.formatRefresh()),\n                sprintf('<i class=\"%s %s\"></i>', this.options.iconsPrefix, this.options.icons.refresh),\n                '</button>');\n        }\n\n        if (this.options.showToggle) {\n            html.push(sprintf('<button class=\"btn btn-default' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + '\" type=\"button\" name=\"toggle\" title=\"%s\">',\n                this.options.formatToggle()),\n                sprintf('<i class=\"%s %s\"></i>', this.options.iconsPrefix, this.options.icons.toggle),\n                '</button>');\n        }\n\n        if (this.options.showColumns) {\n            html.push(sprintf('<div class=\"keep-open btn-group\" title=\"%s\">',\n                this.options.formatColumns()),\n                '<button type=\"button\" class=\"btn btn-default' + (this.options.iconSize == undefined ? '' : ' btn-' + this.options.iconSize) + ' dropdown-toggle\" data-toggle=\"dropdown\">',\n                sprintf('<i class=\"%s %s\"></i>', this.options.iconsPrefix, this.options.icons.columns),\n                ' <span class=\"caret\"></span>',\n                '</button>',\n                '<ul class=\"dropdown-menu\" role=\"menu\">');\n\n            $.each(this.options.columns, function (i, column) {\n                if (column.radio || column.checkbox) {\n                    return;\n                }\n\n                if (that.options.cardView && (!column.cardVisible)) {\n                    return;\n                }\n\n                var checked = column.visible ? ' checked=\"checked\"' : '';\n\n                if (column.switchable) {\n                    html.push(sprintf('<li>' +\n                        '<label><input type=\"checkbox\" data-field=\"%s\" value=\"%s\"%s> %s</label>' +\n                        '</li>', column.field, i, checked, column.title));\n                    switchableCount++;\n                }\n            });\n            html.push('</ul>',\n                '</div>');\n        }\n\n        html.push('</div>');\n\n        // Fix #188: this.showToolbar is for extentions\n        if (this.showToolbar || html.length > 2) {\n            this.$toolbar.append(html.join(''));\n        }\n\n        if (this.options.showPaginationSwitch) {\n            this.$toolbar.find('button[name=\"paginationSwitch\"]')\n                .off('click').on('click', $.proxy(this.togglePagination, this));\n        }\n\n        if (this.options.showRefresh) {\n            this.$toolbar.find('button[name=\"refresh\"]')\n                .off('click').on('click', $.proxy(this.refresh, this));\n        }\n\n        if (this.options.showToggle) {\n            this.$toolbar.find('button[name=\"toggle\"]')\n                .off('click').on('click', function () {\n                    that.toggleView();\n                });\n        }\n\n        if (this.options.showColumns) {\n            $keepOpen = this.$toolbar.find('.keep-open');\n\n            if (switchableCount <= this.options.minimumCountColumns) {\n                $keepOpen.find('input').prop('disabled', true);\n            }\n\n            $keepOpen.find('li').off('click').on('click', function (event) {\n                event.stopImmediatePropagation();\n            });\n            $keepOpen.find('input').off('click').on('click', function () {\n                var $this = $(this);\n\n                that.toggleColumn(getFieldIndex(that.options.columns, $(this).data('field')), $this.prop('checked'), false);\n                that.trigger('column-switch', $(this).data('field'), $this.prop('checked'));\n            });\n        }\n\n        if (this.options.search) {\n            html = [];\n            html.push(\n                '<div class=\"pull-' + this.options.searchAlign + ' search\">',\n                sprintf('<input class=\"form-control' + (this.options.iconSize === undefined ? '' : ' input-' + this.options.iconSize) + '\" type=\"text\" placeholder=\"%s\">',\n                    this.options.formatSearch()),\n                '</div>');\n\n            this.$toolbar.append(html.join(''));\n            $search = this.$toolbar.find('.search input');\n            $search.off('keyup drop').on('keyup drop', function (event) {\n                clearTimeout(timeoutId); // doesn't matter if it's 0\n                timeoutId = setTimeout(function () {\n                    that.onSearch(event);\n                }, that.options.searchTimeOut);\n            });\n\n            if (this.options.searchText !== '') {\n                $search.val(this.options.searchText);\n                clearTimeout(timeoutId); // doesn't matter if it's 0\n                timeoutId = setTimeout(function () {\n                    $search.trigger('keyup');\n                }, that.options.searchTimeOut);\n            }\n        }\n    };\n\n    BootstrapTable.prototype.onSearch = function (event) {\n        var text = $.trim($(event.currentTarget).val());\n\n        // trim search input\n        if (this.options.trimOnSearch && $(event.currentTarget).val() !== text) {\n            $(event.currentTarget).val(text);\n        }\n\n        if (text === this.searchText) {\n            return;\n        }\n        this.searchText = text;\n\n        this.options.pageNumber = 1;\n        this.initSearch();\n        this.updatePagination();\n        this.trigger('search', text);\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        var that = this;\n\n        if (this.options.sidePagination !== 'server') {\n            var s = this.searchText && this.searchText.toLowerCase();\n            var f = $.isEmptyObject(this.filterColumns) ? null : this.filterColumns;\n\n            // Check filter\n            this.data = f ? $.grep(this.options.data, function (item, i) {\n                for (var key in f) {\n                    if (item[key] !== f[key]) {\n                        return false;\n                    }\n                }\n                return true;\n            }) : this.options.data;\n\n            this.data = s ? $.grep(this.data, function (item, i) {\n                for (var key in item) {\n                    key = $.isNumeric(key) ? parseInt(key, 10) : key;\n                    var value = item[key],\n                        column = that.options.columns[getFieldIndex(that.options.columns, key)],\n                        j = $.inArray(key, that.header.fields);\n\n                    // Fix #142: search use formated data\n                    value = calculateObjectValue(column,\n                        that.header.formatters[j],\n                        [value, item, i], value);\n\n                    var index = $.inArray(key, that.header.fields);\n                    if (index !== -1 && that.header.searchables[index] &&\n                        (typeof value === 'string' ||\n                            typeof value === 'number') &&\n                        (value + '').toLowerCase().indexOf(s) !== -1) {\n                        return true;\n                    }\n                }\n                return false;\n            }) : this.data;\n        }\n    };\n\n    BootstrapTable.prototype.initPagination = function () {\n        if (!this.options.pagination) {\n            this.$pagination.hide();\n            return;\n        } else {\n            this.$pagination.show();\n        }\n\n        var that = this,\n            html = [],\n            $allSelected = false,\n            i, from, to,\n            $pageList,\n            $first, $pre,\n            $next, $last,\n            $number,\n            data = this.getData();\n\n        if (this.options.sidePagination !== 'server') {\n            this.options.totalRows = data.length;\n        }\n\n        this.totalPages = 0;\n        if (this.options.totalRows) {\n            if (this.options.pageSize === this.options.formatAllRows()) {\n                this.options.pageSize = this.options.totalRows;\n                $allSelected = true;\n            } else if (this.options.pageSize === this.options.totalRows) {\n                // Fix #667 Table with pagination, multiple pages and a search that matches to one page throws exception\n                var pageLst = typeof this.options.pageList === 'string' ?\n                    this.options.pageList.replace('[', '').replace(']', '').replace(/ /g, '').toLowerCase().split(',') :\n                    this.options.pageList;\n                if (pageLst.indexOf(this.options.formatAllRows().toLowerCase()) > -1) {\n                    $allSelected = true;\n                }\n            }\n\n            this.totalPages = ~~((this.options.totalRows - 1) / this.options.pageSize) + 1;\n\n            this.options.totalPages = this.totalPages;\n        }\n        if (this.totalPages > 0 && this.options.pageNumber > this.totalPages) {\n            this.options.pageNumber = this.totalPages;\n        }\n\n        this.pageFrom = (this.options.pageNumber - 1) * this.options.pageSize + 1;\n        this.pageTo = this.options.pageNumber * this.options.pageSize;\n        if (this.pageTo > this.options.totalRows) {\n            this.pageTo = this.options.totalRows;\n        }\n\n        html.push(\n            '<div class=\"pull-' + this.options.paginationDetailHAlign + ' pagination-detail\">',\n            '<span class=\"pagination-info\">',\n            this.options.formatShowingRows(this.pageFrom, this.pageTo, this.options.totalRows),\n            '</span>');\n\n        html.push('<span class=\"page-list\">');\n\n        var pageNumber = [\n                sprintf('<span class=\"btn-group %s\">', this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ?\n                    'dropdown' : 'dropup'),\n                '<button type=\"button\" class=\"btn btn-default ' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + ' dropdown-toggle\" data-toggle=\"dropdown\">',\n                '<span class=\"page-size\">',\n                $allSelected ? this.options.formatAllRows() : this.options.pageSize,\n                '</span>',\n                ' <span class=\"caret\"></span>',\n                '</button>',\n                '<ul class=\"dropdown-menu\" role=\"menu\">'],\n            pageList = this.options.pageList;\n\n        if (typeof this.options.pageList === 'string') {\n            var list = this.options.pageList.replace('[', '').replace(']', '').replace(/ /g, '').split(',');\n\n            pageList = [];\n            $.each(list, function (i, value) {\n                pageList.push(value.toUpperCase() === that.options.formatAllRows().toUpperCase() ?\n                    that.options.formatAllRows() : +value);\n            });\n        }\n\n        $.each(pageList, function (i, page) {\n            if (!that.options.smartDisplay || i === 0 || pageList[i - 1] <= that.options.totalRows) {\n                var active;\n                if ($allSelected) {\n                    active = page === that.options.formatAllRows() ? ' class=\"active\"' : '';\n                } else {\n                    active = page === that.options.pageSize ? ' class=\"active\"' : '';\n                }\n                pageNumber.push(sprintf('<li%s><a href=\"javascript:void(0)\">%s</a></li>', active, page));\n            }\n        });\n        pageNumber.push('</ul></span>');\n\n        html.push(this.options.formatRecordsPerPage(pageNumber.join('')));\n        html.push('</span>');\n\n        html.push('</div>',\n            '<div class=\"pull-' + this.options.paginationHAlign + ' pagination\">',\n            '<ul class=\"pagination' + (this.options.iconSize === undefined ? '' : ' pagination-' + this.options.iconSize) + '\">',\n            '<li class=\"page-first\"><a href=\"javascript:void(0)\">' + this.options.paginationFirstText + '</a></li>',\n            '<li class=\"page-pre\"><a href=\"javascript:void(0)\">' + this.options.paginationPreText + '</a></li>');\n\n        if (this.totalPages < 5) {\n            from = 1;\n            to = this.totalPages;\n        } else {\n            from = this.options.pageNumber - 2;\n            to = from + 4;\n            if (from < 1) {\n                from = 1;\n                to = 5;\n            }\n            if (to > this.totalPages) {\n                to = this.totalPages;\n                from = to - 4;\n            }\n        }\n        for (i = from; i <= to; i++) {\n            html.push('<li class=\"page-number' + (i === this.options.pageNumber ? ' active' : '') + '\">',\n                '<a href=\"javascript:void(0)\">', i, '</a>',\n                '</li>');\n        }\n\n        html.push(\n            '<li class=\"page-next\"><a href=\"javascript:void(0)\">' + this.options.paginationNextText + '</a></li>',\n            '<li class=\"page-last\"><a href=\"javascript:void(0)\">' + this.options.paginationLastText + '</a></li>',\n            '</ul>',\n            '</div>');\n\n        this.$pagination.html(html.join(''));\n\n        $pageList = this.$pagination.find('.page-list a');\n        $first = this.$pagination.find('.page-first');\n        $pre = this.$pagination.find('.page-pre');\n        $next = this.$pagination.find('.page-next');\n        $last = this.$pagination.find('.page-last');\n        $number = this.$pagination.find('.page-number');\n\n        if (this.options.pageNumber <= 1) {\n            $first.addClass('disabled');\n            $pre.addClass('disabled');\n        }\n        if (this.options.pageNumber >= this.totalPages) {\n            $next.addClass('disabled');\n            $last.addClass('disabled');\n        }\n        if (this.options.smartDisplay) {\n            if (this.totalPages <= 1) {\n                this.$pagination.find('div.pagination').hide();\n            }\n            if (pageList.length < 2 || this.options.totalRows <= pageList[0]) {\n                this.$pagination.find('span.page-list').hide();\n            }\n\n            // when data is empty, hide the pagination\n            this.$pagination[this.getData().length ? 'show' : 'hide']();\n        }\n        if ($allSelected) {\n            this.options.pageSize = this.options.formatAllRows();\n        }\n        $pageList.off('click').on('click', $.proxy(this.onPageListChange, this));\n        $first.off('click').on('click', $.proxy(this.onPageFirst, this));\n        $pre.off('click').on('click', $.proxy(this.onPagePre, this));\n        $next.off('click').on('click', $.proxy(this.onPageNext, this));\n        $last.off('click').on('click', $.proxy(this.onPageLast, this));\n        $number.off('click').on('click', $.proxy(this.onPageNumber, this));\n    };\n\n    BootstrapTable.prototype.updatePagination = function (event) {\n        // Fix #171: IE disabled button can be clicked bug.\n        if (event && $(event.currentTarget).hasClass('disabled')) {\n            return;\n        }\n\n        if (!this.options.maintainSelected) {\n            this.resetRows();\n        }\n\n        this.initPagination();\n        if (this.options.sidePagination === 'server') {\n            this.initServer();\n        } else {\n            this.initBody();\n        }\n\n        this.trigger('page-change', this.options.pageNumber, this.options.pageSize);\n    };\n\n    BootstrapTable.prototype.onPageListChange = function (event) {\n        var $this = $(event.currentTarget);\n\n        $this.parent().addClass('active').siblings().removeClass('active');\n        this.options.pageSize = $this.text().toUpperCase() === this.options.formatAllRows().toUpperCase() ?\n            this.options.formatAllRows() : +$this.text();\n        this.$toolbar.find('.page-size').text(this.options.pageSize);\n\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPageFirst = function (event) {\n        this.options.pageNumber = 1;\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPagePre = function (event) {\n        this.options.pageNumber--;\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPageNext = function (event) {\n        this.options.pageNumber++;\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPageLast = function (event) {\n        this.options.pageNumber = this.totalPages;\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.onPageNumber = function (event) {\n        if (this.options.pageNumber === +$(event.currentTarget).text()) {\n            return;\n        }\n        this.options.pageNumber = +$(event.currentTarget).text();\n        this.updatePagination(event);\n    };\n\n    BootstrapTable.prototype.initBody = function (fixedScroll) {\n        var that = this,\n            html = [],\n            data = this.getData();\n\n        this.trigger('pre-body', data);\n\n        this.$body = this.$el.find('tbody');\n        if (!this.$body.length) {\n            this.$body = $('<tbody></tbody>').appendTo(this.$el);\n        }\n\n        //Fix #389 Bootstrap-table-flatJSON is not working\n\n        if (!this.options.pagination || this.options.sidePagination === 'server') {\n            this.pageFrom = 1;\n            this.pageTo = data.length;\n        }\n\n        for (var i = this.pageFrom - 1; i < this.pageTo; i++) {\n            var key,\n                item = data[i],\n                style = {},\n                csses = [],\n                data_ = '',\n                attributes = {},\n                htmlAttributes = [];\n\n            style = calculateObjectValue(this.options, this.options.rowStyle, [item, i], style);\n\n            if (style && style.css) {\n                for (key in style.css) {\n                    csses.push(key + ': ' + style.css[key]);\n                }\n            }\n\n            attributes = calculateObjectValue(this.options,\n                this.options.rowAttributes, [item, i], attributes);\n\n            if (attributes) {\n                for (key in attributes) {\n                    htmlAttributes.push(sprintf('%s=\"%s\"', key, escapeHTML(attributes[key])));\n                }\n            }\n\n            if (item._data && !$.isEmptyObject(item._data)) {\n                $.each(item._data, function (k, v) {\n                    // ignore data-index\n                    if (k === 'index') {\n                        return;\n                    }\n                    data_ += sprintf(' data-%s=\"%s\"', k, v);\n                });\n            }\n\n            html.push('<tr',\n                sprintf(' %s', htmlAttributes.join(' ')),\n                sprintf(' id=\"%s\"', $.isArray(item) ? undefined : item._id),\n                sprintf(' class=\"%s\"', style.classes || ($.isArray(item) ? undefined : item._class)),\n                sprintf(' data-index=\"%s\"', i),\n                sprintf(' data-uniqueid=\"%s\"', item[this.options.uniqueId]),\n                sprintf('%s', data_),\n                '>'\n            );\n\n            if (this.options.cardView) {\n                html.push(sprintf('<td colspan=\"%s\">', this.header.fields.length));\n            }\n\n            if (!this.options.cardView && this.options.detailView) {\n                html.push('<td>',\n                    '<a class=\"detail-icon\" href=\"javascript:\">',\n                    '<i class=\"glyphicon glyphicon-plus icon-plus\"></i>',\n                    '</a>',\n                    '</td>');\n            }\n\n            $.each(this.header.fields, function (j, field) {\n                var text = '',\n                    value = item[field],\n                    type = '',\n                    cellStyle = {},\n                    id_ = '',\n                    class_ = that.header.classes[j],\n                    data_ = '',\n                    rowspan_ = '',\n                    column = that.options.columns[getFieldIndex(that.options.columns, field)];\n\n                style = sprintf('style=\"%s\"', csses.concat(that.header.styles[j]).join('; '));\n\n                value = calculateObjectValue(column,\n                    that.header.formatters[j], [value, item, i], value);\n\n                // handle td's id and class\n                if (item['_' + field + '_id']) {\n                    id_ = sprintf(' id=\"%s\"', item['_' + field + '_id']);\n                }\n                if (item['_' + field + '_class']) {\n                    class_ = sprintf(' class=\"%s\"', item['_' + field + '_class']);\n                }\n                if (item['_' + field + '_rowspan']) {\n                    rowspan_ = sprintf(' rowspan=\"%s\"', item['_' + field + '_rowspan']);\n                }\n                cellStyle = calculateObjectValue(that.header,\n                    that.header.cellStyles[j], [value, item, i], cellStyle);\n                if (cellStyle.classes) {\n                    class_ = sprintf(' class=\"%s\"', cellStyle.classes);\n                }\n                if (cellStyle.css) {\n                    var csses_ = [];\n                    for (var key in cellStyle.css) {\n                        csses_.push(key + ': ' + cellStyle.css[key]);\n                    }\n                    style = sprintf('style=\"%s\"', csses_.concat(that.header.styles[j]).join('; '));\n                }\n\n                if (item['_' + field + '_data'] && !$.isEmptyObject(item['_' + field + '_data'])) {\n                    $.each(item['_' + field + '_data'], function (k, v) {\n                        // ignore data-index\n                        if (k === 'index') {\n                            return;\n                        }\n                        data_ += sprintf(' data-%s=\"%s\"', k, v);\n                    });\n                }\n\n                if (column.checkbox || column.radio) {\n                    type = column.checkbox ? 'checkbox' : type;\n                    type = column.radio ? 'radio' : type;\n\n                    text = [that.options.cardView ?\n                        '<div class=\"card-view\">' : '<td class=\"bs-checkbox\">',\n                        '<input' +\n                            sprintf(' data-index=\"%s\"', i) +\n                            sprintf(' name=\"%s\"', that.options.selectItemName) +\n                            sprintf(' type=\"%s\"', type) +\n                            sprintf(' value=\"%s\"', item[that.options.idField]) +\n                            sprintf(' checked=\"%s\"', value === true ||\n                                (value && value.checked) ? 'checked' : undefined) +\n                            sprintf(' disabled=\"%s\"', !column.checkboxEnabled ||\n                                (value && value.disabled) ? 'disabled' : undefined) +\n                            ' />',\n                        that.options.cardView ? '</div>' : '</td>'].join('');\n\n                    item[that.header.stateField] = value === true || (value && value.checked);\n                } else {\n                    value = typeof value === 'undefined' || value === null ?\n                        that.options.undefinedText : value;\n\n                    text = that.options.cardView ?\n                        ['<div class=\"card-view\">',\n                            that.options.showHeader ? sprintf('<span class=\"title\" %s>%s</span>', style,\n                                getPropertyFromOther(that.options.columns, 'field', 'title', field)) : '',\n                            sprintf('<span class=\"value\">%s</span>', value),\n                            '</div>'].join('') :\n                        [sprintf('<td%s %s %s %s %s>', id_, class_, style, data_, rowspan_),\n                            value,\n                            '</td>'].join('');\n\n                    // Hide empty data on Card view when smartDisplay is set to true.\n                    if (that.options.cardView && that.options.smartDisplay && value === '') {\n                        text = '';\n                    }\n                }\n\n                html.push(text);\n            });\n\n            if (this.options.cardView) {\n                html.push('</td>');\n            }\n\n            html.push('</tr>');\n        }\n\n        // show no records\n        if (!html.length) {\n            html.push('<tr class=\"no-records-found\">',\n                sprintf('<td colspan=\"%s\">%s</td>',\n                    this.$header.find('th').length, this.options.formatNoMatches()),\n                '</tr>');\n        }\n\n        this.$body.html(html.join(''));\n\n        if (!fixedScroll) {\n            this.scrollTo(0);\n        }\n\n        // click to select by column\n        this.$body.find('> tr > td').off('click').on('click', function () {\n            var $td = $(this),\n                $tr = $td.parent(),\n                item = that.data[$tr.data('index')],\n                cellIndex = $td[0].cellIndex,\n                $headerCell = that.$header.find('th:eq(' + cellIndex + ')'),\n                field = $headerCell.data('field'),\n                value = item[field];\n            that.trigger('click-cell', field, value, item, $td);\n            that.trigger('click-row', item, $tr);\n            // if click to select - then trigger the checkbox/radio click\n            if (that.options.clickToSelect) {\n                if (that.header.clickToSelects[$tr.children().index($(this))]) {\n                    $tr.find(sprintf('[name=\"%s\"]',\n                        that.options.selectItemName))[0].click(); // #144: .trigger('click') bug\n                }\n            }\n        });\n        this.$body.find('> tr > td').off('dblclick').on('dblclick', function () {\n            var $td = $(this),\n                $tr = $td.parent(),\n                item = that.data[$tr.data('index')],\n                cellIndex = $td[0].cellIndex,\n                $headerCell = that.$header.find('th:eq(' + cellIndex + ')'),\n                field = $headerCell.data('field'),\n                value = item[field];\n            that.trigger('dbl-click-cell', field, value, item, $td);\n            that.trigger('dbl-click-row', item, $tr);\n        });\n\n        this.$body.find('> tr > td > .detail-icon').off('click').on('click', function () {\n            var $this = $(this),\n                $tr = $this.parent().parent(),\n                index = $tr.data('index'),\n                row = that.options.data[index];\n\n            // remove and update\n            if ($tr.next().is('tr.detail-view')) {\n                $this.find('i').attr('class', 'glyphicon glyphicon-plus icon-plus');\n                $tr.next().remove();\n                that.trigger('collapse-row', index, row);\n            } else {\n                $this.find('i').attr('class', 'glyphicon glyphicon-minus icon-minus');\n                $tr.after(sprintf('<tr class=\"detail-view\"><td colspan=\"%s\">%s</td></tr>',\n                    $tr.find('td').length, calculateObjectValue(that.options,\n                        that.options.detailFormatter, [index, row], '')));\n                that.trigger('expand-row', index, row, $tr.next().find('td'));\n            }\n            that.resetView();\n        });\n\n        this.$selectItem = this.$body.find(sprintf('[name=\"%s\"]', this.options.selectItemName));\n        this.$selectItem.off('click').on('click', function (event) {\n            event.stopImmediatePropagation();\n\n            var checked = $(this).prop('checked'),\n                row = that.data[$(this).data('index')];\n\n            row[that.header.stateField] = checked;\n\n            if (that.options.singleSelect) {\n                that.$selectItem.not(this).each(function () {\n                    that.data[$(this).data('index')][that.header.stateField] = false;\n                });\n                that.$selectItem.filter(':checked').not(this).prop('checked', false);\n            }\n\n            that.updateSelected();\n            that.trigger(checked ? 'check' : 'uncheck', row);\n        });\n\n        $.each(this.header.events, function (i, events) {\n            if (!events) {\n                return;\n            }\n            // fix bug, if events is defined with namespace\n            if (typeof events === 'string') {\n                events = calculateObjectValue(null, events);\n            }\n            if (!that.options.cardView && that.options.detailView) {\n                i += 1;\n            }\n            for (var key in events) {\n                that.$body.find('tr').each(function () {\n                    var $tr = $(this),\n                        $td = $tr.find(that.options.cardView ? '.card-view' : 'td').eq(i),\n                        index = key.indexOf(' '),\n                        name = key.substring(0, index),\n                        el = key.substring(index + 1),\n                        func = events[key];\n\n                    $td.find(el).off(name).on(name, function (e) {\n                        var index = $tr.data('index'),\n                            row = that.data[index],\n                            value = row[that.header.fields[i]];\n\n                        func.apply(this, [e, value, row, index]);\n                    });\n                });\n            }\n        });\n\n        this.updateSelected();\n        this.resetView();\n\n        this.trigger('post-body');\n    };\n\n    BootstrapTable.prototype.initServer = function (silent, query) {\n        var that = this,\n            data = {},\n            params = {\n                pageSize: this.options.pageSize === this.options.formatAllRows() ?\n                    this.options.totalRows : this.options.pageSize,\n                pageNumber: this.options.pageNumber,\n                searchText: this.searchText,\n                sortName: this.options.sortName,\n                sortOrder: this.options.sortOrder\n            },\n            request;\n\n        if (!this.options.url && !this.options.ajax) {\n            return;\n        }\n\n        if (this.options.queryParamsType === 'limit') {\n            params = {\n                search: params.searchText,\n                sort: params.sortName,\n                order: params.sortOrder\n            };\n            if (this.options.pagination) {\n                params.limit = this.options.pageSize === this.options.formatAllRows() ?\n                    this.options.totalRows : this.options.pageSize;\n                params.offset = this.options.pageSize === this.options.formatAllRows() ?\n                    0 : this.options.pageSize * (this.options.pageNumber - 1);\n            }\n        }\n\n        if (!($.isEmptyObject(this.filterColumnsPartial))) {\n            params['filter'] = JSON.stringify(this.filterColumnsPartial, null);\n        }\n\n        data = calculateObjectValue(this.options, this.options.queryParams, [params], data);\n\n        $.extend(data, query || {});\n\n        // false to stop request\n        if (data === false) {\n            return;\n        }\n\n        if (!silent) {\n            this.$tableLoading.show();\n        }\n        request = $.extend({}, calculateObjectValue(null, this.options.ajaxOptions), {\n            type: this.options.method,\n            url: this.options.url,\n            data: this.options.contentType === 'application/json' && this.options.method === 'post' ?\n                JSON.stringify(data) : data,\n            cache: this.options.cache,\n            contentType: this.options.contentType,\n            dataType: this.options.dataType,\n            success: function (res) {\n                res = calculateObjectValue(that.options, that.options.responseHandler, [res], res);\n\n                that.load(res);\n                that.trigger('load-success', res);\n            },\n            error: function (res) {\n                that.trigger('load-error', res.status);\n            },\n            complete: function () {\n                if (!silent) {\n                    that.$tableLoading.hide();\n                }\n            }\n        });\n\n        if (this.options.ajax) {\n            calculateObjectValue(this, this.options.ajax, [request], null);\n        } else {\n            $.ajax(request);\n        }\n    };\n\n    BootstrapTable.prototype.getCaretHtml = function () {\n        var that = this;\n\n        $.each(this.$header.find('th'), function (i, th) {\n            if ($(th).data('field') === that.options.sortName) {\n                $(th).find('.sortable').css('background-image', 'url(' + (that.options.sortOrder === 'desc' ? arrowDesc : arrowAsc) + ')');\n            } else {\n                $(th).find('.sortable').css('background-image', 'url(' + arrowBoth +')');\n            }\n        });\n    };\n\n    BootstrapTable.prototype.updateSelected = function () {\n        var checkAll = this.$selectItem.filter(':enabled').length ===\n            this.$selectItem.filter(':enabled').filter(':checked').length;\n\n        this.$selectAll.add(this.$selectAll_).prop('checked', checkAll);\n\n        this.$selectItem.each(function () {\n            $(this).parents('tr')[$(this).prop('checked') ? 'addClass' : 'removeClass']('selected');\n        });\n    };\n\n    BootstrapTable.prototype.updateRows = function () {\n        var that = this;\n\n        this.$selectItem.each(function () {\n            that.data[$(this).data('index')][that.header.stateField] = $(this).prop('checked');\n        });\n    };\n\n    BootstrapTable.prototype.resetRows = function () {\n        var that = this;\n\n        $.each(this.data, function (i, row) {\n            that.$selectAll.prop('checked', false);\n            that.$selectItem.prop('checked', false);\n            row[that.header.stateField] = false;\n        });\n    };\n\n    BootstrapTable.prototype.trigger = function (name) {\n        var args = Array.prototype.slice.call(arguments, 1);\n\n        name += '.bs.table';\n        this.options[BootstrapTable.EVENTS[name]].apply(this.options, args);\n        this.$el.trigger($.Event(name), args);\n\n        this.options.onAll(name, args);\n        this.$el.trigger($.Event('all.bs.table'), [name, args]);\n    };\n\n    BootstrapTable.prototype.resetHeader = function () {\n        // fix #61: the hidden table reset header bug.\n        // fix bug: get $el.css('width') error sometime (height = 500)\n        clearTimeout(this.timeoutId_);\n        this.timeoutId_ = setTimeout($.proxy(this.fitHeader, this), this.$el.is(':hidden') ? 100 : 0);\n    };\n\n    BootstrapTable.prototype.fitHeader = function () {\n        var that = this,\n            fixedBody,\n            scrollWidth;\n\n        if (that.$el.is(':hidden')) {\n            that.timeoutFooter_ = setTimeout($.proxy(that.fitHeader, that), 100);\n            return;\n        }\n        fixedBody = this.$tableBody.get(0);\n\n        scrollWidth = fixedBody.scrollWidth > fixedBody.clientWidth &&\n            fixedBody.scrollHeight > fixedBody.clientHeight + this.$header.height() ?\n            getScrollBarWidth() : 0;\n\n        this.$el.css('margin-top', -this.$header.height());\n        this.$header_ = this.$header.clone(true, true);\n        this.$selectAll_ = this.$header_.find('[name=\"btSelectAll\"]');\n        this.$tableHeader.css({\n            'margin-right': scrollWidth\n        }).find('table').css('width', this.$el.css('width'))\n            .html('').attr('class', this.$el.attr('class'))\n            .append(this.$header_);\n\n        // fix bug: $.data() is not working as expected after $.append()\n        this.$header.find('th').each(function (i) {\n            that.$header_.find('th').eq(i).data($(this).data());\n        });\n\n        this.$body.find('tr:first-child:not(.no-records-found) > *').each(function (i) {\n            that.$header_.find('div.fht-cell').eq(i).width($(this).innerWidth());\n        });\n        // horizontal scroll event\n        // TODO: it's probably better improving the layout than binding to scroll event\n        this.$tableBody.off('scroll').on('scroll', function () {\n            that.$tableHeader.scrollLeft($(this).scrollLeft());\n        });\n        that.trigger('post-header');\n    };\n\n    BootstrapTable.prototype.resetFooter = function () {\n        var that = this,\n            data = that.getData(),\n            html = [];\n\n        if (!this.options.showFooter || this.options.cardView) { //do nothing\n            return;\n        }\n\n        if (!this.options.cardView && this.options.detailView) {\n            html.push('<td></td>');\n        }\n\n        $.each(this.options.columns, function (i, column) {\n            var falign = '', // footer align style\n                style = '',\n                class_ = sprintf(' class=\"%s\"', column['class']);\n\n            if (!column.visible) {\n                return;\n            }\n\n            if (that.options.cardView && (!column.cardVisible)) {\n                return;\n            }\n\n            falign = sprintf('text-align: %s; ', column.falign ? column.falign : column.align);\n            style = sprintf('vertical-align: %s; ', column.valign);\n\n            html.push('<td', class_, sprintf(' style=\"%s\"', falign + style), '>');\n\n            html.push(calculateObjectValue(column, column.footerFormatter, [data], '&nbsp;') || '&nbsp;');\n            html.push('</td>');\n        });\n\n        this.$tableFooter.find('tr').html(html.join(''));\n        clearTimeout(this.timeoutFooter_);\n        this.timeoutFooter_ = setTimeout($.proxy(this.fitFooter, this),\n            this.$el.is(':hidden') ? 100 : 0);\n    };\n\n    BootstrapTable.prototype.fitFooter = function () {\n        var that = this,\n            $footerTd,\n            elWidth,\n            scrollWidth;\n\n        clearTimeout(this.timeoutFooter_);\n        if (this.$el.is(':hidden')) {\n            this.timeoutFooter_ = setTimeout($.proxy(this.fitFooter, this), 100);\n            return;\n        }\n\n        elWidth = this.$el.css('width');\n        scrollWidth = elWidth > this.$tableBody.width() ? getScrollBarWidth() : 0;\n\n        this.$tableFooter.css({\n            'margin-right': scrollWidth\n        }).find('table').css('width', elWidth)\n            .attr('class', this.$el.attr('class'));\n\n        $footerTd = this.$tableFooter.find('td');\n\n        this.$tableBody.find('tbody tr:first-child:not(.no-records-found) > td').each(function (i) {\n            $footerTd.eq(i).outerWidth($(this).outerWidth());\n        });\n    };\n\n    BootstrapTable.prototype.toggleColumn = function (index, checked, needUpdate) {\n        if (index === -1) {\n            return;\n        }\n        this.options.columns[index].visible = checked;\n        this.initHeader();\n        this.initSearch();\n        this.initPagination();\n        this.initBody();\n\n        if (this.options.showColumns) {\n            var $items = this.$toolbar.find('.keep-open input').prop('disabled', false);\n\n            if (needUpdate) {\n                $items.filter(sprintf('[value=\"%s\"]', index)).prop('checked', checked);\n            }\n\n            if ($items.filter(':checked').length <= this.options.minimumCountColumns) {\n                $items.filter(':checked').prop('disabled', true);\n            }\n        }\n    };\n\n    BootstrapTable.prototype.toggleRow = function (index, isIdField, visible) {\n        if (index === -1) {\n            return;\n        }\n\n        $(this.$body[0]).children().filter(sprintf(isIdField ? '[data-uniqueid=\"%s\"]' : '[data-index=\"%s\"]', index))\n            [visible ? 'show' : 'hide']();\n    };\n\n    // PUBLIC FUNCTION DEFINITION\n    // =======================\n\n    BootstrapTable.prototype.resetView = function (params) {\n        var padding = 0;\n\n        if (params && params.height) {\n            this.options.height = params.height;\n        }\n\n        this.$selectAll.prop('checked', this.$selectItem.length > 0 &&\n            this.$selectItem.length === this.$selectItem.filter(':checked').length);\n\n        if (this.options.height) {\n            var toolbarHeight = getRealHeight(this.$toolbar),\n                paginationHeight = getRealHeight(this.$pagination),\n                height = this.options.height - toolbarHeight - paginationHeight;\n\n            this.$tableContainer.css('height', height + 'px');\n        }\n\n        if (this.options.cardView) {\n            // remove the element css\n            this.$el.css('margin-top', '0');\n            this.$tableContainer.css('padding-bottom', '0');\n            return;\n        }\n\n        if (this.options.showHeader && this.options.height) {\n            this.$tableHeader.show();\n            this.resetHeader();\n            padding += cellHeight;\n        } else {\n            this.$tableHeader.hide();\n            this.trigger('post-header');\n        }\n\n        if (this.options.showFooter) {\n            this.resetFooter();\n            if (this.options.height) {\n                padding += cellHeight;\n            }\n        }\n\n        // Assign the correct sortable arrow\n        this.getCaretHtml();\n        this.$tableContainer.css('padding-bottom', padding + 'px');\n    };\n\n    BootstrapTable.prototype.getData = function (useCurrentPage) {\n        return (this.searchText\n            || !$.isEmptyObject(this.filterColumns)\n            || !$.isEmptyObject(this.filterColumnsPartial)) ?\n            (useCurrentPage ? this.data.slice(this.pageFrom -1, this.pageTo)\n                : this.data) :\n            (useCurrentPage ? this.options.data.slice(this.pageFrom - 1, this.pageTo)\n                : this.options.data);\n    };\n\n    BootstrapTable.prototype.load = function (data) {\n        var fixedScroll = false;\n\n        // #431: support pagination\n        if (this.options.sidePagination === 'server') {\n            this.options.totalRows = data.total;\n            fixedScroll = data.fixedScroll;\n            data = data.rows;\n        } else if (!$.isArray(data)) { // support fixedScroll\n            fixedScroll = data.fixedScroll;\n            data = data.data;\n        }\n\n        this.initData(data);\n        this.initSearch();\n        this.initPagination();\n        this.initBody(fixedScroll);\n    };\n\n    BootstrapTable.prototype.append = function (data) {\n        this.initData(data, 'append');\n        this.initSearch();\n        this.initPagination();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.prepend = function (data) {\n        this.initData(data, 'prepend');\n        this.initSearch();\n        this.initPagination();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.remove = function (params) {\n        var len = this.options.data.length,\n            i, row;\n\n        if (!params.hasOwnProperty('field') || !params.hasOwnProperty('values')) {\n            return;\n        }\n\n        for (i = len - 1; i >= 0; i--) {\n            row = this.options.data[i];\n\n            if (!row.hasOwnProperty(params.field)) {\n                continue;\n            }\n            if ($.inArray(row[params.field], params.values) !== -1) {\n                this.options.data.splice(i, 1);\n            }\n        }\n\n        if (len === this.options.data.length) {\n            return;\n        }\n\n        this.initSearch();\n        this.initPagination();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.removeAll = function () {\n        if (this.options.data.length > 0) {\n            this.options.data.splice(0, this.options.data.length);\n            this.initSearch();\n            this.initPagination();\n            this.initBody(true);\n        }\n    };\n\n    BootstrapTable.prototype.removeByUniqueId = function (id) {\n        var uniqueId = this.options.uniqueId,\n            len = this.options.data.length,\n            i, row;\n\n        for (i = len - 1; i >= 0; i--) {\n            row = this.options.data[i];\n\n            if (!row.hasOwnProperty(uniqueId)) {\n                continue;\n            }\n\n            if (typeof row[uniqueId] === 'string') {\n                id = id.toString();\n            } else if (typeof row[uniqueId] === 'number') {\n                if ((Number(row[uniqueId]) === row[uniqueId]) && (row[uniqueId] % 1 === 0)) {\n                    id = parseInt(id);\n                } else if ((row[uniqueId] === Number(row[uniqueId])) && (row[uniqueId] !== 0)) {\n                    id = parseFloat(id);\n                }\n            }\n\n            if (row[uniqueId] === id) {\n                this.options.data.splice(i, 1);\n            }\n        }\n\n        if (len === this.options.data.length) {\n            return;\n        }\n\n        this.initSearch();\n        this.initPagination();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.insertRow = function (params) {\n        if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {\n            return;\n        }\n        this.data.splice(params.index, 0, params.row);\n        this.initSearch();\n        this.initPagination();\n        this.initSort();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.updateRow = function (params) {\n        if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {\n            return;\n        }\n        $.extend(this.data[params.index], params.row);\n        this.initSort();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.showRow = function (params) {\n        if (!params.hasOwnProperty('index')) {\n            return;\n        }\n\n        this.toggleRow(params.index, params.isIdField === undefined ? false : true, true);\n    };\n\n    BootstrapTable.prototype.hideRow = function (params) {\n        if (!params.hasOwnProperty('index')) {\n            return;\n        }\n\n        this.toggleRow(params.index, params.isIdField === undefined ? false : true, false);\n    };\n\n    BootstrapTable.prototype.getRowsHidden = function (show) {\n        var rows = $(this.$body[0]).children().filter(':hidden'),\n            i = 0;\n        if (show) {\n            for (; i < rows.length; i++) {\n                $(rows[i]).show();\n            }\n        }\n        return rows;\n    };\n\n    BootstrapTable.prototype.mergeCells = function (options) {\n        var row = options.index,\n            col = $.inArray(options.field, this.header.fields),\n            rowspan = options.rowspan || 1,\n            colspan = options.colspan || 1,\n            i, j,\n            $tr = this.$body.find('tr'),\n            $td = $tr.eq(row).find('td').eq(col);\n\n        if (!this.options.cardView && this.options.detailView) {\n            col += 1;\n        }\n        $td = $tr.eq(row).find('td').eq(col);\n\n        if (row < 0 || col < 0 || row >= this.data.length) {\n            return;\n        }\n\n        for (i = row; i < row + rowspan; i++) {\n            for (j = col; j < col + colspan; j++) {\n                $tr.eq(i).find('td').eq(j).hide();\n            }\n        }\n\n        $td.attr('rowspan', rowspan).attr('colspan', colspan).show();\n    };\n\n    BootstrapTable.prototype.updateCell = function (params) {\n        if (!params.hasOwnProperty('rowIndex') || !params.hasOwnProperty('fieldName') || !params.hasOwnProperty('fieldValue')) {\n            return;\n        }\n        this.data[params.rowIndex][params.fieldName] = params.fieldValue;\n        this.initSort();\n        this.initBody(true);\n    };\n\n    BootstrapTable.prototype.getOptions = function () {\n        return this.options;\n    };\n\n    BootstrapTable.prototype.getSelections = function () {\n        var that = this;\n\n        return $.grep(this.data, function (row) {\n            return row[that.header.stateField];\n        });\n    };\n\n    BootstrapTable.prototype.getAllSelections = function () {\n        var that = this;\n\n        return $.grep(this.options.data, function (row) {\n            return row[that.header.stateField];\n        });\n    };\n\n    BootstrapTable.prototype.checkAll = function () {\n        this.checkAll_(true);\n    };\n\n    BootstrapTable.prototype.uncheckAll = function () {\n        this.checkAll_(false);\n    };\n\n    BootstrapTable.prototype.checkAll_ = function (checked) {\n        var rows;\n        if (!checked) {\n            rows = this.getSelections();\n        }\n        this.$selectItem.filter(':enabled').prop('checked', checked);\n        this.updateRows();\n        this.updateSelected();\n        if (checked) {\n            rows = this.getSelections();\n        }\n        this.trigger(checked ? 'check-all' : 'uncheck-all', rows);\n    };\n\n    BootstrapTable.prototype.check = function (index) {\n        this.check_(true, index);\n    };\n\n    BootstrapTable.prototype.uncheck = function (index) {\n        this.check_(false, index);\n    };\n\n    BootstrapTable.prototype.check_ = function (checked, index) {\n        this.$selectItem.filter(sprintf('[data-index=\"%s\"]', index)).prop('checked', checked);\n        this.data[index][this.header.stateField] = checked;\n        this.updateSelected();\n        this.trigger(checked ? 'check' : 'uncheck', this.data[index]);\n    };\n\n    BootstrapTable.prototype.checkBy = function (obj) {\n        this.checkBy_(true, obj);\n    };\n\n    BootstrapTable.prototype.uncheckBy = function (obj) {\n        this.checkBy_(false, obj);\n    };\n\n    BootstrapTable.prototype.checkBy_ = function (checked, obj) {\n        if (!obj.hasOwnProperty('field') || !obj.hasOwnProperty('values')) {\n            return;\n        }\n\n        var that = this,\n            rows = [];\n        $.each(this.options.data, function (index, row) {\n            if (!row.hasOwnProperty(obj.field)) {\n                return false;\n            }\n            if ($.inArray(row[obj.field], obj.values) !== -1) {\n                that.$selectItem.filter(sprintf('[data-index=\"%s\"]', index)).prop('checked', checked);\n                row[that.header.stateField] = checked;\n                rows.push(row);\n                that.trigger(checked ? 'check' : 'uncheck', row);\n            }\n        });\n        this.updateSelected();\n        this.trigger(checked ? 'check-some' : 'uncheck-some', rows);\n    };\n\n    BootstrapTable.prototype.destroy = function () {\n        this.$el.insertBefore(this.$container);\n        $(this.options.toolbar).insertBefore(this.$el);\n        this.$container.next().remove();\n        this.$container.remove();\n        this.$el.html(this.$el_.html())\n            .css('margin-top', '0')\n            .attr('class', this.$el_.attr('class') || ''); // reset the class\n    };\n\n    BootstrapTable.prototype.showLoading = function () {\n        this.$tableLoading.show();\n    };\n\n    BootstrapTable.prototype.hideLoading = function () {\n        this.$tableLoading.hide();\n    };\n\n    BootstrapTable.prototype.togglePagination = function () {\n        this.options.pagination = !this.options.pagination;\n        var button = this.$toolbar.find('button[name=\"paginationSwitch\"] i');\n        if (this.options.pagination) {\n            button.attr(\"class\", this.options.iconsPrefix + \" \" + this.options.icons.paginationSwitchDown);\n        } else {\n            button.attr(\"class\", this.options.iconsPrefix + \" \" + this.options.icons.paginationSwitchUp);\n        }\n        this.updatePagination();\n    };\n\n    BootstrapTable.prototype.refresh = function (params) {\n        if (params && params.url) {\n            this.options.url = params.url;\n            this.options.pageNumber = 1;\n        }\n        this.initServer(params && params.silent, params && params.query);\n    };\n\n    BootstrapTable.prototype.resetWidth = function () {\n        if (this.options.showHeader && this.options.height) {\n            this.fitHeader();\n        }\n        if (this.options.showFooter) {\n            this.fitFooter();\n        }\n    };\n\n    BootstrapTable.prototype.showColumn = function (field) {\n        this.toggleColumn(getFieldIndex(this.options.columns, field), true, true);\n    };\n\n    BootstrapTable.prototype.hideColumn = function (field) {\n        this.toggleColumn(getFieldIndex(this.options.columns, field), false, true);\n    };\n\n    BootstrapTable.prototype.filterBy = function (columns) {\n        this.filterColumns = $.isEmptyObject(columns) ? {} : columns;\n        this.options.pageNumber = 1;\n        this.initSearch();\n        this.updatePagination();\n    };\n\n    BootstrapTable.prototype.scrollTo = function (value) {\n        if (typeof value === 'string') {\n            value = value === 'bottom' ? this.$tableBody[0].scrollHeight : 0;\n        }\n        if (typeof value === 'number') {\n            this.$tableBody.scrollTop(value);\n        }\n        if (typeof value === 'undefined') {\n            return this.$tableBody.scrollTop();\n        }\n    };\n\n    BootstrapTable.prototype.getScrollPosition = function () {\n        return this.scrollTo();\n    }\n\n    BootstrapTable.prototype.selectPage = function (page) {\n        if (page > 0 && page <= this.options.totalPages) {\n            this.options.pageNumber = page;\n            this.updatePagination();\n        }\n    };\n\n    BootstrapTable.prototype.prevPage = function () {\n        if (this.options.pageNumber > 1) {\n            this.options.pageNumber--;\n            this.updatePagination();\n        }\n    };\n\n    BootstrapTable.prototype.nextPage = function () {\n        if (this.options.pageNumber < this.options.totalPages) {\n            this.options.pageNumber++;\n            this.updatePagination();\n        }\n    };\n\n    BootstrapTable.prototype.toggleView = function () {\n        this.options.cardView = !this.options.cardView;\n        this.initHeader();\n        // Fixed remove toolbar when click cardView button.\n        //that.initToolbar();\n        this.initBody();\n        this.trigger('toggle', this.options.cardView);\n    };\n\n    // BOOTSTRAP TABLE PLUGIN DEFINITION\n    // =======================\n\n    var allowedMethods = [\n        'getOptions',\n        'getSelections', 'getAllSelections', 'getData',\n        'load', 'append', 'prepend', 'remove', 'removeAll',\n        'insertRow', 'updateRow', 'updateCell', 'removeByUniqueId',\n        'showRow', 'hideRow', 'getRowsHidden',\n        'mergeCells',\n        'checkAll', 'uncheckAll',\n        'check', 'uncheck',\n        'checkBy', 'uncheckBy',\n        'refresh',\n        'resetView',\n        'resetWidth',\n        'destroy',\n        'showLoading', 'hideLoading',\n        'showColumn', 'hideColumn',\n        'filterBy',\n        'scrollTo',\n        'getScrollPosition',\n        'selectPage', 'prevPage', 'nextPage',\n        'togglePagination',\n        'toggleView'\n    ];\n\n    $.fn.bootstrapTable = function (option) {\n        var value,\n            args = Array.prototype.slice.call(arguments, 1);\n\n        this.each(function () {\n            var $this = $(this),\n                data = $this.data('bootstrap.table'),\n                options = $.extend({}, BootstrapTable.DEFAULTS, $this.data(),\n                    typeof option === 'object' && option);\n\n            if (typeof option === 'string') {\n                if ($.inArray(option, allowedMethods) < 0) {\n                    throw new Error(\"Unknown method: \" + option);\n                }\n\n                if (!data) {\n                    return;\n                }\n\n                value = data[option].apply(data, args);\n\n                if (option === 'destroy') {\n                    $this.removeData('bootstrap.table');\n                }\n            }\n\n            if (!data) {\n                $this.data('bootstrap.table', (data = new BootstrapTable(this, options)));\n            }\n        });\n\n        return typeof value === 'undefined' ? this : value;\n    };\n\n    $.fn.bootstrapTable.Constructor = BootstrapTable;\n    $.fn.bootstrapTable.defaults = BootstrapTable.DEFAULTS;\n    $.fn.bootstrapTable.columnDefaults = BootstrapTable.COLUMN_DEFAULTS;\n    $.fn.bootstrapTable.locales = BootstrapTable.LOCALES;\n    $.fn.bootstrapTable.methods = allowedMethods;\n\n    // BOOTSTRAP TABLE INIT\n    // =======================\n\n    $(function () {\n        $('[data-toggle=\"table\"]').bootstrapTable();\n    });\n\n}(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/cookie/README.md",
    "content": "# Table Cookie\n\nUse Plugin: [bootstrap-table-cookie](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/cookie)\n\n## Usage\n\n```html\n<script src=\"extensions/cookie/bootstrap-table-cookie.js\"></script>\n```\n\n## Options\n\n### stateSave\n\n* type: Boolean\n* description: Set true to save the state of a table (its paging position, ordering state, records per page).\n* default: `false`\n\n### stateSaveExpire\n\n* type: String\n* description: You must set this property if stateSave is enable to know when will expire the cookie created. Must use this format: 'number{letter}' like '2h', in the letter position\n               \t\tyou can use: 's','mi','h','d','m','y', these means: 'seconds', 'minutes', 'hours', 'days', 'months', 'years'.\n* default: `2h`\n\n### stateSaveIdTable\n\n* type: String\n* description: You must set this property if stateSave is enable to sets an unique cookie with an identifier for each table in your page or project. You must set this property because we need create cookies with an identifier.\n* default: ``\n\n## This plugin saves\n\n* Sort order\n* Page number\n* Page number from the list\n* Visible columns\n* Search text"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/cookie/bootstrap-table-cookie.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.1.0\n *\n * @update zhixin wen <wenzhixin2010@gmail.com>\n */\n\n(function ($) {\n    'use strict';\n\n    var idsStateSaveList = {\n        sortOrder: 'bs.table.sortOrder',\n        sortName: 'bs.table.sortName',\n        pageNumber: 'bs.table.pageNumber',\n        pageList: 'bs.table.pageList',\n        columns: 'bs.table.columns',\n        searchText: 'bs.table.searchText'\n    };\n\n    var cookieEnabled = function () {\n        return (navigator.cookieEnabled) ? true : false;\n    };\n\n    var setCookie = function (that, cookieName, sValue, sPath, sDomain, bSecure) {\n        if ((!that.options.stateSave) || (!cookieEnabled()) || (that.options.stateSaveIdTable === '')) {\n            return;\n        }\n\n        var tableName = that.options.stateSaveIdTable,\n            vEnd = that.options.stateSaveExpire;\n\n        cookieName = tableName + '.' + cookieName;\n        if (!cookieName || /^(?:expires|max\\-age|path|domain|secure)$/i.test(cookieName)) {\n            return false;\n        }\n\n        document.cookie = encodeURIComponent(cookieName) + '=' + encodeURIComponent(sValue) + calculateExpiration(vEnd) + (sDomain ? '; domain=' + sDomain : '') + (sPath ? '; path=' + sPath : '') + (bSecure ? '; secure' : '');\n        return true;\n    };\n\n    var getCookie = function (tableName, cookieName) {\n        cookieName = tableName + '.' + cookieName;\n        if (!cookieName) {\n            return null;\n        }\n        return decodeURIComponent(document.cookie.replace(new RegExp('(?:(?:^|.*;)\\\\s*' + encodeURIComponent(cookieName).replace(/[\\-\\.\\+\\*]/g, '\\\\$&') + '\\\\s*\\\\=\\\\s*([^;]*).*$)|^.*$'), '$1')) || null;\n    };\n\n    var hasCookie = function (cookieName) {\n        if (!cookieName) {\n            return false;\n        }\n        return (new RegExp('(?:^|;\\\\s*)' + encodeURIComponent(cookieName).replace(/[\\-\\.\\+\\*]/g, '\\\\$&') + '\\\\s*\\\\=')).test(document.cookie);\n    };\n\n    var deleteCookie = function (tableName, cookieName, sPath, sDomain) {\n        cookieName = tableName + '.' + cookieName;\n        if (!hasCookie(cookieName)) {\n            return false;\n        }\n        document.cookie = encodeURIComponent(cookieName) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT' + (sDomain ? '; domain=' + sDomain : '') + (sPath ? '; path=' + sPath : '');\n        return true;\n    };\n\n    var calculateExpiration = function(vEnd) {\n        var time = vEnd.replace(/[0-9]/, ''); //s,mi,h,d,m,y\n        vEnd = vEnd.replace(/[A-Za-z]/, ''); //number\n\n        switch (time.toLowerCase()) {\n            case 's':\n                vEnd = +vEnd;\n                break;\n            case 'mi':\n                vEnd = vEnd * 60;\n                break;\n            case 'h':\n                vEnd = vEnd * 60 * 60;\n                break;\n            case 'd':\n                vEnd = vEnd * 24 * 60 * 60;\n                break;\n            case 'm':\n                vEnd = vEnd * 30 * 24 * 60 * 60;\n                break;\n            case 'y':\n                vEnd = vEnd * 365 * 30 * 24 * 60 * 60;\n                break;\n            default:\n                vEnd = undefined;\n                break;\n        }\n\n        return vEnd === undefined ? '' : '; max-age=' + vEnd;\n    }\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        stateSave: false,\n        stateSaveExpire: '2h',\n        stateSaveIdTable: ''\n    });\n\n    $.fn.bootstrapTable.methods.push('deleteCookie');\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initTable = BootstrapTable.prototype.initTable,\n        _onSort = BootstrapTable.prototype.onSort,\n        _onPageNumber = BootstrapTable.prototype.onPageNumber,\n        _onPageListChange = BootstrapTable.prototype.onPageListChange,\n        _onPageFirst = BootstrapTable.prototype.onPageFirst,\n        _onPagePre = BootstrapTable.prototype.onPagePre,\n        _onPageNext = BootstrapTable.prototype.onPageNext,\n        _onPageLast = BootstrapTable.prototype.onPageLast,\n        _toggleColumn = BootstrapTable.prototype.toggleColumn,\n        _onSearch = BootstrapTable.prototype.onSearch;\n\n    // init save data after initTable function\n    BootstrapTable.prototype.initTable = function () {\n        _initTable.apply(this, Array.prototype.slice.apply(arguments));\n        this.initStateSave();\n    };\n\n    BootstrapTable.prototype.initStateSave = function () {\n        if (!this.options.stateSave) {\n            return;\n        }\n\n        if (!cookieEnabled()) {\n            return;\n        }\n\n        if (this.options.stateSaveIdTable === '') {\n            return;\n        }\n\n        var sortOrderStateSave = getCookie(this.options.stateSaveIdTable, idsStateSaveList.sortOrder),\n            sortOrderStateName = getCookie(this.options.stateSaveIdTable, idsStateSaveList.sortName),\n            pageNumberStateSave = getCookie(this.options.stateSaveIdTable, idsStateSaveList.pageNumber),\n            pageListStateSave = getCookie(this.options.stateSaveIdTable, idsStateSaveList.pageList),\n            columnsStateSave = JSON.parse(getCookie(this.options.stateSaveIdTable, idsStateSaveList.columns)),\n            searchStateSave = getCookie(this.options.stateSaveIdTable, idsStateSaveList.searchText);\n\n        if (sortOrderStateSave) {\n            this.options.sortOrder = sortOrderStateSave;\n            this.options.sortName = sortOrderStateName;\n        }\n\n        if (pageNumberStateSave) {\n            this.options.pageNumber = +pageNumberStateSave;\n        }\n\n        if (pageListStateSave) {\n            this.options.pageSize = pageListStateSave ===\n                this.options.formatAllRows() ? pageListStateSave : +pageListStateSave;\n        }\n\n        if (columnsStateSave) {\n            $.each(this.options.columns, function (i, column) {\n                column.visible = columnsStateSave.indexOf(i) !== -1;\n            });\n        }\n\n        if (searchStateSave) {\n            this.options.searchText = searchStateSave;\n        }\n    };\n\n    BootstrapTable.prototype.onSort = function () {\n        _onSort.apply(this, Array.prototype.slice.apply(arguments));\n\n        setCookie(this, idsStateSaveList.sortOrder, this.options.sortOrder);\n        setCookie(this, idsStateSaveList.sortName, this.options.sortName);\n    };\n\n    BootstrapTable.prototype.onPageNumber = function () {\n        _onPageNumber.apply(this, Array.prototype.slice.apply(arguments));\n\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.onPageListChange = function () {\n        _onPageListChange.apply(this, Array.prototype.slice.apply(arguments));\n\n        setCookie(this, idsStateSaveList.pageList, this.options.pageSize);\n    };\n\n    BootstrapTable.prototype.onPageFirst = function () {\n        _onPageFirst.apply(this, Array.prototype.slice.apply(arguments));\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.onPagePre = function () {\n        _onPagePre.apply(this, Array.prototype.slice.apply(arguments));\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.onPageNext = function () {\n        _onPageNext.apply(this, Array.prototype.slice.apply(arguments));\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.onPageLast = function () {\n        _onPageLast.apply(this, Array.prototype.slice.apply(arguments));\n        setCookie(this, idsStateSaveList.pageNumber, this.options.pageNumber);\n    };\n\n    BootstrapTable.prototype.toggleColumn = function () {\n        _toggleColumn.apply(this, Array.prototype.slice.apply(arguments));\n\n        var visibleColumns = [];\n\n        $.each(this.options.columns, function (i) {\n            if (this.visible) {\n                visibleColumns.push(i);\n            }\n        });\n\n        setCookie(this, idsStateSaveList.columns, JSON.stringify(visibleColumns));\n    };\n\n    BootstrapTable.prototype.onSearch = function () {\n        _onSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        setCookie(this, idsStateSaveList.searchText, this.searchText);\n    };\n\n    BootstrapTable.prototype.deleteCookie = function (cookieName) {\n        if ((cookieName === '') || (!cookieEnabled())) {\n            return;\n        }\n\n        deleteCookie(idsStateSaveList[cookieName]);\n    };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/editable/README.md",
    "content": "# Table Editable\n\nUse Plugin: [x-editable](https://github.com/vitalets/x-editable)\n\n## Usage\n\n```html\n<script src=\"extensions/editable/bootstrap-table-editable.js\"></script>\n```\n\n## Options\n\n### editable\n\n* type: Boolean\n* description: Set false to disabled editable of all columns.\n* default: `true`\n\n## Column options\n\n### editable\n\n* type: Object\n* description: Configuration of x-editable. Full list of options: http://vitalets.github.io/x-editable/docs.html#editable\n* default: `undefined`\n\n## Events\n\n### onEditableInit(editable-init.bs.table)\n\nFired when all columns was initialized by `$().editable()` method.\n\n### onEditableSave(editable-save.bs.table)\n\nFired when an editable cell is saved.\n\n## The existing problems\n\n* Editable extension does not support searchable in the select type.\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/editable/bootstrap-table-editable.js",
    "content": "/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * extensions: https://github.com/vitalets/x-editable\n */\n\n!function ($) {\n\n    'use strict';\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        editable: true,\n        onEditableInit: function () {\n            return false;\n        },\n        onEditableSave: function (field, row, oldValue, $el) {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'editable-init.bs.table': 'onEditableInit',\n        'editable-save.bs.table': 'onEditableSave'\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initTable = BootstrapTable.prototype.initTable,\n        _initBody = BootstrapTable.prototype.initBody;\n\n    BootstrapTable.prototype.initTable = function () {\n        var that = this;\n        _initTable.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.editable) {\n            return;\n        }\n\n        $.each(this.options.columns, function (i, column) {\n            if (!column.editable) {\n                return;\n            }\n\n            var _formatter = column.formatter;\n            column.formatter = function (value, row, index) {\n                var result = _formatter ? _formatter(value, row, index) : value;\n\n                return ['<a href=\"javascript:void(0)\"',\n                    ' data-name=\"' + column.field + '\"',\n                    ' data-pk=\"' + row[that.options.idField] + '\"',\n                    ' data-value=\"' + result + '\"',\n                    '>' + '</a>'\n                ].join('');\n            };\n        });\n    };\n\n    BootstrapTable.prototype.initBody = function () {\n        var that = this;\n        _initBody.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.editable) {\n            return;\n        }\n\n        $.each(this.options.columns, function (i, column) {\n            if (!column.editable) {\n                return;\n            }\n\n            that.$body.find('a[data-name=\"' + column.field + '\"]').editable(column.editable)\n                .off('save').on('save', function (e, params) {\n                    var data = that.getData(),\n                        index = $(this).parents('tr[data-index]').data('index'),\n                        row = data[index],\n                        oldValue = row[column.field];\n\n                    row[column.field] = params.submitValue;\n                    that.trigger('editable-save', column.field, row, oldValue, $(this));\n                });\n        });\n        this.trigger('editable-init');\n    };\n\n}(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/export/README.md",
    "content": "# Table Export\n\nUse Plugin: [tableExport.jquery.plugin](https://github.com/hhurz/tableExport.jquery.plugin)\n\n## Usage\n\n```html\n<script src=\"extensions/export/bootstrap-table-export.js\"></script>\n```\n\n## Options\n\n### showExport\n\n* type: Boolean\n* description: set `true` to show export button.\n* default: `false`\n\n### exportTypes\n\n* type: Array\n* description: export types, support types: 'json', 'xml', 'png', 'csv', 'txt', 'sql', 'doc', 'excel', 'powerpoint', 'pdf'.\n* default: `['json', 'xml', 'csv', 'txt', 'sql', 'excel']`\n\n### exportOptions\n\n* type: Object\n* description: export [options](https://github.com/hhurz/tableExport.jquery.plugin#options) of `tableExport.jquery.plugin`\n* default: `{}`\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/export/bootstrap-table-export.js",
    "content": "/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * extensions: https://github.com/kayalshri/tableExport.jquery.plugin\n */\n\n(function ($) {\n    'use strict';\n\n    var TYPE_NAME = {\n        json: 'JSON',\n        xml: 'XML',\n        png: 'PNG',\n        csv: 'CSV',\n        txt: 'TXT',\n        sql: 'SQL',\n        doc: 'MS-Word',\n        excel: 'Ms-Excel',\n        powerpoint: 'Ms-Powerpoint',\n        pdf: 'PDF'\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        showExport: false,\n        // 'json', 'xml', 'png', 'csv', 'txt', 'sql', 'doc', 'excel', 'powerpoint', 'pdf'\n        exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'],\n        exportOptions: {}\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initToolbar = BootstrapTable.prototype.initToolbar;\n\n    BootstrapTable.prototype.initToolbar = function () {\n        this.showToolbar = this.options.showExport;\n\n        _initToolbar.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.showExport) {\n            var that = this,\n                $btnGroup = this.$toolbar.find('>.btn-group'),\n                $export = $btnGroup.find('div.export');\n\n            if (!$export.length) {\n                $export = $([\n                    '<div class=\"export btn-group\">',\n                        '<button class=\"btn btn-default dropdown-toggle\" ' +\n                            'data-toggle=\"dropdown\" type=\"button\">',\n                            '<i class=\"glyphicon glyphicon-export icon-share\"></i> ',\n                            '<span class=\"caret\"></span>',\n                        '</button>',\n                        '<ul class=\"dropdown-menu\" role=\"menu\">',\n                        '</ul>',\n                    '</div>'].join('')).appendTo($btnGroup);\n\n                var $menu = $export.find('.dropdown-menu'),\n                    exportTypes = this.options.exportTypes;\n\n                if (typeof this.options.exportTypes === 'string') {\n                    var types = this.options.exportTypes.slice(1, -1).replace(/ /g, '').split(',');\n\n                    exportTypes = [];\n                    $.each(types, function (i, value) {\n                        exportTypes.push(value.slice(1, -1));\n                    });\n                }\n                $.each(exportTypes, function (i, type) {\n                    if (TYPE_NAME.hasOwnProperty(type)) {\n                        $menu.append(['<li data-type=\"' + type + '\">',\n                                '<a href=\"javascript:void(0)\">',\n                                    TYPE_NAME[type],\n                                '</a>',\n                            '</li>'].join(''));\n                    }\n                });\n\n                $menu.find('li').click(function () {\n                    that.$el.tableExport($.extend({}, that.options.exportOptions, {\n                        type: $(this).data('type'),\n                        escape: false\n                    }));\n                });\n            }\n        }\n    };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/filter/README.md",
    "content": "# Table Filter\n\nUse Plugin: [bootstrap table filters](https://github.com/lukaskral/bootstrap-table-filter)\n\n## Usage\n\n```html\n<script src=\"extensions/filter/bootstrap-table-filter.js\"></script>\n```\n\n## Options\n\n### showFilter\n\n* type: Boolean\n* description: set true to show filter menu.\n* default: `false`\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/filter/bootstrap-table-filter.js",
    "content": "/**\n * @author zhixin wen <wenzhixin2010@gmail.com>\n * extensions: https://github.com/lukaskral/bootstrap-table-filter\n */\n\n!function($) {\n\n    'use strict';\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        showFilter: false\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _init = BootstrapTable.prototype.init,\n        _initSearch = BootstrapTable.prototype.initSearch;\n\n    BootstrapTable.prototype.init = function () {\n        _init.apply(this, Array.prototype.slice.apply(arguments));\n\n        var that = this;\n        this.$el.on('load-success.bs.table', function () {\n            if (that.options.showFilter) {\n                $(that.options.toolbar).bootstrapTableFilter({\n                    connectTo: that.$el\n                });\n            }\n        });\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        _initSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.sidePagination !== 'server') {\n            if (typeof this.searchCallback === 'function') {\n                this.data = $.grep(this.options.data, this.searchCallback);\n            }\n        }\n    };\n\n    BootstrapTable.prototype.getData = function () {\n        return (this.searchText || this.searchCallback) ? this.data : this.options.data;\n    };\n\n    BootstrapTable.prototype.getColumns = function () {\n        return this.options.columns;\n    };\n\n    BootstrapTable.prototype.registerSearchCallback = function (callback) {\n        this.searchCallback = callback;\n    };\n\n    BootstrapTable.prototype.updateSearch = function () {\n        this.options.pageNumber = 1;\n        this.initSearch();\n        this.updatePagination();\n    };\n\n    BootstrapTable.prototype.getServerUrl = function () {\n        return (this.options.sidePagination === 'server') ? this.options.url : false;\n    };\n\n    $.fn.bootstrapTable.methods.push('getColumns',\n        'registerSearchCallback', 'updateSearch',\n        'getServerUrl');\n\n}(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/filter-control/README.md",
    "content": "# Table Filter Control\n\nUse Plugin: [bootstrap-table-filter-control](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/filter-control)\n\n## Usage\n\n```html\n<script src=\"extensions/filter-control/bootstrap-table-filter-control.js\"></script>\n```\n\n## Options\n\n### filterControl\n\n* type: Boolean\n* description: Set true to add an `input` or `select` into the column.\n* default: `false`\n\n## Column options\n\n### filterControl\n\n* type: String\n* description: Set `input` or `select` to add one of those element into column.\n* default: `undefined`\n\n## Events\n\n### onColumnSearch(column-search.bs.table)\n\n* Fired when we are searching into the column data"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/filter-control/bootstrap-table-filter-control.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.0.0\n */\n\n!function ($) {\n\n    'use strict';\n\n    var sprintf = function (str) {\n        var args = arguments,\n            flag = true,\n            i = 1;\n\n        str = str.replace(/%s/g, function () {\n            var arg = args[i++];\n\n            if (typeof arg === 'undefined') {\n                flag = false;\n                return '';\n            }\n            return arg;\n        });\n        return flag ? str : '';\n    };\n\n    var getFieldIndex = function (columns, field) {\n        var index = -1;\n\n        $.each(columns, function (i, column) {\n            if (column.field === field) {\n                index = i;\n                return false;\n            }\n            return true;\n        });\n        return index;\n    };\n\n    var calculateObjectValue = function (self, name, args, defaultValue) {\n        if (typeof name === 'string') {\n            // support obj.func1.func2\n            var names = name.split('.');\n\n            if (names.length > 1) {\n                name = window;\n                $.each(names, function (i, f) {\n                    name = name[f];\n                });\n            } else {\n                name = window[name];\n            }\n        }\n        if (typeof name === 'object') {\n            return name;\n        }\n        if (typeof name === 'function') {\n            return name.apply(self, args);\n        }\n        return defaultValue;\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        filterControl: false,\n        onColumnSearch: function (field, text) {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {\n        filterControl: undefined,\n        filterData: undefined\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'column-search.bs.table': 'onColumnSearch'\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initHeader = BootstrapTable.prototype.initHeader,\n        _initBody = BootstrapTable.prototype.initBody,\n        _initSearch = BootstrapTable.prototype.initSearch;\n\n    BootstrapTable.prototype.initHeader = function () {\n        _initHeader.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.filterControl) {\n            return;\n        }\n\n        var addedFilterControl = false,\n            that = this,\n            isVisible,\n            html,\n            timeoutId = 0;\n\n        $.each(this.options.columns, function (i, column) {\n            isVisible = 'hidden';\n            html = [];\n\n            if (!column.visible) {\n                return;\n            }\n\n            if (!column.filterControl) {\n                html.push('<div style=\"height: 34px;\"></div>');\n            } else {\n                html.push('<div style=\"margin: 0px 2px 2px 2px;\" class=\"filterControl\">');\n\n                if (column.filterControl && column.searchable) {\n                    addedFilterControl = true;\n                    isVisible = 'visible'\n                }\n                switch (column.filterControl.toLowerCase()) {\n                    case 'input' :\n                        html.push(sprintf('<input type=\"text\" class=\"form-control\" style=\"width: 100%; visibility: %s\">', isVisible));\n                        break;\n                    case 'select':\n                        html.push(sprintf('<select class=\"%s form-control\" style=\"width: 100%; visibility: %s\"></select>',\n                            column.field, isVisible))\n                        break;\n                }\n            }\n\n            that.$header.find(sprintf('.th-inner:eq(\"%s\")', i)).next().append(html.join(''));\n            if (column.filterData !== undefined && column.filterData.toLowerCase() !== 'column') {\n                var filterDataType = column.filterData.substring(0, 3);\n                var filterDataSource = column.filterData.substring(4, column.filterData.length);\n                var selectControl = $('.' + column.field);\n                selectControl.append($(\"<option></option>\")\n                    .attr(\"value\", '')\n                    .text(''));\n                switch (filterDataType) {\n                    case 'url':\n                        $.ajax({\n                            url: filterDataSource,\n                            dataType: 'json',\n                            success: function (data) {\n                                $.each(data, function (key, value) {\n                                    selectControl.append($(\"<option></option>\")\n                                        .attr(\"value\", key)\n                                        .text(value));\n                                });\n                            }\n                        });\n                        break;\n                    case 'var':\n                        var variableValues = window[filterDataSource];\n                        for (var key in variableValues) {\n                            selectControl.append($(\"<option></option>\")\n                                .attr(\"value\", key)\n                                .text(variableValues[key]));\n                        };\n                        break;\n                }\n            }\n        });\n\n        if (addedFilterControl) {\n            this.$header.off('keyup', 'input').on('keyup', 'input', function (event) {\n                clearTimeout(timeoutId);\n                timeoutId = setTimeout(function () {\n                    that.onColumnSearch(event);\n                }, that.options.searchTimeOut);\n            });\n\n            this.$header.off('change', 'select').on('change', 'select', function (event) {\n                clearTimeout(timeoutId);\n                timeoutId = setTimeout(function () {\n                    that.onColumnSearch(event);\n                }, that.options.searchTimeOut);\n            });\n        } else {\n            this.$header.find('.filterControl').hide();\n        }\n    };\n\n    BootstrapTable.prototype.initBody = function () {\n        _initBody.apply(this, Array.prototype.slice.apply(arguments));\n\n        var that = this,\n            data = this.getData();\n\n        for (var i = this.pageFrom - 1; i < this.pageTo; i++) {\n            var key,\n                item = data[i];\n\n            $.each(this.header.fields, function (j, field) {\n                var value = item[field],\n                    column = that.options.columns[getFieldIndex(that.options.columns, field)];\n\n                value = calculateObjectValue(that.header,\n                    that.header.formatters[j], [value, item, i], value);\n\n                if ((!column.checkbox) || (!column.radio)) {\n                    if (column.filterControl !== undefined && column.filterControl.toLowerCase() === 'select'\n                            && column.searchable) {\n\n                        if (column.filterData === undefined || column.filterData.toLowerCase() === 'column') {\n                            var selectControl = $('.' + column.field),\n                                    iOpt = 0,\n                                    exitsOpt = false,\n                                    options;\n                            if (selectControl !== undefined) {\n                                options = selectControl.get(0).options;\n\n                                if (options.length === 0) {\n\n                                    //Added the default option\n                                    selectControl.append($(\"<option></option>\")\n                                        .attr(\"value\", '')\n                                        .text(''));\n\n                                    selectControl.append($(\"<option></option>\")\n                                        .attr(\"value\", value)\n                                        .text(value));\n                                } else {\n                                    for (; iOpt < options.length; iOpt++) {\n                                        if (options[iOpt].value === value) {\n                                            exitsOpt = true;\n                                            break;\n                                        }\n                                    }\n\n                                    if (!exitsOpt) {\n                                        selectControl.append($(\"<option></option>\")\n                                            .attr(\"value\", value)\n                                            .text(value));\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            });\n        }\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        _initSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        var that = this;\n        var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial;\n\n        //Check partial column filter\n        this.data = fp ? $.grep(this.data, function (item, i) {\n            for (var key in fp) {\n                var fval = fp[key].toLowerCase();\n                var value = item[key];\n                value = calculateObjectValue(that.header,\n                    that.header.formatters[$.inArray(key, that.header.fields)],\n                    [value, item, i], value);\n\n                if (!($.inArray(key, that.header.fields) !== -1 &&\n                    (typeof value === 'string' || typeof value === 'number') &&\n                    (value + '').toLowerCase().indexOf(fval) !== -1)) {\n                    return false;\n                }\n            }\n            return true;\n        }) : this.data;\n    };\n\n    BootstrapTable.prototype.onColumnSearch = function (event) {\n        var text = $.trim($(event.currentTarget).val());\n        var $field = $(event.currentTarget).parent().parent().parent().data('field')\n\n        if ($.isEmptyObject(this.filterColumnsPartial)) {\n            this.filterColumnsPartial = {};\n        }\n        if (text) {\n            this.filterColumnsPartial[$field] = text;\n        } else {\n            delete this.filterColumnsPartial[$field];\n        }\n\n        this.options.pageNumber = 1;\n        this.onSearch(event);\n        this.updatePagination();\n        this.trigger('column-search', $field, text);\n    };\n}(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/flat-json/README.md",
    "content": "# Table flat-json\n\nUse Plugin: [bootstrap-table-flat-json](https://github.com/djhvscf/bootstrap-table-flat-json)\n\n## Usage\n\n```html\n<script src=\"extensions/flat-json/bootstrap-table-flat-json.js\"></script>\n```\n\n## Options\n\n### flat\n\n* type: Boolean\n* description: Set true to flat the JSON object.\n* default: `false`\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/flat-json/bootstrap-table-flat-json.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.2.0\n */\n\n\n(function ($) {\n    'use strict';\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        flat: false\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initData = BootstrapTable.prototype.initData;\n\n    BootstrapTable.prototype.initData = function (data, type) {\n        if( this.options.flat ){\n            data = data === undefined ? this.options.data : data;\n            data = sd.flatHelper(data);\n        }\n        _initData.apply(this, [data, type]);\n    };\n\n    //Main functions\n    var sd = {\n        flat: function (element) {\n            var result = {};\n\n            function recurse(cur, prop) {\n                if (Object(cur) !== cur) {\n                    result[prop] = cur;\n                } else if ($.isArray(cur)) {\n                    for (var i = 0, l = cur.length; i < l; i++) {\n                        recurse(cur[i], prop ? prop + \".\" + i : \"\" + i);\n                        if (l == 0) {\n                            result[prop] = [];\n                        }\n                    }\n                } else {\n                    var isEmpty = true;\n                    for (var p in cur) {\n                        isEmpty = false;\n                        recurse(cur[p], prop ? prop + \".\" + p : p);\n                    }\n                    if (isEmpty) {\n                        result[prop] = {};\n                    }\n                }\n            }\n\n            recurse(element, \"\");\n            return result;\n        },\n\n        flatHelper: function (data) {\n            var flatArray = [],\n                arrayHelper = [];\n            if (!$.isArray(data)) {\n                arrayHelper.push(data);\n                data = arrayHelper;\n            }\n            $.each(data, function (i, element) {\n                flatArray.push(sd.flat(element));\n            });\n            return flatArray;\n        }\n    };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/key-events/README.md",
    "content": "# Table Key Events\n\nUse Plugin: [bootstrap-table-key-events](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/key-events)\n\n## Usage\n\n```html\n<script src=\"extensions/cookie/bootstrap-table-key-events.js\"></script>\n```\n\n## Options\n\n### keyEvents\n\n* type: Boolean\n* description:\nTrue to enable the key events. The key event list is:\n    * s: It will be focused the search textbox if it is enabled.\n    * r: It will refresh the table if the showRefresh option is enabled.\n    * t: It will toggle the table view if the showToggle option is enabled.\n    * p: It will fires the pagination switch if the showPaginationSwitch is enabled.\n    * left: It will go to prev page if the pagination is true.\n    * right: It will go to next page if the pagination is true.\n* default: `false`\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/key-events/bootstrap-table-key-events.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.0.0\n *\n * @update zhixin wen <wenzhixin2010@gmail.com>\n */\n\n!function ($) {\n\n    'use strict';\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        keyEvents: false\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _init = BootstrapTable.prototype.init;\n\n    BootstrapTable.prototype.init = function () {\n        _init.apply(this, Array.prototype.slice.apply(arguments));\n\n        this.initKeyEvents();\n    };\n\n    BootstrapTable.prototype.initKeyEvents = function () {\n        if (this.options.keyEvents) {\n            var that = this;\n\n            $(document).off('keydown').on('keydown', function (e) {\n                var $search = that.$toolbar.find('.search input'),\n                    $refresh = that.$toolbar.find('button[name=\"refresh\"]'),\n                    $toggle = that.$toolbar.find('button[name=\"toggle\"]'),\n                    $paginationSwitch = that.$toolbar.find('button[name=\"paginationSwitch\"]');\n\n                if (document.activeElement === $search.get(0)) {\n                    return true;\n                }\n\n                switch (e.keyCode) {\n                    case 83: //s\n                        if (!that.options.search) {\n                            return;\n                        }\n                        $search.focus();\n                        return false;\n                    case 82: //r\n                        if (!that.options.showRefresh) {\n                            return;\n                        }\n                        $refresh.click();\n                        return false;\n                    case 84: //t\n                        if (!that.options.showToggle) {\n                            return;\n                        }\n                        $toggle.click();\n                        return false;\n                    case 80: //p\n                        if (!that.options.showPaginationSwitch) {\n                            return;\n                        }\n                        $paginationSwitch.click();\n                        return false;\n                    case 37: // left\n                        if (!that.options.pagination) {\n                            return;\n                        }\n                        that.prevPage();\n                        return false;\n                    case 39: // right\n                        if (!that.options.pagination) {\n                            return;\n                        }\n                        that.nextPage();\n                        return;\n                }\n            });\n        }\n    };\n}(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/mobile/README.md",
    "content": "# Table Mobile\n\nUse Plugin: [bootstrap-table-mobile](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/mobile)\n\n## Usage\n\n```html\n<script src=\"extensions/mobile/bootstrap-table-mobile.js\"></script>\n```\n\n## Options\n\n### mobileResponsive\n\n* type: Boolean\n* description: Set true to change the view between card and table view depending on width and height given.\n* default: `false`\n\n### checkOnInit\n\n* type: Boolean\n* description: Set true to check the window size on init.\n* default: `true`\n\n### minWidth\n\n* type: Integer\n* description: Set the minimum width when the table will change the view.\n* default: `562`\n\n### minHeight\n\n* type: Integer\n* description: Set the minimum height when the table will change the view.\n* default: `undefined`\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/mobile/bootstrap-table-mobile.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.1.0\n */\n\n!function ($) {\n\n    'use strict';\n\n    var resetView = function (that) {\n        if (that.options.height || that.options.showFooter) {\n            setTimeout(that.resetView(), 1);\n        }\n    };\n\n    var changeView = function (that, width, height) {\n        if (that.options.minHeight) {\n            if (checkValuesLessEqual(width, that.options.minWidth) && checkValuesLessEqual(height, that.options.minHeight)) {\n                conditionCardView(that);\n            } else if (checkValuesGreater(width, that.options.minWidth) && checkValuesGreater(height, that.options.minHeight)) {\n                conditionFullView(that);\n            }\n        } else {\n            if (checkValuesLessEqual(width, that.options.minWidth)) {\n                conditionCardView(that);\n            } else if (checkValuesGreater(width, that.options.minWidth)) {\n                conditionFullView(that);\n            }\n        }\n\n        resetView(that);\n    };\n\n    var checkValuesLessEqual = function (currentValue, targetValue) {\n        return currentValue <= targetValue;\n    };\n\n    var checkValuesGreater = function (currentValue, targetValue) {\n        return currentValue > targetValue;\n    };\n\n    var conditionCardView = function (that) {\n        changeTableView(that, false);\n    };\n\n    var conditionFullView = function (that) {\n        changeTableView(that, true);\n    };\n\n    var changeTableView = function (that, cardViewState) {\n        that.options.cardView = cardViewState;\n        that.toggleView();\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        mobileResponsive: false,\n        minWidth: 562,\n        minHeight: undefined,\n        checkOnInit: true,\n        toggled: false\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _init = BootstrapTable.prototype.init;\n\n    BootstrapTable.prototype.init = function () {\n        _init.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.mobileResponsive) {\n            return;\n        }\n\n        if (!this.options.minWidth) {\n            return;\n        }\n\n        var that = this;\n        $(window).resize(function () {\n            changeView(that, $(this).width(), $(this).height())\n        });\n\n        if (this.options.checkOnInit) {\n            changeView(this, $(window).width(), $(window).height());\n        }\n    };\n}(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/multiple-sort/README.md",
    "content": "# Table Multiple Sort\n\nUse Plugin: [bootstrap-table-multiple-sort](https://github.com/dimbslmh/bootstrap-table/tree/master/src/extensions/multiple-sort)\n\n## Usage\n\n```html\n<script src=\"extensions/multiple-sort/bootstrap-table-multiple-sort.js\"></script>\n```\n\n## Options\n\n### showMultiSort\n\n* type: Boolean\n* description: Set true to allow the multiple sort.\n* default: `false`\n\n### sortPriority\n\n* type: Object\n* description: Set one or multiple sort priority. Example: '[{\"sortName\": \"forks_count\",\"sortOrder\":\"desc\"},{\"sortName\":\"stargazers_count\",\"sortOrder\":\"desc\"}]'\n* default: null\n\n### Icons\n* sort: `glyphicon-sort`\n* plus: `glyphicon-plus`\n* minus: `glyphicon-minus`\n\n## Locales\n\n### formatMultipleSort\n\n* description: Title of the advanced search modal\n* default: `Multiple Sort`\n\n### formatAddLevel\n\n* description: Text of the add level button\n* default: `Add Level`\n\n### formatDeleteLevel\n\n* description: Text of the delete level button\n* default: `Delete Level`\n\n### formatColumn\n\n* description: Text of Column header\n* default: `Column`\n\n### formatOrder\n\n* description: Text of the delete level button\n* default: `Order`\n\n### formatSortBy\n\n* description: Text of the delete level button\n* default: `Sort by`\n\n### formatThenBy\n\n* description: Text of the delete level button\n* default: `Then by`\n\n### formatSort\n\n* description: Text of the delete level button\n* default: `Sort`\n\n### formatCancel\n\n* description: Text of the delete level button\n* default: `Cancel`\n\n### formatDuplicateAlertTitle\n\n* description: Title of the duplicate alert\n* default: `Duplicate(s) detected!`\n\n### formatDuplicateAlertDescription\n\n* description: Text of the duplicate alert\n* default: `Please remove or change any duplicate column.`\n\n## Events\n\n### onMultipleSort(multiple-sort.bs.table)\n\n* Fires when sorting with one or multiple Sort Priority.\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/multiple-sort/bootstrap-table-multiple-sort.js",
    "content": "/**\n * @author Nadim Basalamah <dimbslmh@gmail.com>\n * @version: v1.0.0\n * https://github.com/dimbslmh/bootstrap-table/tree/master/src/extensions/multiple-sort/bootstrap-table-multiple-sort.js\n */\n\n(function($) {\n    'use strict';\n\n    var isSingleSort = false;\n\n    var sort_order = {\n            asc: 'Ascending',\n            desc: 'Descending'\n        },\n        arrowAsc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ' +\n        '0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBd' +\n        'qEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVo' +\n        'AADeemwtPcZI2wAAAABJRU5ErkJggg==',\n        arrowDesc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWj' +\n        'YBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJ' +\n        'zcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= ';\n\n    var showSortModal = function(that) {\n        if (!$(\"#sortModal\").hasClass(\"modal\")) {\n            var sModal = '  <div class=\"modal fade\" id=\"sortModal\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"sortModalLabel\" aria-hidden=\"true\">';\n            sModal += '         <div class=\"modal-dialog\">';\n            sModal += '             <div class=\"modal-content\">';\n            sModal += '                 <div class=\"modal-header\">';\n            sModal += '                     <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\"><span aria-hidden=\"true\">&times;</span></button>';\n            sModal += '                     <h4 class=\"modal-title\" id=\"sortModalLabel\">' + that.options.formatMultipleSort() + '</h4>';\n            sModal += '                 </div>';\n            sModal += '                 <div class=\"modal-body\">';\n            sModal += '                     <div class=\"bootstrap-table\">';\n            sModal += '                         <div class=\"fixed-table-toolbar\">';\n            sModal += '                             <div class=\"bars\">';\n            sModal += '                                 <div id=\"toolbar\">';\n            sModal += '                                     <button id=\"add\" type=\"button\" class=\"btn btn-default\"><i class=\"' + that.options.iconsPrefix + ' ' + that.options.icons.plus + '\"></i> ' + that.options.formatAddLevel() + '</button>';\n            sModal += '                                     <button id=\"delete\" type=\"button\" class=\"btn btn-default\" disabled><i class=\"' + that.options.iconsPrefix + ' ' + that.options.icons.minus + '\"></i> ' + that.options.formatDeleteLevel() + '</button>';\n            sModal += '                                 </div>';\n            sModal += '                             </div>';\n            sModal += '                         </div>';\n            sModal += '                         <div class=\"fixed-table-container\">';\n            sModal += '                             <table id=\"multi-sort\" class=\"table\">';\n            sModal += '                                 <thead>';\n            sModal += '                                     <tr>';\n            sModal += '                                         <th></th>';\n            sModal += '                                         <th><div class=\"th-inner\">' + that.options.formatColumn() + '</div></th>';\n            sModal += '                                         <th><div class=\"th-inner\">' + that.options.formatOrder() + '</div></th>';\n            sModal += '                                     </tr>';\n            sModal += '                                 </thead>';\n            sModal += '                                 <tbody></tbody>';\n            sModal += '                             </table>';\n            sModal += '                         </div>';\n            sModal += '                     </div>';\n            sModal += '                 </div>';\n            sModal += '                 <div class=\"modal-footer\">';\n            sModal += '                     <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">' + that.options.formatCancel() + '</button>';\n            sModal += '                     <button type=\"button\" class=\"btn btn-primary\">' + that.options.formatSort() + '</button>';\n            sModal += '                 </div>';\n            sModal += '             </div>';\n            sModal += '         </div>';\n            sModal += '     </div>';\n\n            $(\"body\").append($(sModal));\n\n            var $sortModal = $('#sortModal'),\n                $rows = $sortModal.find(\"tbody > tr\");\n\n            $sortModal.off('click', '#add').on('click', '#add', function() {\n                var total = $sortModal.find('.multi-sort-name:first option').length,\n                    current = $sortModal.find('tbody tr').length;\n\n                if (current < total) {\n                    current++;\n                    that.addLevel();\n                    that.setButtonStates();\n                }\n            });\n\n            $sortModal.off('click', '#delete').on('click', '#delete', function() {\n                var total = $sortModal.find('.multi-sort-name:first option').length,\n                    current = $sortModal.find('tbody tr').length;\n\n                if (current > 1 && current <= total) {\n                    current--;\n                    $sortModal.find('tbody tr:last').remove();\n                    that.setButtonStates();\n                }\n            });\n\n            $sortModal.off('click', '.btn-primary').on('click', '.btn-primary', function() {\n                var $rows = $sortModal.find(\"tbody > tr\"),\n                    $alert = $sortModal.find('div.alert'),\n                    fields = [],\n                    results = [];\n\n\n                that.options.sortPriority = $.map($rows, function(row) {\n                    var $row = $(row),\n                        name = $row.find('.multi-sort-name').val(),\n                        order = $row.find('.multi-sort-order').val();\n\n                    fields.push(name);\n\n                    return {\n                        sortName: name,\n                        sortOrder: order\n                    };\n                });\n\n                var sorted_fields = fields.sort();\n\n                for (var i = 0; i < fields.length - 1; i++) {\n                    if (sorted_fields[i + 1] == sorted_fields[i]) {\n                        results.push(sorted_fields[i]);\n                    }\n                }\n\n                if (results.length > 0) {\n                    if ($alert.length === 0) {\n                        $alert = '<div class=\"alert alert-danger\" role=\"alert\"><strong>' + that.options.formatDuplicateAlertTitle() + '</strong> ' + that.options.formatDuplicateAlertDescription() + '</div>';\n                        $($alert).insertBefore($sortModal.find('.bars'));\n                    }\n                } else {\n                    if ($alert.length === 1) {\n                        $($alert).remove();\n                    }\n\n                    that.options.sortName = \"\";\n                    that.onMultipleSort();\n                    $sortModal.modal('hide');\n                }\n            });\n\n            if (that.options.sortPriority === null) {\n                if (that.options.sortName) {\n                    that.options.sortPriority = [{\n                        sortName: that.options.sortName,\n                        sortOrder: that.options.sortOrder\n                    }];\n                }\n            }\n            \n            if (that.options.sortPriority !== null) {\n                if ($rows.length < that.options.sortPriority.length && typeof that.options.sortPriority === 'object') {\n                    for (var i = 0; i < that.options.sortPriority.length; i++) {\n                        that.addLevel(i, that.options.sortPriority[i]);\n                    }\n                }\n            } else {\n                that.addLevel(0);\n            }\n\n            that.setButtonStates();\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        showMultiSort: false,\n        sortPriority: null,\n        onMultipleSort: function() {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.defaults.icons, {\n        sort: 'glyphicon-sort',\n        plus: 'glyphicon-plus',\n        minus: 'glyphicon-minus'\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'multiple-sort.bs.table': 'onMultipleSort'\n    });\n\n    $.extend($.fn.bootstrapTable.locales, {\n        formatMultipleSort: function() {\n            return 'Multiple Sort';\n        },\n        formatAddLevel: function() {\n            return \"Add Level\";\n        },\n        formatDeleteLevel: function() {\n            return \"Delete Level\";\n        },\n        formatColumn: function() {\n            return \"Column\";\n        },\n        formatOrder: function() {\n            return \"Order\";\n        },\n        formatSortBy: function() {\n            return \"Sort by\";\n        },\n        formatThenBy: function() {\n            return \"Then by\";\n        },\n        formatSort: function() {\n            return \"Sort\";\n        },\n        formatCancel: function() {\n            return \"Cancel\";\n        },\n        formatDuplicateAlertTitle: function() {\n            return \"Duplicate(s) detected!\";\n        },\n        formatDuplicateAlertDescription: function() {\n            return \"Please remove or change any duplicate column.\";\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initToolbar = BootstrapTable.prototype.initToolbar;\n\n    BootstrapTable.prototype.initToolbar = function() {\n        this.showToolbar = true;\n        var that = this;\n\n        _initToolbar.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.showMultiSort) {\n            var $btnGroup = this.$toolbar.find('>.btn-group'),\n                $multiSortBtn = $btnGroup.find('div.multi-sort');\n\n            if (!$multiSortBtn.length) {\n                $multiSortBtn = '  <button class=\"multi-sort btn btn-default' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + '\" type=\"button\" data-toggle=\"modal\" data-target=\"#sortModal\" title=\"' + this.options.formatMultipleSort() + '\">';\n                $multiSortBtn += '     <i class=\"' + this.options.iconsPrefix + ' ' + this.options.icons.sort + '\"></i>';\n                $multiSortBtn += '</button>';\n\n                $btnGroup.append($multiSortBtn);\n\n                showSortModal(that);\n            }\n\n            this.$el.one('sort.bs.table', function() {\n                isSingleSort = true;\n            });\n\n            this.$el.on('multiple-sort.bs.table', function() {\n                isSingleSort = false;\n            });\n\n            this.$el.on('load-success.bs.table', function() {\n                if (!isSingleSort && that.options.sortPriority !== null && typeof that.options.sortPriority === 'object') {\n                    that.onMultipleSort();\n                }\n            });\n\n            this.$el.on('column-switch.bs.table', function() {\n                that.options.sortPriority = null;\n                $('#sortModal').remove();\n                showSortModal(that);\n            });\n        }\n    };\n\n    BootstrapTable.prototype.onMultipleSort = function() {\n        var that = this;\n        \n        var cmp = function(x, y) {\n            return x > y ? 1 : x < y ? -1 : 0;\n        };\n\n        var arrayCmp = function(a, b) {\n            var arr1 = [],\n                arr2 = [];\n\n            for (var i = 0; i < that.options.sortPriority.length; i++) {\n                var order = that.options.sortPriority[i].sortOrder === 'desc' ? -1 : 1,\n                    aa = a[that.options.sortPriority[i].sortName],\n                    bb = b[that.options.sortPriority[i].sortName];\n\n                if (aa === undefined || aa === null) {\n                    aa = '';\n                }\n                if (bb === undefined || bb === null) {\n                    bb = '';\n                }\n                if ($.isNumeric(aa) && $.isNumeric(bb)) {\n                    aa = parseFloat(aa);\n                    bb = parseFloat(bb);\n                }\n                if (typeof aa !== 'string') {\n                    aa = aa.toString();\n                }\n\n                arr1.push(\n                    order * cmp(aa, bb));\n                arr2.push(\n                    order * cmp(bb, aa));\n            }\n\n            return cmp(arr1, arr2);\n        };\n\n        this.data.sort(function(a, b) {\n            return arrayCmp(a, b);\n        });\n\n        this.initBody();\n        this.assignSortableArrows();\n        this.trigger('multiple-sort');\n    };\n\n    BootstrapTable.prototype.addLevel = function(index, sortPriority) {\n        var $sortModal = $(\"#sortModal\"),\n            text = index === 0 ? this.options.formatSortBy() : this.options.formatThenBy();\n\n        $sortModal.find('tbody')\n            .append($('<tr>')\n                .append($('<td>').text(text))\n                .append($('<td>').append($('<select class=\"form-control multi-sort-name\">')))\n                .append($('<td>').append($('<select class=\"form-control multi-sort-order\">')))\n            );\n\n        var $multiSortName = $sortModal.find('.multi-sort-name').last(),\n            $multiSortOrder = $sortModal.find('.multi-sort-order').last();\n\n        this.options.columns.forEach(function(column) {\n            if (column.sortable === false || column.visible === false) {\n                return true;\n            }\n            $multiSortName.append('<option value=\"' + column.field + '\">' + column.title + '</option>');\n        });\n\n        $.each(sort_order, function(value, order) {\n            $multiSortOrder.append('<option value=\"' + value + '\">' + order + '</option>');\n        });\n\n        if (sortPriority !== undefined) {\n            $multiSortName.find('option[value=\"' + sortPriority.sortName + '\"]').attr(\"selected\", true);\n            $multiSortOrder.find('option[value=\"' + sortPriority.sortOrder + '\"]').attr(\"selected\", true);\n        }\n    };\n\n    BootstrapTable.prototype.assignSortableArrows = function() {\n        var that = this,\n            headers = that.$header.find('th');\n\n        for (var i = 0; i < headers.length; i++) {\n            for (var c = 0; c < that.options.sortPriority.length; c++) {\n                if ($(headers[i]).data('field') === that.options.sortPriority[c].sortName) {\n                    $(headers[i]).find('.sortable').css('background-image', 'url(' + (that.options.sortPriority[c].sortOrder === 'desc' ? arrowDesc : arrowAsc) + ')');\n                }\n            }\n        }\n    };\n\n    BootstrapTable.prototype.setButtonStates = function() {\n        var $sortModal = $('#sortModal'),\n            total = $sortModal.find('.multi-sort-name:first option').length,\n            current = $sortModal.find('tbody tr').length;\n\n        if (current == total) {\n            $sortModal.find('#add').attr('disabled', 'disabled');\n        }\n        if (current > 1) {\n            $sortModal.find('#delete').removeAttr('disabled');\n        }\n        if (current < total) {\n            $sortModal.find('#add').removeAttr('disabled');\n        }\n        if (current == 1) {\n            $sortModal.find('#delete').attr('disabled', 'disabled');\n        }\n    };\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/natural-sorting/README.md",
    "content": "# Table Natural Sorting\n\nUse Plugin: [bootstrap-table-natural-sorting](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/natural-sorting)\n\n## Usage\n\n```html\n<script src=\"extensions/natural-sorting/bootstrap-table-natural-sorting.js\"></script>\n```\n\n### Options\n\n* Just add data-sorter=\"alphanum\" to any th"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/natural-sorting/bootstrap-table-natural-sorting.js",
    "content": "/**\n * @author: Brian Huisman\n * @webSite: http://www.greywyvern.com\n * @version: v1.0.0\n * JS function to allow natural sorting on bootstrap-table columns\n * just add data-sorter=\"alphanum\" to any th\n *\n * @update Dennis Hernández <http://djhvscf.github.io/Blog>\n */\n\nfunction alphanum(a, b) {\n  function chunkify(t) {\n    var tz = [],\n        x = 0,\n        y = -1,\n        n = 0,\n        i,\n        j;\n\n    while (i = (j = t.charAt(x++)).charCodeAt(0)) {\n      var m = (i === 46 || (i >= 48 && i <= 57));\n      if (m !== n) {\n        tz[++y] = \"\";\n        n = m;\n      }\n      tz[y] += j;\n    }\n    return tz;\n  }\n\n  var aa = chunkify(a);\n  var bb = chunkify(b);\n\n  for (x = 0; aa[x] && bb[x]; x++) {\n    if (aa[x] !== bb[x]) {\n      var c = Number(aa[x]),\n          d = Number(bb[x]);\n\n      if (c == aa[x] && d == bb[x]) {\n        return c - d;\n      } else {\n          return (aa[x] > bb[x]) ? 1 : -1;\n      }\n    }\n  }\n  return aa.length - bb.length;\n}"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/reorder-columns/README.md",
    "content": "# Table Reorder Columns\n\nUse Plugin: [bootstrap-table-reorder-columns](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/reorder-columns) </br>\nDependence: [dragTable](https://github.com/akottr/dragtable/) v2.0.14 (must include the css file), </br>\n[jquery-ui](https://code.jquery.com/ui/) v1.11\n\n\n## Usage\n\n```html\n<link rel=\"stylesheet\" href=\".../dragtable.css\">\n<script src=\".../jquery-ui.js\"></script>\n<script src=\".../jquery.dragtable.js\"></script>\n<script src=\"extensions/reorder-columns/bootstrap-table-reorder-columns.js\"></script>\n```\n\n## Options\n\n### reorderableColumns\n\n* type: Boolean\n* description: Set true to allow the reorder feature.\n* default: `false`\n\n### maxMovingRows\n\n* type: Integer\n* description: Moving only the header. Recommended for very large tables (cells > 1000)\n* default: `10`\n\n## Events\n\n### onReorderColumn(reorder-column.bs.table)\n\nFired when the column was dropped, receive as parameter the new header fields order"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/reorder-columns/bootstrap-table-reorder-columns.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.1.0\n */\n\n!function ($) {\n\n    'use strict';\n\n    var getFieldIndex = function (columns, field) {\n        var index = -1;\n\n        $.each(columns, function (i, column) {\n            if (column.field === field) {\n                index = i;\n                return false;\n            }\n            return true;\n        });\n        return index;\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        reorderableColumns: false,\n        maxMovingRows: 10,\n        onReorderColumn: function (headerFields) {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'reorder-column.bs.table': 'onReorderColumn'\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initHeader = BootstrapTable.prototype.initHeader,\n        _toggleColumn = BootstrapTable.prototype.toggleColumn,\n        _toggleView = BootstrapTable.prototype.toggleView,\n        _resetView = BootstrapTable.prototype.resetView;\n\n    BootstrapTable.prototype.initHeader = function () {\n        _initHeader.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableColumns) {\n            return;\n        }\n\n        this.makeRowsReorderable();\n    };\n\n    BootstrapTable.prototype.toggleColumn = function () {\n        _toggleColumn.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableColumns) {\n            return;\n        }\n\n        this.makeRowsReorderable();\n    };\n\n    BootstrapTable.prototype.toggleView = function () {\n        _toggleView.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableColumns) {\n            return;\n        }\n\n        if (this.options.cardView) {\n            return;\n        }\n\n        this.makeRowsReorderable();\n    };\n\n    BootstrapTable.prototype.resetView = function () {\n        _resetView.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableColumns) {\n            return;\n        }\n\n        this.makeRowsReorderable();\n    };\n\n    BootstrapTable.prototype.makeRowsReorderable = function () {\n\n        var that = this;\n        try {\n            $(this.$el).dragtable('destroy');\n        } catch (e) {}\n        $(this.$el).dragtable({\n            maxMovingRows: that.options.maxMovingRows,\n            clickDelay:200,\n            beforeStop: function() {\n                var ths = [],\n                    columns = [],\n                    columnIndex = -1;\n                that.$header.find('th').each(function (i) {\n                    ths.push($(this).data('field'));\n                });\n\n                for (var i = 0; i < ths.length; i++ ) {\n                    columnIndex = getFieldIndex(that.options.columns, ths[i]);\n                    if (columnIndex !== -1) {\n                        columns.push(that.options.columns[columnIndex]);\n                        that.options.columns.splice(columnIndex, 1);\n                    }\n                }\n\n                that.options.columns = that.options.columns.concat(columns);\n                that.header.fields = ths;\n                that.resetView();\n                that.trigger('reorder-column', ths);\n            }\n        });\n    };\n}(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/reorder-rows/README.md",
    "content": "# Table Reorder Rows\n\nUse Plugin: [bootstrap-table-reorder-rows](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/reorder-rows) </br>\nDependence: [tablednd](https://github.com/isocra/TableDnD) v0.9, </br>\nif you want you can include the bootstrap-table-reorder-rows.css file to use the default dragClass\n\n\n## Usage\n\n```html\n<link rel=\"stylesheet\" href=\".../bootstrap-table-reorder-rows.css\">\n<script src=\".../jquery.tablednd.js\"></script>\n<script src=\"extensions/reorder-rows/bootstrap-table-reorder-rows.js\"></script>\n```\n\n## Options\n\n### reorderableRows\n\n* type: Boolean\n* description: Set true to allow the reorder feature.\n* default: `false`\n\n### onDragStyle\n\n* type: String\n* description: This is the style that is assigned to the row during drag. There are limitations to the styles that can be associated with a row (such as you can't assign a border�well you can, but it won't be displayed).\n* default: `null`\n\n### onDropStyle\n\n* type: String\n* description: This is the style that is assigned to the row when it is dropped. As for onDragStyle, there are limitations to what you can do. Also this replaces the original style, so again consider using onDragClass which is simply added and then removed on drop.\n* default: `null`\n\n### onDragClass\n\n* type: String\n* description: This class is added for the duration of the drag and then removed when the row is dropped. It is more flexible than using onDragStyle since it can be inherited by the row cells and other content.\n* default: `reorder_rows_onDragClass`\n\n### dragHandle\n\n* type: String\n* description: This is the cursor to use\n* default: `null`\n\n### useRowAttrFunc\n\n* type: Boolean\n* description: This function must be use if your `tr` elements won't have the `id` attribute. If your `tr` elements don't have the `id` attribute this plugin don't fire the onDrop event.\n* default: `false`\n\n### onReorderRowsDrag\n\n* type: Function\n* description: Pass a function that will be called when the user starts dragging. The function takes 2 parameters: the table and the row which the user has started to drag.\n* default: `empty function`\n\n### onReorderRowsDrop\n\n* type: Function\n* description: Pass a function that will be called when the row is dropped. The function takes 2 parameters: the table and the row that was dropped.\n* default: `empty function`\n\n## Events\n\n### onReorderRow(reorder-row.bs.table)\n\nFired when the row was dropped, receive as parameter the new data order\n\n## The existing problems\n\n* After search if the user reorder the rows the data is not shown properly after that."
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/reorder-rows/bootstrap-table-reorder-rows.css",
    "content": ".reorder_rows_onDragClass td {\n    background-color: #eee;\n    -webkit-box-shadow: 11px 5px 12px 2px #333, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;\n    -webkit-box-shadow: 6px 3px 5px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;\n    -moz-box-shadow: 6px 4px 5px 1px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;\n    -box-shadow: 6px 4px 5px 1px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;\n}\n\n.reorder_rows_onDragClass td:last-child {\n    -webkit-box-shadow: 8px 7px 12px 0 #333, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;\n    -webkit-box-shadow: 1px 8px 6px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;\n    -moz-box-shadow: 0 9px 4px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset, -1px 0 0 #ccc inset;\n    -box-shadow: 0 9px 4px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset, -1px 0 0 #ccc inset;\n}"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/reorder-rows/bootstrap-table-reorder-rows.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.0.0\n */\n\n!function ($) {\n\n    'use strict';\n\n    var isSearch = false;\n\n    var rowAttr = function (row, index) {\n        return {\n            id: 'customId_' + index\n        };\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        reorderableRows: false,\n        onDragStyle: null,\n        onDropStyle: null,\n        onDragClass: \"reorder_rows_onDragClass\",\n        dragHandle: null,\n        useRowAttrFunc: false,\n        onReorderRowsDrag: function (table, row) {\n            return false;\n        },\n        onReorderRowsDrop: function (table, row) {\n            return false;\n        },\n        onReorderRow: function (newData) {\n             return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'reorder-row.bs.table': 'onReorderRow'\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _init = BootstrapTable.prototype.init,\n        _initSearch = BootstrapTable.prototype.initSearch;\n\n    BootstrapTable.prototype.init = function () {\n\n        _init.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableRows) {\n            return;\n        }\n\n        var that = this;\n        if (this.options.useRowAttrFunc) {\n            this.options.rowAttributes = rowAttr;\n        }\n\n        var onPostBody = this.options.onPostBody;\n        this.options.onPostBody = function () {\n            setTimeout(function () {\n                that.makeRowsReorderable();\n                onPostBody.apply();\n            }, 1);\n        };\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        _initSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.reorderableRows) {\n            return;\n        }\n\n        //Known issue after search if you reorder the rows the data is not display properly\n        //isSearch = true;\n    };\n\n    BootstrapTable.prototype.makeRowsReorderable = function () {\n        if (this.options.cardView) {\n            return;\n        }\n\n        var that = this;\n        this.$el.tableDnD({\n            onDragStyle: that.options.onDragStyle,\n            onDropStyle: that.options.onDropStyle,\n            onDragClass: that.options.onDragClass,\n            onDrop: that.onDrop,\n            onDragStart: that.options.onReorderRowsDrag,\n            dragHandle: that.options.dragHandle\n        });\n    };\n\n    BootstrapTable.prototype.onDrop = function (table, row) {\n        var tableBs = $(table),\n            tableBsData = tableBs.data('bootstrap.table'),\n            tableBsOptions = tableBs.data('bootstrap.table').options,\n            row = null,\n            newData = [];\n\n        for (var i = 0; i < table.tBodies[0].rows.length; i++) {\n            row = $(table.tBodies[0].rows[i]);\n            newData.push(tableBsOptions.data[row.data('index')]);\n            row.data('index', i).attr('data-index', i);\n        }\n\n        tableBsOptions.data = newData;\n\n        //Call the user defined function\n        tableBsOptions.onReorderRowsDrop.apply(table, row);\n\n        //Call the event reorder-row\n        tableBsData.trigger('reorder-row', newData);\n    };\n}(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/resizable/README.md",
    "content": "# Table Resizable\n\nUse Plugin: [bootstrap-table-resizable](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/resizable) </br>\nDependence: [colResizable](https://github.com/alvaro-prieto/colResizable) v1.5\n\n## Usage\n\n```html\n<script src=\"extensions/cookie/bootstrap-table-resizable.js\"></script>\n```\n\n## Options\n\n### resizable\n\n* type: Boolean\n* description: Set true to allow the resize in each column.\n* default: `false`\n\n### liveDrag\n\n* type: Boolean\n* description: When set to true the table layout is updated while dragging column anchors. liveDrag enabled is more CPU consuming so it is not recommended for slow computers, specially when dealing with huge or extremely complicated tables.\n* default: `false`\n\n### fixed\n\n* type: Boolean\n* description: It is used to set how the resize method works. In fixed mode resizing a column does not alter total table width, which means that when a column is expanded the next one shrinks. If fixed is set to false then table can change its width and each column can shrink or expand independently.\n* default: `true`\n\n### headerOnly\n\n* type: Boolean\n* description: This attribute can be used to prevent vertical expansion of the column anchors to fit the table height. If it is set to true, column handler's size will be bounded to the first row's vertical size.\n* default: `false`\n\n### minWidth\n\n* type: Integer\n* description: This value specifies the minimum width (measured in pixels) that is allowed for the columns.\n* default: `15`\n\n### hoverCursor\n\n* type: String\n* description: This attribute can be used to customize the cursor that will be displayed when the user is positioned on the column anchors.\n* default: `e-resize`\n\n### dragCursor\n\n* type: String\n* description: Defines the cursor that will be used while the user is resizing a column.\n* default: `e-resize`\n\n### onResizableResize\n\n* type: Function\n* description: If a callback function is supplied it will be fired when the user has ended dragging a column anchor altering the previous table layout. The callback function can obtain a reference to the updated table through the currentTarget attribute of the event retrieved by parameters.\n* default: `empty function`\n\n### onResizableDrag\n\n* type: Function\n* description: This event is fired while dragging a column anchor if liveDrag is enabled. It can be useful if the table is being used as a multiple range slider. The callback function can obtain a reference to the updated table through the currentTarget attribute of the event retrieved by parameters\n* default: `empty function`"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/resizable/bootstrap-table-resizable.js",
    "content": "/**\n * @author: Dennis Hernández\n * @webSite: http://djhvscf.github.io/Blog\n * @version: v1.0.0\n */\n\n(function ($) {\n    'use strict';\n\n    var initResizable = function (that) {\n        //Deletes the plugin to re-create it\n        that.$el.colResizable({disable: true});\n\n        //Creates the plugin\n        that.$el.colResizable({\n            liveDrag: that.options.liveDrag,\n            fixed: that.options.fixed,\n            headerOnly: that.options.headerOnly,\n            minWidth: that.options.minWidth,\n            hoverCursor: that.options.hoverCursor,\n            dragCursor: that.options.dragCursor,\n            onResize: that.onResize,\n            onDrag: that.options.onResizableDrag\n        });\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        resizable: false,\n        liveDrag: false,\n        fixed: true,\n        headerOnly: false,\n        minWidth: 15,\n        hoverCursor: 'e-resize',\n        dragCursor: 'e-resize',\n        onResizableResize: function (e) {\n            return false;\n        },\n        onResizableDrag: function (e) {\n            return false;\n        }\n    });\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _toggleView = BootstrapTable.prototype.toggleView,\n        _resetView = BootstrapTable.prototype.resetView;\n\n    BootstrapTable.prototype.toggleView = function () {\n        _toggleView.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.resizable && this.options.cardView) {\n            //Deletes the plugin\n            $(this.$el).colResizable({disable: true});\n        }\n    };\n\n    BootstrapTable.prototype.resetView = function () {\n        var that = this;\n\n        _resetView.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (this.options.resizable) {\n            // because in fitHeader function, we use setTimeout(func, 100);\n            setTimeout(function () {\n                initResizable(that);\n            }, 100);\n        }\n    };\n\n    BootstrapTable.prototype.onResize = function (e) {\n        var that = $(e.currentTarget);\n        that.bootstrapTable('resetView');\n        that.data('bootstrap.table').options.onResizableResize.apply(e);\n    }\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/toolbar/README.md",
    "content": "# Table Toolbar\n\nUse Plugin: [bootstrap-table-toolbar](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/toolbar)\n\n## Usage\n\n```html\n<script src=\"extensions/toolbar/bootstrap-table-toolbar.js\"></script>\n```\n\n## Options\n\n### advancedSearch\n\n* type: Boolean\n* description: Set true to allow the advanced search.\n* default: `false`\n\n### idForm\n\n* type: String\n* description: Must be set to know the idform.\n* default: `advancedSearch`\n\n### actionForm\n\n* type: String\n* description: Set the action of the form (pop-up).\n* default: ``\n\n### idTable\n\n* type: String\n* description: Set the id of the table to create the pop-up form.\n* default: ``\n\n## Locales\n\n### formatAdvancedSearch\n\n* description: Title of the advanced search modal\n* default: `Advanced search`\n\n### formatAdvancedCloseButton\n\n* description: Text of the close button\n* default: `Close`\n\n## Events\n\n### onColumnAdvancedSearch(column-advanced-search.bs.table)\n\n* Fired when we are searching into the advanced search form"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/extensions/toolbar/bootstrap-table-toolbar.js",
    "content": "/**\n * @author: aperez <aperez@datadec.es>\n * @version: v2.0.0\n *\n * @update Dennis Hernández <http://djhvscf.github.io/Blog>\n */\n\n!function($) {\n    'use strict';\n\n    var firstLoad = false;\n\n    var sprintf = function(str) {\n        var args = arguments,\n            flag = true,\n            i = 1;\n\n        str = str.replace(/%s/g, function() {\n            var arg = args[i++];\n\n            if (typeof arg === 'undefined') {\n                flag = false;\n                return '';\n            }\n            return arg;\n        });\n        return flag ? str : '';\n    };\n\n    var calculateObjectValue = function (self, name, args, defaultValue) {\n        if (typeof name === 'string') {\n            // support obj.func1.func2\n            var names = name.split('.');\n\n            if (names.length > 1) {\n                name = window;\n                $.each(names, function (i, f) {\n                    name = name[f];\n                });\n            } else {\n                name = window[name];\n            }\n        }\n        if (typeof name === 'object') {\n            return name;\n        }\n        if (typeof name === 'function') {\n            return name.apply(self, args);\n        }\n        return defaultValue;\n    };\n\n    var showAvdSearch = function(pColumns, searchTitle, searchText, that) {\n        if (!$(\"#avdSearchModal\").hasClass(\"modal\")) {\n            var vModal = \"<div id=\\\"avdSearchModal\\\" class=\\\"modal fade\\\" tabindex=\\\"-1\\\" role=\\\"dialog\\\" aria-labelledby=\\\"mySmallModalLabel\\\" aria-hidden=\\\"true\\\">\";\n            vModal += \"<div class=\\\"modal-dialog modal-xs\\\">\";\n            vModal += \" <div class=\\\"modal-content\\\">\";\n            vModal += \"  <div class=\\\"modal-header\\\">\";\n            vModal += \"   <button type=\\\"button\\\" class=\\\"close\\\" data-dismiss=\\\"modal\\\" aria-hidden=\\\"true\\\" >&times;</button>\";\n            vModal += sprintf(\"   <h4 class=\\\"modal-title\\\">%s</h4>\", searchTitle);\n            vModal += \"  </div>\";\n            vModal += \"  <div class=\\\"modal-body modal-body-custom\\\">\";\n            vModal += \"   <div class=\\\"container-fluid\\\" id=\\\"avdSearchModalContent\\\" style=\\\"padding-right: 0px;padding-left: 0px;\\\" >\";\n            vModal += \"   </div>\";\n            vModal += \"  </div>\";\n            vModal += \"  </div>\";\n            vModal += \" </div>\";\n            vModal += \"</div>\";\n\n            $(\"body\").append($(vModal));\n\n            var vFormAvd = createFormAvd(pColumns, searchText, that),\n                timeoutId = 0;;\n\n            $('#avdSearchModalContent').append(vFormAvd.join(''));\n\n            $('#' + that.options.idForm).off('keyup blur', 'input').on('keyup blur', 'input', function (event) {\n                clearTimeout(timeoutId);\n                timeoutId = setTimeout(function () {\n                    that.onColumnAdvancedSearch(event);\n                }, that.options.searchTimeOut);\n            });\n\n            $(\"#btnCloseAvd\").click(function() {\n                $(\"#avdSearchModal\").modal('hide');\n            });\n\n            $(\"#avdSearchModal\").modal();\n        } else {\n            $(\"#avdSearchModal\").modal();\n        }\n    };\n\n    var createFormAvd = function(pColumns, searchText, that) {\n        var htmlForm = [];\n        htmlForm.push(sprintf('<form class=\"form-horizontal\" id=\"%s\" action=\"%s\" >', that.options.idForm, that.options.actionForm));\n        for (var i in pColumns) {\n            var vObjCol = pColumns[i];\n            if (!vObjCol.checkbox && vObjCol.visible && vObjCol.searchable) {\n                htmlForm.push('<div class=\"form-group\">');\n                htmlForm.push(sprintf('<label class=\"col-sm-4 control-label\">%s</label>', vObjCol.title));\n                htmlForm.push('<div class=\"col-sm-6\">');\n                htmlForm.push(sprintf('<input type=\"text\" class=\"form-control input-md\" name=\"%s\" placeholder=\"%s\" id=\"%s\">', vObjCol.field, vObjCol.title, vObjCol.field));\n                htmlForm.push('</div>');\n                htmlForm.push('</div>');\n            }\n        }\n\n        htmlForm.push('<div class=\"form-group\">');\n        htmlForm.push('<div class=\"col-sm-offset-9 col-sm-3\">');\n        htmlForm.push(sprintf('<button type=\"button\" id=\"btnCloseAvd\" class=\"btn btn-default\" >%s</button>', searchText));\n        htmlForm.push('</div>');\n        htmlForm.push('</div>');\n        htmlForm.push('</form>');\n\n        return htmlForm;\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, {\n        advancedSearch: false,\n        idForm: 'advancedSearch',\n        actionForm: '',\n        idTable: undefined,\n        onColumnAdvancedSearch: function (field, text) {\n            return false;\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.defaults.icons, {\n        advancedSearchIcon: 'glyphicon-chevron-down'\n    });\n\n    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {\n        'column-advanced-search.bs.table': 'onColumnAdvancedSearch'\n    });\n\n    $.extend($.fn.bootstrapTable.locales, {\n        formatAdvancedSearch: function() {\n            return 'Advanced search';\n        },\n        formatAdvancedCloseButton: function() {\n            return \"Close\";\n        }\n    });\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);\n\n    var BootstrapTable = $.fn.bootstrapTable.Constructor,\n        _initToolbar = BootstrapTable.prototype.initToolbar,        \n        _load = BootstrapTable.prototype.load,\n        _initSearch = BootstrapTable.prototype.initSearch;\n\n    BootstrapTable.prototype.initToolbar = function() {\n        _initToolbar.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (!this.options.search) {\n            return;\n        }\n\n        if (!this.options.advancedSearch) {\n            return;\n        }\n\n        var that = this,\n            html = [];\n\n        html.push(sprintf('<div class=\"columns columns-%s btn-group pull-%s\" role=\"group\">', this.options.buttonsAlign, this.options.buttonsAlign));\n        html.push(sprintf('<button class=\"btn btn-default%s' + '\" type=\"button\" name=\"advancedSearch\" title=\"%s\">', that.options.iconSize === undefined ? '' : ' btn-' + that.options.iconSize, that.options.formatAdvancedSearch()));\n        html.push(sprintf('<i class=\"%s %s\"></i>', that.options.iconsPrefix, that.options.icons.advancedSearchIcon))\n        html.push('</button></div>');\n\n        that.$toolbar.prepend(html.join(''));\n\n        that.$toolbar.find('button[name=\"advancedSearch\"]')\n            .off('click').on('click', function() {\n                showAvdSearch(that.options.columns, that.options.formatAdvancedSearch(), that.options.formatAdvancedCloseButton(), that);\n            });\n    };\n\n    BootstrapTable.prototype.load = function(data) {\n        _load.apply(this, Array.prototype.slice.apply(arguments));\n\n        if (typeof this.options.idTable === 'undefined') {\n            return;\n        } else {\n            if (!firstLoad) {\n                var height = parseInt($(\".bootstrap-table\").height());\n                height += 10;\n                $(\"#\" + this.options.idTable).bootstrapTable(\"resetView\", {height: height});\n                firstLoad = true;\n            }\n        }\n    };\n\n    BootstrapTable.prototype.initSearch = function () {\n        _initSearch.apply(this, Array.prototype.slice.apply(arguments));\n\n        var that = this;\n        var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial;\n\n        this.data = fp ? $.grep(this.data, function (item, i) {\n            for (var key in fp) {\n                var fval = fp[key].toLowerCase();\n                var value = item[key];\n                value = calculateObjectValue(that.header,\n                    that.header.formatters[$.inArray(key, that.header.fields)],\n                    [value, item, i], value);\n\n                if (!($.inArray(key, that.header.fields) !== -1 &&\n                    (typeof value === 'string' || typeof value === 'number') &&\n                    (value + '').toLowerCase().indexOf(fval) !== -1)) {\n                    return false;\n                }\n            }\n            return true;\n        }) : this.data;\n    };\n\n    BootstrapTable.prototype.onColumnAdvancedSearch = function (event) {\n        var text = $.trim($(event.currentTarget).val());\n        var $field = $(event.currentTarget)[0].id;\n\n        if ($.isEmptyObject(this.filterColumnsPartial)) {\n            this.filterColumnsPartial = {};\n        }\n        if (text) {\n            this.filterColumnsPartial[$field] = text;\n        } else {\n            delete this.filterColumnsPartial[$field];\n        }\n\n        this.options.pageNumber = 1;\n        this.onSearch(event);\n        this.updatePagination();\n        this.trigger('column-advanced-search', $field, text);\n    };\n}(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/README.md",
    "content": "[List of All Locales and Their Short Codes](http://stackoverflow.com/questions/3191664/list-of-all-locales-and-their-short-codes)\n```\naf-ZA\nam-ET\nar-AE\nar-BH\nar-DZ\nar-EG\nar-IQ\nar-JO\nar-KW\nar-LB\nar-LY\nar-MA\narn-CL\nar-OM\nar-QA\nar-SY\nar-TN\nar-YE\nas-IN\naz-Cyrl-AZ\naz-Latn-AZ\nba-RU\nbe-BY\nbg-BG\nbn-BD\nbn-IN\nbo-CN\nbr-FR\nbs-Cyrl-BA\nbs-Latn-BA\nca-ES\nco-FR\ncy-GB\nde-AT\nde-CH\nde-LI\nde-LU\ndsb-DE\ndv-MV\nen-029\nen-AU\nen-BZ\nen-CA\nen-GB\nen-IE\nen-IN\nen-JM\nen-MY\nen-NZ\nen-PH\nen-SG\nen-TT\nen-ZA\nen-ZW\nes-BO\nes-CL\nes-CO\nes-DO\nes-EC\nes-ES\nes-GT\nes-HN\nes-PA\nes-PE\nes-PR\nes-PY\nes-SV\nes-US\nes-UY\nes-VE\net-EE\neu-ES\nfa-IR\nfi-FI\nfil-PH\nfo-FO\nfr-CA\nfr-CH\nfr-LU\nfr-MC\nfy-NL\nga-IE\ngd-GB\ngl-ES\ngsw-FR\ngu-IN\nha-Latn-NG\nhe-IL\nhi-IN\nhr-BA\nhr-HR\nhsb-DE\nhy-AM\nid-ID\nig-NG\nii-CN\nis-IS\nit-CH\niu-Cans-CA\niu-Latn-CA\nkk-KZ\nkl-GL\nkm-KH\nkn-IN\nkok-IN\nky-KG\nlb-LU\nlo-LA\nlt-LT\nlv-LV\nmi-NZ\nmk-MK\nml-IN\nmn-MN\nmn-Mong-CN\nmoh-CA\nmr-IN\nms-BN\nmt-MT\nne-NP\nnl-BE\nnn-NO\nnso-ZA\noc-FR\nor-IN\npa-IN\nprs-AF\nps-AF\nqut-GT\nquz-BO\nquz-EC\nquz-PE\nrm-CH\nrw-RW\nsah-RU\nsa-IN\nse-FI\nse-NO\nse-SE\nsi-LK\nsl-SI\nsma-NO\nsma-SE\nsmj-NO\nsmj-SE\nsmn-FI\nsms-FI\nsq-AL\nsr-Cyrl-BA\nsr-Cyrl-CS\nsr-Cyrl-ME\nsr-Cyrl-RS\nsr-Latn-BA\nsr-Latn-CS\nsr-Latn-ME\nsr-Latn-RS\nsv-FI\nsw-KE\nsyr-SY\nta-IN\nte-IN\ntg-Cyrl-TJ\ntk-TM\ntn-ZA\ntt-RU\ntzm-Latn-DZ\nug-CN\nuz-Cyrl-UZ\nuz-Latn-UZ\nwo-SN\nxh-ZA\nyo-NG\nzh-HK\nzh-MO\nzh-SG\nzu-ZA\n```\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-ar-SA.js",
    "content": "/**\n * Bootstrap Table English translation\n * Author: Zhixin Wen<wenzhixin2010@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ar-SA'] = {\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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ar-SA']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-cs-CZ.js",
    "content": "/**\n * Bootstrap Table Czech translation\n * Author: Lukas Kral (monarcha@seznam.cz)\n * Author: Jakub Svestka <svestka1999@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['cs-CZ'] = {\n        formatLoadingMessage: function () {\n            return 'Čekejte, prosím...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' položek na stránku';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Zobrazena ' + pageFrom + '. - ' + pageTo + '. položka z celkových ' + totalRows;\n        },\n        formatSearch: function () {\n            return 'Vyhledávání';\n        },\n        formatNoMatches: function () {\n            return 'Nenalezena žádná vyhovující položka';\n        },\n        formatPaginationSwitch: function () {\n            return 'Skrýt/Zobrazit stránkování';\n        },\n        formatRefresh: function () {\n            return 'Aktualizovat';\n        },\n        formatToggle: function () {\n            return 'Přepni';\n        },\n        formatColumns: function () {\n            return 'Sloupce';\n        },\n        formatAllRows: function () {\n            return 'Vše';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['cs-CZ']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-da-DK.js",
    "content": "/**\n * Bootstrap Table danish translation\n * Author: Your Name Jan Borup Coyle, github@coyle.dk\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['da-DK'] = {\n        formatLoadingMessage: function () {\n            return 'Indlæser, vent venligst...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' poster pr side';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Viser ' + pageFrom + ' til ' + pageTo + ' af ' + totalRows + ' rækker';\n        },\n        formatSearch: function () {\n            return 'Søg';\n        },\n        formatNoMatches: function () {\n            return 'Ingen poster fundet';\n        },\n        formatRefresh: function () {\n            return 'Opdater';\n        },\n        formatToggle: function () {\n            return 'Skift';\n        },\n        formatColumns: function () {\n            return 'Kolonner';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['da-DK']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-de-DE.js",
    "content": "/**\n* Bootstrap Table German translation\n* Author: Paul Mohr - Sopamo<p.mohr@sopamo.de>\n*/\n(function ($) {\n  'use strict';\n\n  $.fn.bootstrapTable.locales['de-DE'] = {\n    formatLoadingMessage: function () {\n      return 'Lade, bitte warten...';\n    },\n    formatRecordsPerPage: function (pageNumber) {\n      return pageNumber + ' Einträge pro Seite';\n    },\n    formatShowingRows: function (pageFrom, pageTo, totalRows) {\n      return 'Zeige ' + pageFrom + ' bis ' + pageTo + ' von ' + totalRows + ' Zeile' + ((totalRows > 1) ? \"n\" : \"\");\n    },\n    formatSearch: function () {\n      return 'Suchen';\n    },\n    formatNoMatches: function () {\n      return 'Keine passenden Ergebnisse gefunden';\n    },\n    formatRefresh: function () {\n      return 'Neu laden';\n    },\n    formatToggle: function () {\n      return 'Umschalten';\n    },\n    formatColumns: function () {\n      return 'Spalten';\n    }\n  };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['de-DE']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-el-GR.js",
    "content": "/**\n * Bootstrap Table Greek translation\n * Author: giannisdallas\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['el-GR'] = {\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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['el-GR']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-en-US.js",
    "content": "/**\n * Bootstrap Table English translation\n * Author: Zhixin Wen<wenzhixin2010@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['en-US'] = {\n        formatLoadingMessage: function () {\n            return 'Loading, please wait...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' records per page';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Showing ' + pageFrom + ' to ' + pageTo + ' of ' + totalRows + ' rows';\n        },\n        formatSearch: function () {\n            return 'Search';\n        },\n        formatNoMatches: function () {\n            return 'No matching records found';\n        },\n        formatPaginationSwitch: function () {\n            return 'Hide/Show pagination';\n        },\n        formatRefresh: function () {\n            return 'Refresh';\n        },\n        formatToggle: function () {\n            return 'Toggle';\n        },\n        formatColumns: function () {\n            return 'Columns';\n        },\n        formatAllRows: function () {\n            return 'All';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['en-US']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-en-US.js.template",
    "content": "/**\n * Bootstrap Table <Language> translation\n * Author: Your Name <your@email>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['en-US'] = {\n        formatLoadingMessage: function () {\n            return 'Loading, please wait...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' records per page';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Showing ' + pageFrom + ' to ' + pageTo + ' of ' + totalRows + ' rows';\n        },\n        formatSearch: function () {\n            return 'Search';\n        },\n        formatNoMatches: function () {\n            return 'No matching records found';\n        },\n        formatPaginationSwitch: function () {\n            return 'Hide/Show pagination';\n        },\n        formatRefresh: function () {\n            return 'Refresh';\n        },\n        formatToggle: function () {\n            return 'Toggle';\n        },\n        formatColumns: function () {\n            return 'Columns';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['en-US']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-es-AR.js",
    "content": "/**\n * Bootstrap Table Spanish (Argentina) translation\n * Author: Felix Vera (felix.vera@gmail.com)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['es-AR'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, espere por favor...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Mostrando ' + pageFrom + ' a ' + pageTo + ' de ' + totalRows + ' filas';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se encontraron registros';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-AR']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-es-CR.js",
    "content": "/**\n * Bootstrap Table Spanish (Costa Rica) translation\n * Author: Dennis Hernández (http://djhvscf.github.io/Blog/)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['es-CR'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, por favor espere...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Mostrando de ' + pageFrom + ' a ' + pageTo + ' registros de ' + totalRows + ' registros en total';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se encontraron registros';\n        },\n        formatRefresh: function () {\n            return 'Refrescar';\n        },\n        formatToggle: function () {\n            return 'Alternar';\n        },\n        formatColumns: function () {\n            return 'Columnas';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-CR']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-es-MX.js",
    "content": "/**\n * Bootstrap Table Spanish (México) translation (Obtenido de traducción de Argentina)\n * Author: Felix Vera (felix.vera@gmail.com) \n * Copiado: Mauricio Vera (mauricioa.vera@gmail.com)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['es-MX'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, espere por favor...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Mostrando ' + pageFrom + ' a ' + pageTo + ' de ' + totalRows + ' filas';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se encontraron registros';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-MX']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-es-NI.js",
    "content": "/**\n * Bootstrap Table Spanish (Nicaragua) translation\n * Author: Dennis Hernández (http://djhvscf.github.io/Blog/)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['es-NI'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, por favor espere...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Mostrando de ' + pageFrom + ' a ' + pageTo + ' registros de ' + totalRows + ' registros en total';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se encontraron registros';\n        },\n        formatRefresh: function () {\n            return 'Refrescar';\n        },\n        formatToggle: function () {\n            return 'Alternar';\n        },\n        formatColumns: function () {\n            return 'Columnas';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-NI']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-es-SP.js",
    "content": "/**\n * Bootstrap Table Spanish (España) translation\n * Author: Antonio Pérez <anpegar@gmail.com>\n */\n (function ($) {\n    'use strict';\n    \n    $.fn.bootstrapTable.locales['es-SP'] = {\n        formatLoadingMessage: function () {\n            return 'Cargando, por favor espera...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por p&#225;gina.';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return pageFrom + ' - ' + pageTo + ' de ' + totalRows + ' registros.';\n        },\n        formatSearch: function () {\n            return 'Buscar';\n        },\n        formatNoMatches: function () {\n            return 'No se han encontrado registros.';\n        },\n        formatRefresh: function () {\n            return 'Actualizar';\n        },\n        formatToggle: function () {\n            return 'Alternar';\n        },\n        formatColumns: function () {\n            return 'Columnas';\n        },\n        formatAllRows: function () {\n            return 'Todo';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-SP']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-fr-BE.js",
    "content": "/**\n * Bootstrap Table French (Belgium) translation\n * Author: Julien Bisconti (julien.bisconti@gmail.com)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['fr-BE'] = {\n        formatLoadingMessage: function () {\n            return 'Chargement en cours...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' entrées par page';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Affiche de' + pageFrom + ' à ' + pageTo + ' sur ' + totalRows + ' lignes';\n        },\n        formatSearch: function () {\n            return 'Recherche';\n        },\n        formatNoMatches: function () {\n            return 'Pas de fichiers trouvés';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['fr-BE']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-fr-FR.js",
    "content": "/**\n * Bootstrap Table French (France) translation\n * Author: Dennis Hernández (http://djhvscf.github.io/Blog/)\n * Modification: Tidalf (https://github.com/TidalfFR)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['fr-FR'] = {\n        formatLoadingMessage: function () {\n            return 'Chargement en cours, patientez, s´il vous plaît ...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' lignes par page';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Affichage des lignes ' + pageFrom + ' à ' + pageTo + ' sur ' + totalRows + ' lignes au total';\n        },\n        formatSearch: function () {\n            return 'Rechercher';\n        },\n        formatNoMatches: function () {\n            return 'Aucun résultat trouvé';\n        },\n        formatRefresh: function () {\n            return 'Rafraîchir';\n        },\n        formatToggle: function () {\n            return 'Alterner';\n        },\n        formatColumns: function () {\n            return 'Colonnes';\n        },\n        formatAllRows: function () {\n            return 'Tous';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['fr-FR']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-hu-HU.js",
    "content": "/**\n * Bootstrap Table Hungarian translation\n * Author: Nagy Gergely <info@nagygergely.eu>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['hu-HU'] = {\n        formatLoadingMessage: function () {\n            return 'Betöltés, kérem várjon...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' rekord per oldal';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Megjelenítve ' + pageFrom + ' - ' + pageTo + ' / ' + totalRows + ' összesen';\n        },\n        formatSearch: function () {\n            return 'Keresés';\n        },\n        formatNoMatches: function () {\n            return 'Nincs találat';\n        },\n        formatRefresh: function () {\n            return 'Frissítés';\n        },\n        formatToggle: function () {\n            return 'Váltás';\n        },\n        formatColumns: function () {\n            return 'Oszlopok';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['hu-HU']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-it-IT.js",
    "content": "/**\n * Bootstrap Table Italian translation\n * Author: Davide Renzi<davide.renzi@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['it-IT'] = {\n        formatLoadingMessage: function () {\n            return 'Caricamento in corso...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' records per pagina';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Pagina ' + pageFrom + ' di ' + pageTo + ' (' + totalRows + ' records)';\n        },\n        formatSearch: function () {\n            return 'Cerca';\n        },\n        formatNoMatches: function () {\n            return 'Nessun record trovato';\n        },\n        formatRefresh: function () {\n            return 'Rinfrescare';\n        },\n        formatToggle: function () {\n            return 'Alternare';\n        },\n        formatColumns: function () {\n            return 'Colonne';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['it-IT']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-ja-JP.js",
    "content": "/**\n * Bootstrap Table Japanese translation\n * Author: Azamshul Azizy <azamshul@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ja-JP'] = {\n        formatLoadingMessage: function () {\n            return '読み込み中です。少々お待ちください。';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return 'ページ当たり最大' + pageNumber + '件';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return '全' + totalRows + '件から、'+ pageFrom + 'から' + pageTo + '件目まで表示しています';\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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ja-JP']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-ka-GE.js",
    "content": "/**\n * Bootstrap Table Georgian translation\n * Author: Levan Lotuashvili <l.lotuashvili@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ka-GE'] = {\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    };\n    \n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ka-GE']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-ko-KR.js",
    "content": "/**\n * Bootstrap Table Korean translation\n * Author: Yi Tae-Hyeong (jsonobject@gmail.com)\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ko-KR'] = {\n        formatLoadingMessage: function () {\n            return '데이터를 불러오는 중입니다...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return '페이지 당 ' + pageNumber + '개 데이터 출력';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return '전체 ' + totalRows + '개 중 ' + pageFrom + '~' + pageTo + '번째 데이터 출력,';\n        },\n        formatSearch: function () {\n            return '검색';\n        },\n        formatNoMatches: function () {\n            return '조회된 데이터가 없습니다.';\n        },\n        formatRefresh: function () {\n            return '새로 고침';\n        },\n        formatToggle: function () {\n            return '전환';\n        },\n        formatColumns: function () {\n            return '컬럼 필터링';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ko-KR']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-ms-MY.js",
    "content": "/**\n * Bootstrap Table Malay translation\n * Author: Azamshul Azizy <azamshul@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ms-MY'] = {\n        formatLoadingMessage: function () {\n            return 'Permintaan sedang dimuatkan. Sila tunggu sebentar...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' rekod setiap muka surat';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Sedang memaparkan rekod ' + pageFrom + ' hingga ' + pageTo + ' daripada jumlah ' + totalRows + ' rekod';\n        },\n        formatSearch: function () {\n            return 'Cari';\n        },\n        formatNoMatches: function () {\n            return 'Tiada rekod yang menyamai permintaan';\n        },\n        formatPaginationSwitch: function () {\n            return 'Tunjuk/sembunyi muka surat';\n        },\n        formatRefresh: function () {\n            return 'Muatsemula';\n        },\n        formatToggle: function () {\n            return 'Tukar';\n        },\n        formatColumns: function () {\n            return 'Lajur';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ms-MY']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-nb-NO.js",
    "content": "/**\n * Bootstrap Table norwegian translation\n * Author: Jim Nordbø, jim@nordb.no\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['nb-NO'] = {\n        formatLoadingMessage: function () {\n            return 'Oppdaterer, vennligst vent...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' poster pr side';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Viser ' + pageFrom + ' til ' + pageTo + ' av ' + totalRows + ' rekker';\n        },\n        formatSearch: function () {\n            return 'Søk';\n        },\n        formatNoMatches: function () {\n            return 'Ingen poster funnet';\n        },\n        formatRefresh: function () {\n            return 'Oppdater';\n        },\n        formatToggle: function () {\n            return 'Endre';\n        },\n        formatColumns: function () {\n            return 'Kolonner';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['nb-NO']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-nl-NL.js",
    "content": "/**\n * Bootstrap Table Dutch translation\n * Author: Your Name <info@a2hankes.nl>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['nl-NL'] = {\n        formatLoadingMessage: function () {\n            return 'Laden, even geduld...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' records per pagina';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Toon ' + pageFrom + ' tot ' + pageTo + ' van ' + totalRows + ' records';\n        },\n        formatSearch: function () {\n            return 'Zoeken';\n        },\n        formatNoMatches: function () {\n            return 'Geen resultaten gevonden';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['nl-NL']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-pl-PL.js",
    "content": "/**\n * Bootstrap Table Polish translation\n * Author: zergu <michal.zagdan @ gmail com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['pl-PL'] = {\n        formatLoadingMessage: function () {\n            return 'Ładowanie, proszę czekać...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' rekordów na stronę';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Wyświetlanie rekordów od ' + pageFrom + ' do ' + pageTo + ' z ' + totalRows;\n        },\n        formatSearch: function () {\n            return 'Szukaj';\n        },\n        formatNoMatches: function () {\n            return 'Niestety, nic nie znaleziono';\n        },\n        formatRefresh: function () {\n            return 'Odśwież';\n        },\n        formatToggle: function () {\n            return 'Przełącz';\n        },\n        formatColumns: function () {\n            return 'Kolumny';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pl-PL']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-pt-BR.js",
    "content": "/**\n * Bootstrap Table Brazilian Portuguese Translation\n * Author: Eduardo Cerqueira<egcerqueira@gmail.com>\n * Update: João Mello<jmello@hotmail.com.br>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['pt-BR'] = {\n        formatLoadingMessage: function () {\n            return 'Carregando, aguarde...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registros por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Exibindo ' + pageFrom + ' até ' + pageTo + ' de ' + totalRows + ' linhas';\n        },\n        formatSearch: function () { \n            return 'Pesquisar';\n        },\n        formatRefresh: function () { \n            return 'Recarregar';\n        },\n        formatToggle: function () { \n            return 'Alternar';\n        },\n        formatColumns: function () { \n            return 'Colunas';\n        },\n        formatPaginationSwitch: function () { \n            return 'Ocultar/Exibir paginação';\n        },\n        formatNoMatches: function () {\n            return 'Nenhum registro encontrado';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pt-BR']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-pt-PT.js",
    "content": "/**\n * Bootstrap Table Portuguese Portugal Translation\n * Author: Burnspirit<burnspirit@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['pt-PT'] = {\n        formatLoadingMessage: function () {\n            return 'A carregar, aguarde...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' registos por página';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'A mostrar ' + pageFrom + ' até ' + pageTo + ' de ' + totalRows + ' linhas';\n        },\n        formatSearch: function () {\n            return 'Pesquisa';\n        },\n        formatNoMatches: function () {\n            return 'Nenhum registo encontrado';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pt-PT']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-ro-RO.js",
    "content": "/**\n * Bootstrap Table Romanian translation\n * Author: cristake <cristianiosif@me.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ro-RO'] = {\n        formatLoadingMessage: function () {\n            return 'Se incarca, va rugam asteptati...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' inregistrari pe pagina';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Arata de la ' + pageFrom + ' pana la ' + pageTo + ' din ' + totalRows + ' randuri';\n        },\n        formatSearch: function () {\n            return 'Cauta';\n        },\n        formatNoMatches: function () {\n            return 'Nu au fost gasite inregistrari';\n        },\n        formatPaginationSwitch: function () {\n            return 'Ascunde/Arata paginatia';\n        },\n        formatRefresh: function () {\n            return 'Reincarca';\n        },\n        formatToggle: function () {\n            return 'Comuta';\n        },\n        formatColumns: function () {\n            return 'Coloane';\n        },\n        formatAllRows: function () {\n            return 'Toate';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ro-RO']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-ru-RU.js",
    "content": "/**\n * Bootstrap Table Russian translation\n * Author: Dunaevsky Maxim <dunmaksim@yandex.ru>\n */\n(function ($) {\n    'use strict';\n    $.fn.bootstrapTable.locales['ru-RU'] = {\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        formatRefresh: function () {\n            return 'Обновить';\n        },\n        formatToggle: function () {\n            return 'Переключить';\n        },\n        formatColumns: function () {\n            return 'Колонки';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ru-RU']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-sk-SK.js",
    "content": "/**\n * Bootstrap Table Slovak translation\n * Author: Jozef Dúc<jozef.d13@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['sk-SK'] = {\n        formatLoadingMessage: function () {\n            return 'Prosím čakajte ...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' záznamov na stranu';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Zobrazená ' + pageFrom + '. - ' + pageTo + '. položka z celkových ' + totalRows;\n        },\n        formatSearch: function () {\n            return 'Vyhľadávanie';\n        },\n        formatNoMatches: function () {\n            return 'Nenájdená žiadne vyhovujúca položka';\n        },\n        formatRefresh: function () {\n            return 'Obnoviť';\n        },\n        formatToggle: function () {\n            return 'Prepni';\n        },\n        formatColumns: function () {\n            return 'Stĺpce';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['sk-SK']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-sv-SE.js",
    "content": "/**\n * Bootstrap Table Swedish translation\n * Author: C Bratt <bratt@inix.se>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['sv-SE'] = {\n        formatLoadingMessage: function () {\n            return 'Laddar, vänligen vänta...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' rader per sida';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Visa ' + pageFrom + ' till ' + pageTo + ' av ' + totalRows + ' rader';\n        },\n        formatSearch: function () {\n            return 'Sök';\n        },\n        formatNoMatches: function () {\n            return 'Inga matchande resultat funna.';\n        },\n        formatRefresh: function () {\n            return 'Uppdatera';\n        },\n        formatToggle: function () {\n            return 'Skifta';\n        },\n        formatColumns: function () {\n            return 'kolumn';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['sv-SE']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-th-TH.js",
    "content": "/**\n * Bootstrap Table Thai translation\n * Author: Monchai S.<monchais@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['th-TH'] = {\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        formatRefresh: function () {\n            return 'รีเฟรส';\n        },\n        formatToggle: function () {\n            return 'สลับมุมมอง';\n        },\n        formatColumns: function () {\n            return 'คอลัมน์';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['th-TH']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-tr-TR.js",
    "content": "/**\n * Bootstrap Table Turkish translation\n * Author: Emin Şen\n * Author: Sercan Cakir <srcnckr@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['tr-TR'] = {\n        formatLoadingMessage: function () {\n            return 'Yükleniyor, lütfen bekleyin...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return 'Sayfa başına ' + pageNumber + ' kayıt.';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return totalRows + ' kayıttan ' + pageFrom + '-' + pageTo + ' arası gösteriliyor.';\n        },\n        formatSearch: function () {\n            return 'Ara';\n        },\n        formatNoMatches: function () {\n            return 'Eşleşen kayıt bulunamadı.';\n        },\n        formatRefresh: function () {\n            return 'Yenile';\n        },\n        formatToggle: function () {\n            return 'Değiştir';\n        },\n        formatColumns: function () {\n            return 'Sütunlar';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['tr-TR']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-uk-UA.js",
    "content": "/**\n * Bootstrap Table Ukrainian translation\n * Author: Vitaliy Timchenko <vitaliy.timchenko@gmail.com>\n */\n (function ($) {\n    'use strict';\n    \n    $.fn.bootstrapTable.locales['uk-UA'] = {\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        formatRefresh: function () {\n            return 'Оновити';\n        },\n        formatToggle: function () {\n            return 'Змінити';\n        },\n        formatColumns: function () {\n            return 'Стовпці';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['uk-UA']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-ur-PK.js",
    "content": "/**\n * Bootstrap Table Urdu translation\n * Author: Malik <me@malikrizwan.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['ur-PK'] = {\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        formatRefresh: function () {\n            return 'تازہ کریں';\n        },\n        formatToggle: function () {\n            return 'تبدیل کریں';\n        },\n        formatColumns: function () {\n            return 'کالم';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ur-PK']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-vi-VN.js",
    "content": "/**\n * Bootstrap Table Vietnamese translation\n * Author: Duc N. PHAM <pngduc@gmail.com>\n */\n(function ($) {\n    'use strict';\n\n    $.fn.bootstrapTable.locales['vi-VN'] = {\n        formatLoadingMessage: function () {\n            return 'Đang tải...';\n        },\n        formatRecordsPerPage: function (pageNumber) {\n            return pageNumber + ' bản ghi mỗi trang';\n        },\n        formatShowingRows: function (pageFrom, pageTo, totalRows) {\n            return 'Hiển thị từ trang ' + pageFrom + ' đến ' + pageTo + ' của ' + totalRows + ' bảng ghi';\n        },\n        formatSearch: function () {\n            return 'Tìm kiếm';\n        },\n        formatNoMatches: function () {\n            return 'Không có dữ liệu';\n        }\n    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['vi-VN']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-CN']);\n\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/bootstrap-table/src/locale/bootstrap-table-zh-TW.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-TW'] = {\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    };\n\n    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-TW']);\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.css",
    "content": "/*\n *  Bootstrap TouchSpin - v3.0.1\n *  A mobile and touch friendly input spinner component for Bootstrap 3.\n *  http://www.virtuosoft.eu/code/bootstrap-touchspin/\n *\n *  Made by István Ujj-Mészáros\n *  Under Apache License v2.0 License\n */\n\n.bootstrap-touchspin .input-group-btn-vertical {\n  position: relative;\n  white-space: nowrap;\n  width: 1%;\n  vertical-align: middle;\n  display: table-cell;\n}\n\n.bootstrap-touchspin .input-group-btn-vertical > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n  padding: 8px 10px;\n  margin-left: -1px;\n  position: relative;\n}\n\n.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up {\n  border-radius: 0;\n  border-top-right-radius: 4px;\n}\n\n.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down {\n  margin-top: -2px;\n  border-radius: 0;\n  border-bottom-right-radius: 4px;\n}\n\n.bootstrap-touchspin .input-group-btn-vertical i {\n  position: absolute;\n  top: 3px;\n  left: 5px;\n  font-size: 9px;\n  font-weight: normal;\n}\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.js",
    "content": "/*\n *  Bootstrap TouchSpin - v3.0.1\n *  A mobile and touch friendly input spinner component for Bootstrap 3.\n *  http://www.virtuosoft.eu/code/bootstrap-touchspin/\n *\n *  Made by István Ujj-Mészáros\n *  Under Apache License v2.0 License\n */\n(function($) {\n  'use strict';\n\n  var _currentSpinnerId = 0;\n\n  function _scopedEventName(name, id) {\n    return name + '.touchspin_' + id;\n  }\n\n  function _scopeEventNames(names, id) {\n    return $.map(names, function(name) {\n      return _scopedEventName(name, id);\n    });\n  }\n\n  $.fn.TouchSpin = function(options) {\n\n    if (options === 'destroy') {\n      this.each(function() {\n        var originalinput = $(this),\n            originalinput_data = originalinput.data();\n        $(document).off(_scopeEventNames([\n          'mouseup',\n          'touchend',\n          'touchcancel',\n          'mousemove',\n          'touchmove',\n          'scroll',\n          'scrollstart'], originalinput_data.spinnerid).join(' '));\n      });\n      return;\n    }\n\n    var defaults = {\n      min: 0,\n      max: 100,\n      initval: '',\n      step: 1,\n      decimals: 0,\n      stepinterval: 100,\n      forcestepdivisibility: 'round', // none | floor | round | ceil\n      stepintervaldelay: 500,\n      verticalbuttons: false,\n      verticalupclass: 'glyphicon glyphicon-chevron-up',\n      verticaldownclass: 'glyphicon glyphicon-chevron-down',\n      prefix: '',\n      postfix: '',\n      prefix_extraclass: '',\n      postfix_extraclass: '',\n      booster: true,\n      boostat: 10,\n      maxboostedstep: false,\n      mousewheel: true,\n      buttondown_class: 'btn btn-default',\n      buttonup_class: 'btn btn-default'\n    };\n\n    var attributeMap = {\n      min: 'min',\n      max: 'max',\n      initval: 'init-val',\n      step: 'step',\n      decimals: 'decimals',\n      stepinterval: 'step-interval',\n      verticalbuttons: 'vertical-buttons',\n      verticalupclass: 'vertical-up-class',\n      verticaldownclass: 'vertical-down-class',\n      forcestepdivisibility: 'force-step-divisibility',\n      stepintervaldelay: 'step-interval-delay',\n      prefix: 'prefix',\n      postfix: 'postfix',\n      prefix_extraclass: 'prefix-extra-class',\n      postfix_extraclass: 'postfix-extra-class',\n      booster: 'booster',\n      boostat: 'boostat',\n      maxboostedstep: 'max-boosted-step',\n      mousewheel: 'mouse-wheel',\n      buttondown_class: 'button-down-class',\n      buttonup_class: 'button-up-class'\n    };\n\n    return this.each(function() {\n\n      var settings,\n          originalinput = $(this),\n          originalinput_data = originalinput.data(),\n          container,\n          elements,\n          value,\n          downSpinTimer,\n          upSpinTimer,\n          downDelayTimeout,\n          upDelayTimeout,\n          spincount = 0,\n          spinning = false;\n\n      init();\n\n\n      function init() {\n        if (originalinput.data('alreadyinitialized')) {\n          return;\n        }\n\n        originalinput.data('alreadyinitialized', true);\n        _currentSpinnerId += 1;\n        originalinput.data('spinnerid', _currentSpinnerId);\n\n\n        if (!originalinput.is('input')) {\n          console.log('Must be an input.');\n          return;\n        }\n\n        _initSettings();\n        _setInitval();\n        _checkValue();\n        _buildHtml();\n        _initElements();\n        _hideEmptyPrefixPostfix();\n        _bindEvents();\n        _bindEventsInterface();\n        elements.input.css('display', 'block');\n      }\n\n      function _setInitval() {\n        if (settings.initval !== '' && originalinput.val() === '') {\n          originalinput.val(settings.initval);\n        }\n      }\n\n      function changeSettings(newsettings) {\n        _updateSettings(newsettings);\n        _checkValue();\n\n        var value = elements.input.val();\n\n        if (value !== '') {\n          value = Number(elements.input.val());\n          elements.input.val(value.toFixed(settings.decimals));\n        }\n      }\n\n      function _initSettings() {\n        settings = $.extend({}, defaults, originalinput_data, _parseAttributes(), options);\n      }\n\n      function _parseAttributes() {\n        var data = {};\n        $.each(attributeMap, function(key, value) {\n          var attrName = 'bts-' + value + '';\n          if (originalinput.is('[data-' + attrName + ']')) {\n            data[key] = originalinput.data(attrName);\n          }\n        });\n        return data;\n      }\n\n      function _updateSettings(newsettings) {\n        settings = $.extend({}, settings, newsettings);\n      }\n\n      function _buildHtml() {\n        var initval = originalinput.val(),\n            parentelement = originalinput.parent();\n\n        if (initval !== '') {\n          initval = Number(initval).toFixed(settings.decimals);\n        }\n\n        originalinput.data('initvalue', initval).val(initval);\n        originalinput.addClass('form-control');\n\n        if (parentelement.hasClass('input-group')) {\n          _advanceInputGroup(parentelement);\n        }\n        else {\n          _buildInputGroup();\n        }\n      }\n\n      function _advanceInputGroup(parentelement) {\n        parentelement.addClass('bootstrap-touchspin');\n\n        var prev = originalinput.prev(),\n            next = originalinput.next();\n\n        var downhtml,\n            uphtml,\n            prefixhtml = '<span class=\"input-group-addon bootstrap-touchspin-prefix\">' + settings.prefix + '</span>',\n            postfixhtml = '<span class=\"input-group-addon bootstrap-touchspin-postfix\">' + settings.postfix + '</span>';\n\n        if (prev.hasClass('input-group-btn')) {\n          downhtml = '<button class=\"' + settings.buttondown_class + ' bootstrap-touchspin-down\" type=\"button\">-</button>';\n          prev.append(downhtml);\n        }\n        else {\n          downhtml = '<span class=\"input-group-btn\"><button class=\"' + settings.buttondown_class + ' bootstrap-touchspin-down\" type=\"button\">-</button></span>';\n          $(downhtml).insertBefore(originalinput);\n        }\n\n        if (next.hasClass('input-group-btn')) {\n          uphtml = '<button class=\"' + settings.buttonup_class + ' bootstrap-touchspin-up\" type=\"button\">+</button>';\n          next.prepend(uphtml);\n        }\n        else {\n          uphtml = '<span class=\"input-group-btn\"><button class=\"' + settings.buttonup_class + ' bootstrap-touchspin-up\" type=\"button\">+</button></span>';\n          $(uphtml).insertAfter(originalinput);\n        }\n\n        $(prefixhtml).insertBefore(originalinput);\n        $(postfixhtml).insertAfter(originalinput);\n\n        container = parentelement;\n      }\n\n      function _buildInputGroup() {\n        var html;\n\n        if (settings.verticalbuttons) {\n          html = '<div class=\"input-group bootstrap-touchspin\"><span class=\"input-group-addon bootstrap-touchspin-prefix\">' + settings.prefix + '</span><span class=\"input-group-addon bootstrap-touchspin-postfix\">' + settings.postfix + '</span><span class=\"input-group-btn-vertical\"><button class=\"' + settings.buttondown_class + ' bootstrap-touchspin-up\" type=\"button\"><i class=\"' + settings.verticalupclass + '\"></i></button><button class=\"' + settings.buttonup_class + ' bootstrap-touchspin-down\" type=\"button\"><i class=\"' + settings.verticaldownclass + '\"></i></button></span></div>';\n        }\n        else {\n          html = '<div class=\"input-group bootstrap-touchspin\"><span class=\"input-group-btn\"><button class=\"' + settings.buttondown_class + ' bootstrap-touchspin-down\" type=\"button\">-</button></span><span class=\"input-group-addon bootstrap-touchspin-prefix\">' + settings.prefix + '</span><span class=\"input-group-addon bootstrap-touchspin-postfix\">' + settings.postfix + '</span><span class=\"input-group-btn\"><button class=\"' + settings.buttonup_class + ' bootstrap-touchspin-up\" type=\"button\">+</button></span></div>';\n        }\n\n        container = $(html).insertBefore(originalinput);\n\n        $('.bootstrap-touchspin-prefix', container).after(originalinput);\n\n        if (originalinput.hasClass('input-sm')) {\n          container.addClass('input-group-sm');\n        }\n        else if (originalinput.hasClass('input-lg')) {\n          container.addClass('input-group-lg');\n        }\n      }\n\n      function _initElements() {\n        elements = {\n          down: $('.bootstrap-touchspin-down', container),\n          up: $('.bootstrap-touchspin-up', container),\n          input: $('input', container),\n          prefix: $('.bootstrap-touchspin-prefix', container).addClass(settings.prefix_extraclass),\n          postfix: $('.bootstrap-touchspin-postfix', container).addClass(settings.postfix_extraclass)\n        };\n      }\n\n      function _hideEmptyPrefixPostfix() {\n        if (settings.prefix === '') {\n          elements.prefix.hide();\n        }\n\n        if (settings.postfix === '') {\n          elements.postfix.hide();\n        }\n      }\n\n      function _bindEvents() {\n        originalinput.on('keydown', function(ev) {\n          var code = ev.keyCode || ev.which;\n\n          if (code === 38) {\n            if (spinning !== 'up') {\n              upOnce();\n              startUpSpin();\n            }\n            ev.preventDefault();\n          }\n          else if (code === 40) {\n            if (spinning !== 'down') {\n              downOnce();\n              startDownSpin();\n            }\n            ev.preventDefault();\n          }\n        });\n\n        originalinput.on('keyup', function(ev) {\n          var code = ev.keyCode || ev.which;\n\n          if (code === 38) {\n            stopSpin();\n          }\n          else if (code === 40) {\n            stopSpin();\n          }\n        });\n\n        originalinput.on('blur', function() {\n          _checkValue();\n        });\n\n        elements.down.on('keydown', function(ev) {\n          var code = ev.keyCode || ev.which;\n\n          if (code === 32 || code === 13) {\n            if (spinning !== 'down') {\n              downOnce();\n              startDownSpin();\n            }\n            ev.preventDefault();\n          }\n        });\n\n        elements.down.on('keyup', function(ev) {\n          var code = ev.keyCode || ev.which;\n\n          if (code === 32 || code === 13) {\n            stopSpin();\n          }\n        });\n\n        elements.up.on('keydown', function(ev) {\n          var code = ev.keyCode || ev.which;\n\n          if (code === 32 || code === 13) {\n            if (spinning !== 'up') {\n              upOnce();\n              startUpSpin();\n            }\n            ev.preventDefault();\n          }\n        });\n\n        elements.up.on('keyup', function(ev) {\n          var code = ev.keyCode || ev.which;\n\n          if (code === 32 || code === 13) {\n            stopSpin();\n          }\n        });\n\n        elements.down.on('mousedown.touchspin', function(ev) {\n          elements.down.off('touchstart.touchspin');  // android 4 workaround\n\n          if (originalinput.is(':disabled')) {\n            return;\n          }\n\n          downOnce();\n          startDownSpin();\n\n          ev.preventDefault();\n          ev.stopPropagation();\n        });\n\n        elements.down.on('touchstart.touchspin', function(ev) {\n          elements.down.off('mousedown.touchspin');  // android 4 workaround\n\n          if (originalinput.is(':disabled')) {\n            return;\n          }\n\n          downOnce();\n          startDownSpin();\n\n          ev.preventDefault();\n          ev.stopPropagation();\n        });\n\n        elements.up.on('mousedown.touchspin', function(ev) {\n          elements.up.off('touchstart.touchspin');  // android 4 workaround\n\n          if (originalinput.is(':disabled')) {\n            return;\n          }\n\n          upOnce();\n          startUpSpin();\n\n          ev.preventDefault();\n          ev.stopPropagation();\n        });\n\n        elements.up.on('touchstart.touchspin', function(ev) {\n          elements.up.off('mousedown.touchspin');  // android 4 workaround\n\n          if (originalinput.is(':disabled')) {\n            return;\n          }\n\n          upOnce();\n          startUpSpin();\n\n          ev.preventDefault();\n          ev.stopPropagation();\n        });\n\n        elements.up.on('mouseout touchleave touchend touchcancel', function(ev) {\n          if (!spinning) {\n            return;\n          }\n\n          ev.stopPropagation();\n          stopSpin();\n        });\n\n        elements.down.on('mouseout touchleave touchend touchcancel', function(ev) {\n          if (!spinning) {\n            return;\n          }\n\n          ev.stopPropagation();\n          stopSpin();\n        });\n\n        elements.down.on('mousemove touchmove', function(ev) {\n          if (!spinning) {\n            return;\n          }\n\n          ev.stopPropagation();\n          ev.preventDefault();\n        });\n\n        elements.up.on('mousemove touchmove', function(ev) {\n          if (!spinning) {\n            return;\n          }\n\n          ev.stopPropagation();\n          ev.preventDefault();\n        });\n\n        $(document).on(_scopeEventNames(['mouseup', 'touchend', 'touchcancel'], _currentSpinnerId).join(' '), function(ev) {\n          if (!spinning) {\n            return;\n          }\n\n          ev.preventDefault();\n          stopSpin();\n        });\n\n        $(document).on(_scopeEventNames(['mousemove', 'touchmove', 'scroll', 'scrollstart'], _currentSpinnerId).join(' '), function(ev) {\n          if (!spinning) {\n            return;\n          }\n\n          ev.preventDefault();\n          stopSpin();\n        });\n\n        originalinput.on('mousewheel DOMMouseScroll', function(ev) {\n          if (!settings.mousewheel || !originalinput.is(':focus')) {\n            return;\n          }\n\n          var delta = ev.originalEvent.wheelDelta || -ev.originalEvent.deltaY || -ev.originalEvent.detail;\n\n          ev.stopPropagation();\n          ev.preventDefault();\n\n          if (delta < 0) {\n            downOnce();\n          }\n          else {\n            upOnce();\n          }\n        });\n      }\n\n      function _bindEventsInterface() {\n        originalinput.on('touchspin.uponce', function() {\n          stopSpin();\n          upOnce();\n        });\n\n        originalinput.on('touchspin.downonce', function() {\n          stopSpin();\n          downOnce();\n        });\n\n        originalinput.on('touchspin.startupspin', function() {\n          startUpSpin();\n        });\n\n        originalinput.on('touchspin.startdownspin', function() {\n          startDownSpin();\n        });\n\n        originalinput.on('touchspin.stopspin', function() {\n          stopSpin();\n        });\n\n        originalinput.on('touchspin.updatesettings', function(e, newsettings) {\n          changeSettings(newsettings);\n        });\n      }\n\n      function _forcestepdivisibility(value) {\n        switch (settings.forcestepdivisibility) {\n          case 'round':\n            return (Math.round(value / settings.step) * settings.step).toFixed(settings.decimals);\n          case 'floor':\n            return (Math.floor(value / settings.step) * settings.step).toFixed(settings.decimals);\n          case 'ceil':\n            return (Math.ceil(value / settings.step) * settings.step).toFixed(settings.decimals);\n          default:\n            return value;\n        }\n      }\n\n      function _checkValue() {\n        var val, parsedval, returnval;\n\n        val = originalinput.val();\n\n        if (val === '') {\n          return;\n        }\n\n        if (settings.decimals > 0 && val === '.') {\n          return;\n        }\n\n        parsedval = parseFloat(val);\n\n        if (isNaN(parsedval)) {\n          parsedval = 0;\n        }\n\n        returnval = parsedval;\n\n        if (parsedval.toString() !== val) {\n          returnval = parsedval;\n        }\n\n        if (parsedval < settings.min) {\n          returnval = settings.min;\n        }\n\n        if (parsedval > settings.max) {\n          returnval = settings.max;\n        }\n\n        returnval = _forcestepdivisibility(returnval);\n\n        if (Number(val).toString() !== returnval.toString()) {\n          originalinput.val(returnval);\n          originalinput.trigger('change');\n        }\n      }\n\n      function _getBoostedStep() {\n        if (!settings.booster) {\n          return settings.step;\n        }\n        else {\n          var boosted = Math.pow(2, Math.floor(spincount / settings.boostat)) * settings.step;\n\n          if (settings.maxboostedstep) {\n            if (boosted > settings.maxboostedstep) {\n              boosted = settings.maxboostedstep;\n              value = Math.round((value / boosted)) * boosted;\n            }\n          }\n\n          return Math.max(settings.step, boosted);\n        }\n      }\n\n      function upOnce() {\n        _checkValue();\n\n        value = parseFloat(elements.input.val());\n        if (isNaN(value)) {\n          value = 0;\n        }\n\n        var initvalue = value,\n            boostedstep = _getBoostedStep();\n\n        value = value + boostedstep;\n\n        if (value > settings.max) {\n          value = settings.max;\n          originalinput.trigger('touchspin.on.max');\n          stopSpin();\n        }\n\n        elements.input.val(Number(value).toFixed(settings.decimals));\n\n        if (initvalue !== value) {\n          originalinput.trigger('change');\n        }\n      }\n\n      function downOnce() {\n        _checkValue();\n\n        value = parseFloat(elements.input.val());\n        if (isNaN(value)) {\n          value = 0;\n        }\n\n        var initvalue = value,\n            boostedstep = _getBoostedStep();\n\n        value = value - boostedstep;\n\n        if (value < settings.min) {\n          value = settings.min;\n          originalinput.trigger('touchspin.on.min');\n          stopSpin();\n        }\n\n        elements.input.val(value.toFixed(settings.decimals));\n\n        if (initvalue !== value) {\n          originalinput.trigger('change');\n        }\n      }\n\n      function startDownSpin() {\n        stopSpin();\n\n        spincount = 0;\n        spinning = 'down';\n\n        originalinput.trigger('touchspin.on.startspin');\n        originalinput.trigger('touchspin.on.startdownspin');\n\n        downDelayTimeout = setTimeout(function() {\n          downSpinTimer = setInterval(function() {\n            spincount++;\n            downOnce();\n          }, settings.stepinterval);\n        }, settings.stepintervaldelay);\n      }\n\n      function startUpSpin() {\n        stopSpin();\n\n        spincount = 0;\n        spinning = 'up';\n\n        originalinput.trigger('touchspin.on.startspin');\n        originalinput.trigger('touchspin.on.startupspin');\n\n        upDelayTimeout = setTimeout(function() {\n          upSpinTimer = setInterval(function() {\n            spincount++;\n            upOnce();\n          }, settings.stepinterval);\n        }, settings.stepintervaldelay);\n      }\n\n      function stopSpin() {\n        clearTimeout(downDelayTimeout);\n        clearTimeout(upDelayTimeout);\n        clearInterval(downSpinTimer);\n        clearInterval(upSpinTimer);\n\n        switch (spinning) {\n          case 'up':\n            originalinput.trigger('touchspin.on.stopupspin');\n            originalinput.trigger('touchspin.on.stopspin');\n            break;\n          case 'down':\n            originalinput.trigger('touchspin.on.stopdownspin');\n            originalinput.trigger('touchspin.on.stopspin');\n            break;\n        }\n\n        spincount = 0;\n        spinning = false;\n      }\n\n    });\n\n  };\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-touchspin/src/jquery.bootstrap-touchspin.css",
    "content": "\n.bootstrap-touchspin .input-group-btn-vertical {\n  position: relative;\n  white-space: nowrap;\n  width: 1%;\n  vertical-align: middle;\n  display: table-cell;\n}\n\n.bootstrap-touchspin .input-group-btn-vertical > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n  padding: 8px 10px;\n  margin-left: -1px;\n  position: relative;\n}\n\n.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up {\n  border-radius: 0;\n  border-top-right-radius: 4px;\n}\n\n.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down {\n  margin-top: -2px;\n  border-radius: 0;\n  border-bottom-right-radius: 4px;\n}\n\n.bootstrap-touchspin .input-group-btn-vertical i {\n  position: absolute;\n  top: 3px;\n  left: 5px;\n  font-size: 9px;\n  font-weight: normal;\n}\n"
  },
  {
    "path": "static/assets/plugins/bootstrap-touchspin/src/jquery.bootstrap-touchspin.js",
    "content": "(function($) {\n  'use strict';\n\n  var _currentSpinnerId = 0;\n\n  function _scopedEventName(name, id) {\n    return name + '.touchspin_' + id;\n  }\n\n  function _scopeEventNames(names, id) {\n    return $.map(names, function(name) {\n      return _scopedEventName(name, id);\n    });\n  }\n\n  $.fn.TouchSpin = function(options) {\n\n    if (options === 'destroy') {\n      this.each(function() {\n        var originalinput = $(this),\n            originalinput_data = originalinput.data();\n        $(document).off(_scopeEventNames([\n          'mouseup',\n          'touchend',\n          'touchcancel',\n          'mousemove',\n          'touchmove',\n          'scroll',\n          'scrollstart'], originalinput_data.spinnerid).join(' '));\n      });\n      return;\n    }\n\n    var defaults = {\n      min: 0,\n      max: 100,\n      initval: '',\n      step: 1,\n      decimals: 0,\n      stepinterval: 100,\n      forcestepdivisibility: 'round', // none | floor | round | ceil\n      stepintervaldelay: 500,\n      verticalbuttons: false,\n      verticalupclass: 'glyphicon glyphicon-chevron-up',\n      verticaldownclass: 'glyphicon glyphicon-chevron-down',\n      prefix: '',\n      postfix: '',\n      prefix_extraclass: '',\n      postfix_extraclass: '',\n      booster: true,\n      boostat: 10,\n      maxboostedstep: false,\n      mousewheel: true,\n      buttondown_class: 'btn btn-default',\n      buttonup_class: 'btn btn-default'\n    };\n\n    var attributeMap = {\n      min: 'min',\n      max: 'max',\n      initval: 'init-val',\n      step: 'step',\n      decimals: 'decimals',\n      stepinterval: 'step-interval',\n      verticalbuttons: 'vertical-buttons',\n      verticalupclass: 'vertical-up-class',\n      verticaldownclass: 'vertical-down-class',\n      forcestepdivisibility: 'force-step-divisibility',\n      stepintervaldelay: 'step-interval-delay',\n      prefix: 'prefix',\n      postfix: 'postfix',\n      prefix_extraclass: 'prefix-extra-class',\n      postfix_extraclass: 'postfix-extra-class',\n      booster: 'booster',\n      boostat: 'boostat',\n      maxboostedstep: 'max-boosted-step',\n      mousewheel: 'mouse-wheel',\n      buttondown_class: 'button-down-class',\n      buttonup_class: 'button-up-class'\n    };\n\n    return this.each(function() {\n\n      var settings,\n          originalinput = $(this),\n          originalinput_data = originalinput.data(),\n          container,\n          elements,\n          value,\n          downSpinTimer,\n          upSpinTimer,\n          downDelayTimeout,\n          upDelayTimeout,\n          spincount = 0,\n          spinning = false;\n\n      init();\n\n\n      function init() {\n        if (originalinput.data('alreadyinitialized')) {\n          return;\n        }\n\n        originalinput.data('alreadyinitialized', true);\n        _currentSpinnerId += 1;\n        originalinput.data('spinnerid', _currentSpinnerId);\n\n\n        if (!originalinput.is('input')) {\n          console.log('Must be an input.');\n          return;\n        }\n\n        _initSettings();\n        _setInitval();\n        _checkValue();\n        _buildHtml();\n        _initElements();\n        _hideEmptyPrefixPostfix();\n        _bindEvents();\n        _bindEventsInterface();\n        elements.input.css('display', 'block');\n      }\n\n      function _setInitval() {\n        if (settings.initval !== '' && originalinput.val() === '') {\n          originalinput.val(settings.initval);\n        }\n      }\n\n      function changeSettings(newsettings) {\n        _updateSettings(newsettings);\n        _checkValue();\n\n        var value = elements.input.val();\n\n        if (value !== '') {\n          value = Number(elements.input.val());\n          elements.input.val(value.toFixed(settings.decimals));\n        }\n      }\n\n      function _initSettings() {\n        settings = $.extend({}, defaults, originalinput_data, _parseAttributes(), options);\n      }\n\n      function _parseAttributes() {\n        var data = {};\n        $.each(attributeMap, function(key, value) {\n          var attrName = 'bts-' + value + '';\n          if (originalinput.is('[data-' + attrName + ']')) {\n            data[key] = originalinput.data(attrName);\n          }\n        });\n        return data;\n      }\n\n      function _updateSettings(newsettings) {\n        settings = $.extend({}, settings, newsettings);\n      }\n\n      function _buildHtml() {\n        var initval = originalinput.val(),\n            parentelement = originalinput.parent();\n\n        if (initval !== '') {\n          initval = Number(initval).toFixed(settings.decimals);\n        }\n\n        originalinput.data('initvalue', initval).val(initval);\n        originalinput.addClass('form-control');\n\n        if (parentelement.hasClass('input-group')) {\n          _advanceInputGroup(parentelement);\n        }\n        else {\n          _buildInputGroup();\n        }\n      }\n\n      function _advanceInputGroup(parentelement) {\n        parentelement.addClass('bootstrap-touchspin');\n\n        var prev = originalinput.prev(),\n            next = originalinput.next();\n\n        var downhtml,\n            uphtml,\n            prefixhtml = '<span class=\"input-group-addon bootstrap-touchspin-prefix\">' + settings.prefix + '</span>',\n            postfixhtml = '<span class=\"input-group-addon bootstrap-touchspin-postfix\">' + settings.postfix + '</span>';\n\n        if (prev.hasClass('input-group-btn')) {\n          downhtml = '<button class=\"' + settings.buttondown_class + ' bootstrap-touchspin-down\" type=\"button\">-</button>';\n          prev.append(downhtml);\n        }\n        else {\n          downhtml = '<span class=\"input-group-btn\"><button class=\"' + settings.buttondown_class + ' bootstrap-touchspin-down\" type=\"button\">-</button></span>';\n          $(downhtml).insertBefore(originalinput);\n        }\n\n        if (next.hasClass('input-group-btn')) {\n          uphtml = '<button class=\"' + settings.buttonup_class + ' bootstrap-touchspin-up\" type=\"button\">+</button>';\n          next.prepend(uphtml);\n        }\n        else {\n          uphtml = '<span class=\"input-group-btn\"><button class=\"' + settings.buttonup_class + ' bootstrap-touchspin-up\" type=\"button\">+</button></span>';\n          $(uphtml).insertAfter(originalinput);\n        }\n\n        $(prefixhtml).insertBefore(originalinput);\n        $(postfixhtml).insertAfter(originalinput);\n\n        container = parentelement;\n      }\n\n      function _buildInputGroup() {\n        var html;\n\n        if (settings.verticalbuttons) {\n          html = '<div class=\"input-group bootstrap-touchspin\"><span class=\"input-group-addon bootstrap-touchspin-prefix\">' + settings.prefix + '</span><span class=\"input-group-addon bootstrap-touchspin-postfix\">' + settings.postfix + '</span><span class=\"input-group-btn-vertical\"><button class=\"' + settings.buttondown_class + ' bootstrap-touchspin-up\" type=\"button\"><i class=\"' + settings.verticalupclass + '\"></i></button><button class=\"' + settings.buttonup_class + ' bootstrap-touchspin-down\" type=\"button\"><i class=\"' + settings.verticaldownclass + '\"></i></button></span></div>';\n        }\n        else {\n          html = '<div class=\"input-group bootstrap-touchspin\"><span class=\"input-group-btn\"><button class=\"' + settings.buttondown_class + ' bootstrap-touchspin-down\" type=\"button\">-</button></span><span class=\"input-group-addon bootstrap-touchspin-prefix\">' + settings.prefix + '</span><span class=\"input-group-addon bootstrap-touchspin-postfix\">' + settings.postfix + '</span><span class=\"input-group-btn\"><button class=\"' + settings.buttonup_class + ' bootstrap-touchspin-up\" type=\"button\">+</button></span></div>';\n        }\n\n        container = $(html).insertBefore(originalinput);\n\n        $('.bootstrap-touchspin-prefix', container).after(originalinput);\n\n        if (originalinput.hasClass('input-sm')) {\n          container.addClass('input-group-sm');\n        }\n        else if (originalinput.hasClass('input-lg')) {\n          container.addClass('input-group-lg');\n        }\n      }\n\n      function _initElements() {\n        elements = {\n          down: $('.bootstrap-touchspin-down', container),\n          up: $('.bootstrap-touchspin-up', container),\n          input: $('input', container),\n          prefix: $('.bootstrap-touchspin-prefix', container).addClass(settings.prefix_extraclass),\n          postfix: $('.bootstrap-touchspin-postfix', container).addClass(settings.postfix_extraclass)\n        };\n      }\n\n      function _hideEmptyPrefixPostfix() {\n        if (settings.prefix === '') {\n          elements.prefix.hide();\n        }\n\n        if (settings.postfix === '') {\n          elements.postfix.hide();\n        }\n      }\n\n      function _bindEvents() {\n        originalinput.on('keydown', function(ev) {\n          var code = ev.keyCode || ev.which;\n\n          if (code === 38) {\n            if (spinning !== 'up') {\n              upOnce();\n              startUpSpin();\n            }\n            ev.preventDefault();\n          }\n          else if (code === 40) {\n            if (spinning !== 'down') {\n              downOnce();\n              startDownSpin();\n            }\n            ev.preventDefault();\n          }\n        });\n\n        originalinput.on('keyup', function(ev) {\n          var code = ev.keyCode || ev.which;\n\n          if (code === 38) {\n            stopSpin();\n          }\n          else if (code === 40) {\n            stopSpin();\n          }\n        });\n\n        originalinput.on('blur', function() {\n          _checkValue();\n        });\n\n        elements.down.on('keydown', function(ev) {\n          var code = ev.keyCode || ev.which;\n\n          if (code === 32 || code === 13) {\n            if (spinning !== 'down') {\n              downOnce();\n              startDownSpin();\n            }\n            ev.preventDefault();\n          }\n        });\n\n        elements.down.on('keyup', function(ev) {\n          var code = ev.keyCode || ev.which;\n\n          if (code === 32 || code === 13) {\n            stopSpin();\n          }\n        });\n\n        elements.up.on('keydown', function(ev) {\n          var code = ev.keyCode || ev.which;\n\n          if (code === 32 || code === 13) {\n            if (spinning !== 'up') {\n              upOnce();\n              startUpSpin();\n            }\n            ev.preventDefault();\n          }\n        });\n\n        elements.up.on('keyup', function(ev) {\n          var code = ev.keyCode || ev.which;\n\n          if (code === 32 || code === 13) {\n            stopSpin();\n          }\n        });\n\n        elements.down.on('mousedown.touchspin', function(ev) {\n          elements.down.off('touchstart.touchspin');  // android 4 workaround\n\n          if (originalinput.is(':disabled')) {\n            return;\n          }\n\n          downOnce();\n          startDownSpin();\n\n          ev.preventDefault();\n          ev.stopPropagation();\n        });\n\n        elements.down.on('touchstart.touchspin', function(ev) {\n          elements.down.off('mousedown.touchspin');  // android 4 workaround\n\n          if (originalinput.is(':disabled')) {\n            return;\n          }\n\n          downOnce();\n          startDownSpin();\n\n          ev.preventDefault();\n          ev.stopPropagation();\n        });\n\n        elements.up.on('mousedown.touchspin', function(ev) {\n          elements.up.off('touchstart.touchspin');  // android 4 workaround\n\n          if (originalinput.is(':disabled')) {\n            return;\n          }\n\n          upOnce();\n          startUpSpin();\n\n          ev.preventDefault();\n          ev.stopPropagation();\n        });\n\n        elements.up.on('touchstart.touchspin', function(ev) {\n          elements.up.off('mousedown.touchspin');  // android 4 workaround\n\n          if (originalinput.is(':disabled')) {\n            return;\n          }\n\n          upOnce();\n          startUpSpin();\n\n          ev.preventDefault();\n          ev.stopPropagation();\n        });\n\n        elements.up.on('mouseout touchleave touchend touchcancel', function(ev) {\n          if (!spinning) {\n            return;\n          }\n\n          ev.stopPropagation();\n          stopSpin();\n        });\n\n        elements.down.on('mouseout touchleave touchend touchcancel', function(ev) {\n          if (!spinning) {\n            return;\n          }\n\n          ev.stopPropagation();\n          stopSpin();\n        });\n\n        elements.down.on('mousemove touchmove', function(ev) {\n          if (!spinning) {\n            return;\n          }\n\n          ev.stopPropagation();\n          ev.preventDefault();\n        });\n\n        elements.up.on('mousemove touchmove', function(ev) {\n          if (!spinning) {\n            return;\n          }\n\n          ev.stopPropagation();\n          ev.preventDefault();\n        });\n\n        $(document).on(_scopeEventNames(['mouseup', 'touchend', 'touchcancel'], _currentSpinnerId).join(' '), function(ev) {\n          if (!spinning) {\n            return;\n          }\n\n          ev.preventDefault();\n          stopSpin();\n        });\n\n        $(document).on(_scopeEventNames(['mousemove', 'touchmove', 'scroll', 'scrollstart'], _currentSpinnerId).join(' '), function(ev) {\n          if (!spinning) {\n            return;\n          }\n\n          ev.preventDefault();\n          stopSpin();\n        });\n\n        originalinput.on('mousewheel DOMMouseScroll', function(ev) {\n          if (!settings.mousewheel || !originalinput.is(':focus')) {\n            return;\n          }\n\n          var delta = ev.originalEvent.wheelDelta || -ev.originalEvent.deltaY || -ev.originalEvent.detail;\n\n          ev.stopPropagation();\n          ev.preventDefault();\n\n          if (delta < 0) {\n            downOnce();\n          }\n          else {\n            upOnce();\n          }\n        });\n      }\n\n      function _bindEventsInterface() {\n        originalinput.on('touchspin.uponce', function() {\n          stopSpin();\n          upOnce();\n        });\n\n        originalinput.on('touchspin.downonce', function() {\n          stopSpin();\n          downOnce();\n        });\n\n        originalinput.on('touchspin.startupspin', function() {\n          startUpSpin();\n        });\n\n        originalinput.on('touchspin.startdownspin', function() {\n          startDownSpin();\n        });\n\n        originalinput.on('touchspin.stopspin', function() {\n          stopSpin();\n        });\n\n        originalinput.on('touchspin.updatesettings', function(e, newsettings) {\n          changeSettings(newsettings);\n        });\n      }\n\n      function _forcestepdivisibility(value) {\n        switch (settings.forcestepdivisibility) {\n          case 'round':\n            return (Math.round(value / settings.step) * settings.step).toFixed(settings.decimals);\n          case 'floor':\n            return (Math.floor(value / settings.step) * settings.step).toFixed(settings.decimals);\n          case 'ceil':\n            return (Math.ceil(value / settings.step) * settings.step).toFixed(settings.decimals);\n          default:\n            return value;\n        }\n      }\n\n      function _checkValue() {\n        var val, parsedval, returnval;\n\n        val = originalinput.val();\n\n        if (val === '') {\n          return;\n        }\n\n        if (settings.decimals > 0 && val === '.') {\n          return;\n        }\n\n        parsedval = parseFloat(val);\n\n        if (isNaN(parsedval)) {\n          parsedval = 0;\n        }\n\n        returnval = parsedval;\n\n        if (parsedval.toString() !== val) {\n          returnval = parsedval;\n        }\n\n        if (parsedval < settings.min) {\n          returnval = settings.min;\n        }\n\n        if (parsedval > settings.max) {\n          returnval = settings.max;\n        }\n\n        returnval = _forcestepdivisibility(returnval);\n\n        if (Number(val).toString() !== returnval.toString()) {\n          originalinput.val(returnval);\n          originalinput.trigger('change');\n        }\n      }\n\n      function _getBoostedStep() {\n        if (!settings.booster) {\n          return settings.step;\n        }\n        else {\n          var boosted = Math.pow(2, Math.floor(spincount / settings.boostat)) * settings.step;\n\n          if (settings.maxboostedstep) {\n            if (boosted > settings.maxboostedstep) {\n              boosted = settings.maxboostedstep;\n              value = Math.round((value / boosted)) * boosted;\n            }\n          }\n\n          return Math.max(settings.step, boosted);\n        }\n      }\n\n      function upOnce() {\n        _checkValue();\n\n        value = parseFloat(elements.input.val());\n        if (isNaN(value)) {\n          value = 0;\n        }\n\n        var initvalue = value,\n            boostedstep = _getBoostedStep();\n\n        value = value + boostedstep;\n\n        if (value > settings.max) {\n          value = settings.max;\n          originalinput.trigger('touchspin.on.max');\n          stopSpin();\n        }\n\n        elements.input.val(Number(value).toFixed(settings.decimals));\n\n        if (initvalue !== value) {\n          originalinput.trigger('change');\n        }\n      }\n\n      function downOnce() {\n        _checkValue();\n\n        value = parseFloat(elements.input.val());\n        if (isNaN(value)) {\n          value = 0;\n        }\n\n        var initvalue = value,\n            boostedstep = _getBoostedStep();\n\n        value = value - boostedstep;\n\n        if (value < settings.min) {\n          value = settings.min;\n          originalinput.trigger('touchspin.on.min');\n          stopSpin();\n        }\n\n        elements.input.val(value.toFixed(settings.decimals));\n\n        if (initvalue !== value) {\n          originalinput.trigger('change');\n        }\n      }\n\n      function startDownSpin() {\n        stopSpin();\n\n        spincount = 0;\n        spinning = 'down';\n\n        originalinput.trigger('touchspin.on.startspin');\n        originalinput.trigger('touchspin.on.startdownspin');\n\n        downDelayTimeout = setTimeout(function() {\n          downSpinTimer = setInterval(function() {\n            spincount++;\n            downOnce();\n          }, settings.stepinterval);\n        }, settings.stepintervaldelay);\n      }\n\n      function startUpSpin() {\n        stopSpin();\n\n        spincount = 0;\n        spinning = 'up';\n\n        originalinput.trigger('touchspin.on.startspin');\n        originalinput.trigger('touchspin.on.startupspin');\n\n        upDelayTimeout = setTimeout(function() {\n          upSpinTimer = setInterval(function() {\n            spincount++;\n            upOnce();\n          }, settings.stepinterval);\n        }, settings.stepintervaldelay);\n      }\n\n      function stopSpin() {\n        clearTimeout(downDelayTimeout);\n        clearTimeout(upDelayTimeout);\n        clearInterval(downSpinTimer);\n        clearInterval(upSpinTimer);\n\n        switch (spinning) {\n          case 'up':\n            originalinput.trigger('touchspin.on.stopupspin');\n            originalinput.trigger('touchspin.on.stopspin');\n            break;\n          case 'down':\n            originalinput.trigger('touchspin.on.stopdownspin');\n            originalinput.trigger('touchspin.on.stopspin');\n            break;\n        }\n\n        spincount = 0;\n        spinning = false;\n      }\n\n    });\n\n  };\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/custombox/src/css/custombox.css",
    "content": "/*\n ----------------------------\n Actions\n ----------------------------\n */\n.custombox-open,\n.custombox-open body {\n    overflow: hidden;\n}\n.custombox-perspective,\n.custombox-perspective body  {\n    perspective: 600px;\n    height: 100%;\n}\n.custombox-overlay-open {\n    visibility: visible;\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Defaults\n ----------------------------\n */\n.custombox-overlay {\n    top: 0;\n    right: 0;\n    bottom: 0;\n    left: 0;\n    position: fixed;\n    transition-delay: 0s;\n}\n.custombox-overlay-default {\n    transition-timing-function: linear;\n    transition-property: opacity;\n    opacity: 0;\n}\n.custombox-modal-wrapper {\n    right: 0;\n    top: 0;\n    bottom: 0;\n    left: 0;\n    outline: 0 none;\n    overflow: auto;\n    position: fixed;\n    text-align: center;\n}\n.custombox-modal-container {\n    margin: 0 auto;\n    position: relative;\n}\n.custombox-modal img {\n    max-width: 100%;\n    height: auto;\n}\n.custombox-scrollbar {\n    position: absolute;\n    top: -9999px;\n    width: 50px;\n    height: 50px;\n    overflow: scroll;\n}\n.custombox-loading {\n    position: fixed;\n    transform: translateY(-50%) translateX(-50%);\n    top: 50%;\n    left: 50%;\n}\n\n/*\n ----------------------------\n Overlay: Letmein\n ----------------------------\n */\n.custombox-overlay-letmein {\n    transition-property: all;\n    transition-timing-function: ease;\n    visibility: hidden;\n}\n.custombox-overlay-open.custombox-overlay-letmein {\n    transform: rotateX(-2deg);\n    transform-origin: 50% 0;\n    transform-style: preserve-3d;\n    visibility: visible;\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Overlay: Slide together\n ----------------------------\n */\n.custombox-overlay-slidetogether {\n    transform: translateY(-100%);\n    transition-property: transform ease-in-out;\n}\n\n.custombox-overlay-open.custombox-overlay-slidetogether {\n    transform: translateY(0);\n    transition-property: transform ease-in-out;\n}\n\n/*\n ----------------------------\n Overlay: Corner\n ----------------------------\n */\n.custombox-overlay-corner {\n    transform: translateY(150px) translateX(150px);\n    transition-property: opacity, transform, visibility;\n}\n.custombox-overlay-open.custombox-overlay-corner {\n    transform: translateY(0);\n    transition-property: opacity, transform;\n}\n\n/*\n ----------------------------\n Overlay: Scale\n ----------------------------\n */\n.custombox-overlay-scale {\n    transform: scale(0.9);\n    transition-property: transform;\n}\n.custombox-overlay-open.custombox-overlay-scale {\n    transform: scale(1);\n    transition-property: transform;\n}\n\n/*\n ----------------------------\n Overlay: Door\n ----------------------------\n */\n.custombox-overlay-door {\n    visibility: hidden;\n    width: 0;\n    left: 50%;\n    transform: translateX(-50%);\n    transition-property: width ease-in-out;\n}\n.custombox-overlay-open.custombox-overlay-door {\n    visibility: visible;\n    width: 100%;\n    transition-property: width ease-in-out;\n}\n\n/*\n ----------------------------\n Overlay: Push\n ----------------------------\n */\n.custombox-container-push {\n    overflow-x: hidden;\n    transition-property: transform;\n}\n.custombox-container-open.custombox-container-push {\n    transform: translateX(100%);\n}\n.custombox-overlay-push {\n    backface-visibility: hidden;\n    transform: translateX(-100%);\n    transition-property: transform ease-in-out;\n}\n.custombox-overlay-open.custombox-overlay-push {\n    transform: translateX(0);\n    transition-property: transform ease-in-out;\n}\n\n/*\n ----------------------------\n Overlay: Content Scale\n ----------------------------\n */\n.custombox-open-contentscale body {\n    background-color: #DDD;\n}\n.custombox-container-contentscale {\n    transition: transform 0.5s;\n    overflow: hidden;\n    height: 100%;\n}\n.custombox-container-open.custombox-container-contentscale {\n    transform: scale(0.8);\n}\n.custombox-overlay-contentscale {\n    transform: translateY(100%);\n    transition-property: transform ease-in-out;\n}\n.custombox-overlay-open.custombox-overlay-contentscale {\n    transform: translateY(0);\n    transition-property: transform ease-in-out;\n}\n\n/*\n ----------------------------\n Overlay: Makeway\n ----------------------------\n */\n.custombox-container-open.custombox-container-makeway {\n    height: 100%;\n    overflow: hidden;\n}\n.custombox-overlay-open.custombox-overlay-makeway {\n    transition-property: all;\n}\n.custombox-overlay-open.custombox-overlay-makeway,\n.custombox-container-open.custombox-container-makeway {\n    transform-style: preserve-3d;\n    transform-origin: 0 50%;\n    animation: rotateRightSideFirst 0.5s forwards ease-in;\n}\n@keyframes rotateRightSideFirst {\n    50% {\n        transform: translateZ(-50px) rotateY(5deg);\n        animation-timing-function: ease-out;\n    }\n    100% {\n        transform: translateZ(-200px);\n    }\n}\n\n/*\n ----------------------------\n Overlay: Slip\n ----------------------------\n */\n.custombox-overlay-open.custombox-overlay-slip {\n    transition-property: all;\n}\n.custombox-overlay-open.custombox-overlay-slip,\n.custombox-container-open.custombox-container-slip {\n    transform-style: preserve-3d;\n    transform-origin: 50% 100%;\n    animation: OpenTop 0.5s forwards ease-in-out;\n}\n@keyframes OpenTop {\n    50% {\n        transform: rotateX(10deg);\n        animation-timing-function: ease-out;\n    }\n}\n\n/*\n ----------------------------\n Modal: Fadein\n ----------------------------\n */\n.custombox-modal-fadein {\n    transform: scale(0.7);\n    transition-property: all;\n    opacity: 0;\n    visibility: hidden;\n}\n.custombox-modal-open .custombox-modal-fadein {\n    transform: scale(1);\n    opacity: 1;\n    visibility: visible;\n}\n\n/*\n ----------------------------\n Modal: Slide\n ----------------------------\n */\n.custombox-modal-container-slide > div,\n.custombox-modal-container-slidetogether > div {\n    opacity: 0;\n    float: left;\n}\n.custombox-modal-open > .custombox-modal-container-slide > div,\n.custombox-modal-open > .custombox-modal-container-slidetogether > div {\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Modal: Slide from top\n ----------------------------\n */\n.custombox-modal-slide-top {\n    transform: translateY(-300%);\n}\n.custombox-modal-open .custombox-modal-slide-top {\n    transform: translateY(0);\n}\n\n/*\n ----------------------------\n Modal: Slide from left\n ----------------------------\n */\n.custombox-modal-slide-left {\n    transform: translateX(-300%);\n}\n.custombox-modal-open .custombox-modal-slide-left {\n    transform: translateX(0);\n}\n\n/*\n ----------------------------\n Modal: Slide from right\n ----------------------------\n */\n.custombox-modal-slide-right {\n    transform: translateX(300%);\n}\n.custombox-modal-open .custombox-modal-slide-right {\n    transform: translateX(0);\n}\n\n/*\n ----------------------------\n Modal: Slide from bottom\n ----------------------------\n */\n.custombox-modal-slide-bottom {\n    transform: translateY(300%);\n}\n.custombox-modal-open .custombox-modal-slide-bottom {\n    transform: translateY(0);\n}\n\n/*\n ----------------------------\n Modal: Newspaper\n ----------------------------\n */\n.custombox-modal-newspaper {\n    transform: scale(0) rotate(720deg);\n    opacity: 0;\n    transition-property: all;\n    position: absolute;\n}\n.custombox-overlay-newspaper {\n    transition-property: all;\n}\n.custombox-modal-open .custombox-modal-newspaper {\n    transform: scale(1) rotate(0deg);\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Modal: Fall\n ----------------------------\n */\n.custombox-modal-container-fall {\n    perspective: 1300px;\n}\n.custombox-modal-fall {\n    transform-style: preserve-3d;\n    transform: translateZ(600px) rotateX(20deg);\n    opacity: 0;\n}\n.custombox-modal-open .custombox-modal-fall {\n    transition-timing-function: ease-in;\n    transition-property: all;\n    transform: translateZ(0) rotateX(0deg);\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Modal: Sideball\n ----------------------------\n */\n.custombox-modal-container-sidefall {\n    perspective: 1300px;\n}\n.custombox-modal-wrapper-sidefall {\n    overflow-x: hidden;\n}\n.custombox-modal-sidefall {\n    transform-style: preserve-3d;\n    transform: translate(30%) translateZ(600px) rotate(10deg);\n    opacity: 0;\n}\n.custombox-modal-open .custombox-modal-sidefall {\n    transition-timing-function: ease-in;\n    transition-property: all;\n    transform: translate(0) translateZ(0) rotate(0deg);\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Modal: Blur\n ----------------------------\n */\n.custombox-open-blur .custombox-container-blur {\n    filter: blur(3px);\n}\n@media all and (-ms-high-contrast: none) {\n    .custombox-open-blur .custombox-container-blur {\n        text-shadow: 0 0 8px #000;\n        color: rgba(255,255,255,0);\n        filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius='3');\n        zoom: 1;\n    }\n}\n.custombox-modal-blur {\n    transform: translateY(-5%);\n    opacity: 0;\n    position: absolute;\n}\n.custombox-overlay-blur,\n.custombox-modal-container-blur {\n    transition-property: all;\n}\n.custombox-modal-open .custombox-modal-blur {\n    transform: translateY(0);\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Modal: 3D Flip generic\n ----------------------------\n */\n.custombox-modal-container-flip {\n    perspective: 1300px;\n}\n\n/*\n ----------------------------\n Modal: 3D Flip horizontal\n ----------------------------\n */\n.custombox-modal-flip-horizontal {\n    position: absolute;\n    transform-style: preserve-3d;\n    transform: rotateY(-70deg);\n    transition-property: all;\n    opacity: 0;\n}\n.custombox-modal-open .custombox-modal-flip-horizontal {\n    transform: rotateY(0deg);\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Modal: 3D Flip vertical\n ----------------------------\n */\n.custombox-modal-flip-vertical {\n    position: absolute;\n    transform-style: preserve-3d;\n    transform: rotateX(-70deg);\n    transition-property: all;\n    opacity: 0;\n}\n.custombox-modal-open .custombox-modal-flip-vertical {\n    transform: rotateX(0deg);\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Modal: 3D Sign\n ----------------------------\n */\n.custombox-modal-container-sign {\n    perspective: 1300px;\n}\n.custombox-modal-sign {\n    transform-style: preserve-3d;\n    transform: rotateX(-60deg);\n    transform-origin: 50% 0;\n    opacity: 0;\n    transition-property: all;\n}\n.custombox-modal-open .custombox-modal-sign {\n    transform: rotateX(0deg);\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Modal: Superscaled\n ----------------------------\n */\n.custombox-modal-superscaled {\n    transform: scale(2);\n    opacity: 0;\n    transition-property: all;\n    position: absolute;\n}\n.custombox-modal-open .custombox-modal-superscaled {\n    transform: scale(1);\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Modal: 3D Slit\n ----------------------------\n */\n.custombox-modal-container-slit {\n    perspective: 1300px;\n}\n.custombox-modal-slit {\n    transform-style: preserve-3d;\n    transform: translateZ(-3000px) rotateY(90deg);\n    opacity: 0;\n}\n.custombox-modal-open .custombox-modal-slit {\n    animation: slit .7s forwards ease-out;\n}\n@keyframes slit {\n    50% {\n        transform: translateZ(-250px) rotateY(89deg);\n        opacity: 1;\n        animation-timing-function: ease-out;\n    }\n    100% {\n        transform: translateZ(0) rotateY(0deg);\n        opacity: 1;\n    }\n}\n\n/*\n ----------------------------\n Modal: 3D Rotate generic\n ----------------------------\n */\n.custombox-modal-container-rotate {\n    perspective: 1300px;\n}\n\n/*\n ----------------------------\n Modal: 3D Rotate from bottom\n ----------------------------\n */\n.custombox-modal-rotate-bottom {\n    transform-style: preserve-3d;\n    transform: translateY(100%) rotateX(90deg);\n    transform-origin: 0 100%;\n    opacity: 0;\n    transition-timing-function: ease-out;\n    transition-property: all;\n    position: absolute;\n}\n.custombox-modal-open .custombox-modal-rotate-bottom {\n    transform: translateY(0) rotateX(0deg);\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Modal: 3D Rotate from left\n ----------------------------\n */\n.custombox-modal-rotate-left {\n    transform-style: preserve-3d;\n    transform: translateZ(100px) translateX(-30%) rotateY(90deg);\n    transform-origin: 0 100%;\n    opacity: 0;\n    transition-property: all;\n    position: absolute;\n}\n.custombox-modal-open .custombox-modal-rotate-left {\n    transform: translateZ(0) translateX(0) rotateY(0deg);\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Modal: Letmein\n ----------------------------\n */\n.custombox-modal-container-letmein {\n    transition-property: transform;\n    transform: rotateX(-2deg);\n    transform-origin: 50% 0;\n    transform-style: preserve-3d;\n    opacity: 1;\n}\n.custombox-modal-letmein {\n    opacity: 0;\n    transform: translateY(300%);\n    float: left;\n}\n.custombox-modal-open .custombox-modal-letmein {\n    transform: translateY(0);\n    opacity: 1;\n    transition-property: all;\n}\n\n/*\n ----------------------------\n Modal: Makeway\n ----------------------------\n */\n.custombox-modal-makeway {\n    transform: translateX(200%);\n    opacity: 0;\n    float: left;\n}\n.custombox-modal-open .custombox-modal-makeway {\n    transform: translateX(0);\n    opacity: 1;\n}\n.custombox-modal-wrapper-makeway {\n    overflow: hidden;\n}\n\n/*\n ----------------------------\n Modal: Slip\n ----------------------------\n */\n.custombox-modal-slip {\n    transform: translateY(-350%);\n}\n.custombox-modal-open .custombox-modal-slip {\n    transform: translateY(0);\n    transition-property: all;\n}\n\n/*\n ----------------------------\n Modal: Corner\n ----------------------------\n */\n.custombox-modal-corner {\n    opacity: 0;\n    transform: translateY(150px) translateX(150px);\n    transition-property: opacity, transform, visibility;\n}\n.custombox-modal-open .custombox-modal-corner {\n    transform: translateY(0);\n    opacity: 1;\n    transition-property: opacity, transform;\n}\n\n/*\n ----------------------------\n Modal: Slide together\n ----------------------------\n */\n.custombox-modal-slidetogether {\n    transform: translateY(-600%);\n\n}\n.custombox-modal-open .custombox-modal-slidetogether {\n    transform: translateY(0);\n}\n\n/*\n ----------------------------\n Modal: Scale\n ----------------------------\n */\n.custombox-modal-scale {\n    transform: scale(0.9);\n    transition: transform;\n    opacity: 0;\n}\n.custombox-modal-open .custombox-modal-scale {\n    transform: scale(1);\n    transition: transform;\n    opacity: 1;\n}\n\n/*\n ----------------------------\n Modal: Door\n ----------------------------\n */\n.custombox-modal-door {\n    visibility: hidden;\n    opacity: 0;\n}\n.custombox-modal-open .custombox-modal-door {\n    opacity: 1;\n    visibility: visible;\n}\n\n/*\n ----------------------------\n Modal: Push\n ----------------------------\n */\n.custombox-modal-push {\n    transform: translateX(-300%);\n}\n.custombox-modal-open .custombox-modal-push {\n    transform: translateX(0);\n}\n\n/*\n ----------------------------\n Modal: Content Scale\n ----------------------------\n */\n.custombox-modal-contentscale {\n    transform: translateY(600%);\n    transition-property: transform ease-in-out;\n    position: absolute;\n}\n.custombox-modal-open .custombox-modal-contentscale {\n    transform: translateY(0);\n}\n\n/*\n ----------------------------\n Modal: Val\n ----------------------------\n */\n.custombox-modal-swell {\n    animation-duration: 0.5s;\n    animation-fill-mode: forwards;\n    animation-timing-function: ease-out;\n    animation-name: swell-close;\n}\n.custombox-modal-open .custombox-modal-swell {\n    animation-name: swell-open;\n}\n@keyframes swell-open {\n    0% {\n        opacity: 0;\n        transform: translate3d(calc(-100vw - 50%), 0, 0);\n    }\n    50% {\n        opacity: 1;\n        transform: translate3d(100px, 0, 0);\n    }\n    100% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0);\n    }\n}\n@keyframes swell-close {\n    0% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0);\n    }\n    50% {\n        opacity: 1;\n        transform: translate3d(-100px, 0, 0) scale3d(1.1, 1.1, 1);\n    }\n    100% {\n        opacity: 0;\n        transform: translate3d(calc(100vw + 50%), 0, 0)\n    }\n}\n\n/*\n ----------------------------\n Modal: Rotate down\n ----------------------------\n */\n.custombox-modal-rotatedown {\n    animation-duration: 0.4s;\n    animation-timing-function: cubic-bezier(0.7,0,0.3,1);\n    animation-fill-mode: forwards;\n    transform-origin: -150% 50%;\n    animation-name: rotatedown-close;\n    overflow: hidden;\n}\n.custombox-modal-open .custombox-modal-rotatedown {\n    animation-name: rotatedown-open;\n}\n.custombox-modal-open .custombox-modal-rotatedown div > * {\n    animation: rotatedown-elem 0.4s both;\n    transform-origin: -50% 50%;\n    animation-timing-function: cubic-bezier(0.7,0,0.3,1);\n    animation-delay: 0.15s;\n}\n@keyframes rotatedown-open {\n    0% {\n        opacity: 0;\n        transform: rotate3d(0, 0, 1, -45deg);\n    }\n    100% {\n        opacity: 1;\n        transform: rotate3d(0, 0, 1, 0deg);\n    }\n}\n@keyframes rotatedown-close {\n    0% {\n        opacity: 1;\n    }\n    100% {\n        opacity: 0;\n        transform: rotate3d(0, 0, 1, 45deg);\n    }\n}\n@keyframes rotatedown-elem {\n    0% {\n        opacity: 0;\n        transform: translate3d(0, -150px, 0) rotate3d(0, 0, 1, -20deg);\n    }\n    100% { opacity: 1;\n        transform: translate3d(0, 0, 0) rotate3d(0, 0, 1, 0deg);\n    }\n}\n\n/*\n ----------------------------\n Modal: Flash\n ----------------------------\n */\n.custombox-modal-flash {\n    animation-duration: 0.4s;\n    animation-fill-mode: forwards;\n    animation-timing-function: cubic-bezier(0.7,0,0.3,1);\n    animation-name: flash-close;\n    overflow: hidden;\n}\n.custombox-modal-open .custombox-modal-flash {\n    animation-name: flash-open;\n}\n.custombox-modal-open .custombox-modal-flash div > * {\n    animation: flash-elem-open 0.4s cubic-bezier(0.7,0,0.3,1) both;\n}\n.custombox-modal-flash div > * {\n    animation: flash-elem-close 0.4s cubic-bezier(0.7,0,0.3,1) both;\n}\n@keyframes flash-open {\n    0% {\n        opacity: 0;\n        transform: translate3d(-400px, 0, 0)\n        scale3d(1.4, 0, 1);\n    }\n    100% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0) scale3d(1, 1, 1);\n    }\n}\n@keyframes flash-close {\n    0% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0) scale3d(1, 1, 1);\n    }\n    20% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0) scale3d(1, 1, 1);\n    }\n    100% {\n        opacity: 0;\n        transform: translate3d(-400px, 0, 0) scale3d(1.4, 0, 1);\n    }\n}\n@keyframes flash-elem-open {\n    0% {\n        opacity: 0;\n        transform: translate3d(-100px, 0, 0);\n    }\n    20% {\n        opacity: 0;\n        transform: translate3d(-100px, 0, 0);\n    }\n    100% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0);\n    }\n}\n@keyframes flash-elem-close {\n    0% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0);\n    }\n    100% {\n        opacity: 0;\n        transform: translate3d(-100px, 0, 0);\n    }\n}"
  },
  {
    "path": "static/assets/plugins/custombox/src/js/custombox.js",
    "content": "(function( global, factory ) {\n    if ( typeof exports === 'object' && typeof module !== 'undefined' ) {\n        module.exports = factory();\n    } else if ( typeof define === 'function' && define.amd ) {\n        define(factory);\n    } else {\n        global.Custombox = factory();\n    }\n}(this, function() {\n    'use strict';\n    /*\n     ----------------------------\n     Settings\n     ----------------------------\n     */\n    var _defaults = {\n        target:         null,                   // Set the URL, ID or Class.\n        cache:          false,                  // If set to false, it will force requested pages not to be cached by the browser only when send by AJAX.\n        escKey:         true,                   // Allows the user to close the modal by pressing 'ESC'.\n        zIndex:         9999,                   // Overlay z-index: Auto or number.\n        overlay:        true,                   // Show the overlay.\n        overlayColor:   '#000',                 // Overlay color.\n        overlayOpacity: 0.8,                    // The overlay opacity level. Range: 0 to 1.\n        overlayClose:   true,                   // Allows the user to close the modal by clicking the overlay.\n        overlaySpeed:   300,                    // Sets the speed of the overlay, in milliseconds.\n        overlayEffect:  'auto',                 // Combine any of the effects.\n        width:          null,                   // Set a fixed total width or 'full'.\n        effect:         'fadein',               // fadein | slide | newspaper | fall | sidefall | blur | flip | sign | superscaled | slit | rotate | letmein | makeway | slip | corner | slidetogether | scale | door | push | contentscale | swell | rotatedown | flash.\n        position:       ['center', 'center'],   // Set position of modal. First position 'x': left, center and right. Second position 'y': top, center, bottom.\n        animation:      null,                   // Only with effects: slide, flip and rotate (top, right, bottom, left and center) | (vertical or horizontal) and output position. Example: ['top', 'bottom'].\n        speed:          500,                    // Sets the speed of the transitions, in milliseconds.\n        loading:        false,                  // Show loading.\n        open:           null,                   // Callback that fires right before begins to open.\n        complete:       null,                   // Callback that fires right after loaded content is displayed.\n        close:          null                    // Callback that fires once is closed.\n    },\n    /*\n     ----------------------------\n     Config\n     ----------------------------\n     */\n    _config = {\n        oldIE:              navigator.appVersion.indexOf('MSIE 8.') > -1 || navigator.appVersion.indexOf('MSIE 9.') > -1,       // Check if is a old IE.\n        oldMobile:          /(iPhone|iPad|iPod)\\sOS\\s6/.test(navigator.userAgent),                                              // Check if is a old browser mobile.\n        overlay: {\n            perspective:    ['letmein', 'makeway', 'slip'],                                                                     // Custom effects overlay.\n            together:       ['corner', 'slidetogether', 'scale', 'door', 'push', 'contentscale', 'simplegenie', 'slit', 'slip'] // Animation together (overlay and modal).\n        },\n        modal: {\n            position:       ['slide', 'flip', 'rotate'],                                                                        // Custom animation of the modal.\n            animationend:   ['swell', 'rotatedown', 'flash']                                                                    // Type of animation.\n        }\n    },\n    /*\n     ----------------------------\n     Private methods\n     ----------------------------\n     */\n    _private = {\n        set: function( val ) {\n            if ( !this.cb || !this.cb.length ) {\n                this.cb = [];\n                this.item = -1;\n            }\n\n            this.item++;\n\n            if ( val && val.zIndex === 'auto' ) {\n                for ( var zIndex = 0, x = 0, elements = document.getElementsByTagName('*'), xLen = elements.length; x < xLen; x += 1 ) {\n                    var value = window.getComputedStyle(elements[x]).getPropertyValue('z-index');\n                    if ( value ) {\n                        value =+ value;\n                        if ( value > zIndex ) {\n                            zIndex = value;\n                        }\n                    }\n                }\n                val.zIndex = zIndex;\n            }\n\n            this.cb.push({\n                settings: _config.oldIE && typeof cbExtendObjects !== 'undefined' ? cbExtendObjects( {}, _defaults, val ) : Object.assign( {}, _defaults, val )\n            });\n\n            if ( this.cb[this.item].settings.overlayEffect === 'auto' ) {\n                this.cb[this.item].settings.overlayEffect = this.cb[this.item].settings.effect;\n            }\n        },\n        get: function() {\n            return this.cb[this.cb.length - 1] || null;\n        },\n        init: function() {\n            // Add class open.\n            document.documentElement.classList.add('custombox-open');\n            document.documentElement.classList.add('custombox-open-' + this.cb[this.item].settings.overlayEffect);\n\n            // Add class perspective.\n            if ( _config.overlay.perspective.indexOf( this.cb[this.item].settings.overlayEffect ) > -1 ) {\n                this.cb[this.item].scroll = document.documentElement && document.documentElement.scrollTop || document.body && document.body.scrollTop || 0;\n                document.documentElement.classList.add('custombox-perspective');\n                window.scrollTo(0, 0);\n            }\n\n            // Create main.\n            if ( !this.main ) {\n                this.built('container');\n            }\n\n            // Create loading.\n            if ( this.cb[this.item].settings.loading && this.cb[this.item].settings.loading.parent ) {\n                this.built('loading');\n            }\n\n            // Create overlay.\n            if ( this.cb[this.item].settings.overlay ) {\n                this.built('overlay').built('modal').open();\n            } else {\n                this.built('modal').open();\n            }\n\n            // Listeners.\n            this.binds();\n        },\n        zIndex: function() {\n            for ( var zIndex = 0, x = 0, elements = document.getElementsByTagName('*'), xLen = elements.length; x < xLen; x += 1 ) {\n                var val = window.getComputedStyle(elements[x]).getPropertyValue('z-index');\n                if ( val ) {\n                    val =+ val;\n                    if ( val > zIndex ) {\n                        zIndex = val;\n                    }\n                }\n            }\n            return zIndex;\n        },\n        built: function( item ) {\n            var cb;\n            if ( typeof this.item !== 'undefined' ) {\n                cb = this.cb[this.item];\n            }\n\n            // Container.\n            switch ( item ) {\n                case 'container':\n                    this.main = document.createElement('div');\n                    while ( document.body.firstChild ) {\n                        this.main.appendChild(document.body.firstChild);\n                    }\n                    document.body.appendChild(this.main);\n                    break;\n                case 'overlay':\n                    if ( !cb.overlay ) {\n                        cb.overlay = {};\n                    }\n                    cb.overlay = document.createElement('div');\n                    cb.overlay.classList.add('custombox-overlay');\n                    cb.overlay.classList.add('custombox-overlay-' + cb.settings.overlayEffect);\n                    cb.overlay.style.zIndex = cb.settings.zIndex + 2;\n                    cb.overlay.style.backgroundColor = cb.settings.overlayColor;\n\n                    // Add class perspective.\n                    if ( _config.overlay.perspective.indexOf( cb.settings.overlayEffect ) > -1 || _config.overlay.together.indexOf( cb.settings.overlayEffect ) > -1 ) {\n                        cb.overlay.style.opacity = cb.settings.overlayOpacity;\n                    } else {\n                        cb.overlay.classList.add('custombox-overlay-default');\n                    }\n\n                    if ( _config.overlay.together.indexOf( cb.settings.overlayEffect ) > -1 ) {\n                        cb.overlay.style.transitionDuration = cb.settings.speed + 'ms';\n                    } else {\n                        cb.overlay.style.transitionDuration = cb.settings.overlaySpeed + 'ms';\n                    }\n\n                    // Append overlay in to the DOM.\n                    document.body.insertBefore(cb.overlay, document.body.lastChild.nextSibling);\n                    break;\n                case 'modal':\n                    if ( cb.settings.overlayEffect === 'push' ) {\n                        this.main.style.transitionDuration = cb.settings.speed + 'ms';\n                    }\n\n                    this.main.classList.add('custombox-container');\n                    this.main.classList.add('custombox-container-' + cb.settings.overlayEffect);\n\n                    cb.wrapper = document.createElement('div');\n                    cb.wrapper.classList.add('custombox-modal-wrapper');\n                    cb.wrapper.classList.add('custombox-modal-wrapper-' + cb.settings.effect);\n                    cb.wrapper.style.zIndex = cb.settings.zIndex + 3;\n                    document.body.insertBefore(cb.wrapper, document.body.lastChild.nextSibling);\n\n                    cb.container = document.createElement('div');\n                    cb.container.classList.add('custombox-modal-container');\n                    cb.container.classList.add('custombox-modal-container-' + cb.settings.effect);\n                    cb.container.style.zIndex = cb.settings.zIndex + 4;\n\n                    if ( _config.modal.position.indexOf(cb.settings.effect) > -1 && cb.settings.animation === null ) {\n                        // Defaults.\n                        if ( cb.settings.effect === 'slide' ) {\n                            cb.settings.animation = ['top'];\n                        } else if ( cb.settings.effect === 'flip' ) {\n                            cb.settings.animation = ['horizontal'];\n                        } else {\n                            cb.settings.animation = ['bottom'];\n                        }\n                    }\n\n                    cb.modal = document.createElement('div');\n                    cb.modal.classList.add('custombox-modal');\n                    cb.modal.classList.add(\n                        'custombox-modal-' + cb.settings.effect + ( _config.modal.position.indexOf( cb.settings.effect ) > -1 ? '-' + cb.settings.animation[0].trim() : '' )\n                    );\n                    cb.modal.style.transitionDuration = cb.settings.speed + 'ms';\n                    cb.modal.style.zIndex = cb.settings.zIndex + 4;\n                    cb.wrapper.appendChild(cb.container).appendChild(cb.modal);\n                    break;\n                case 'loading':\n                    this.loading = document.createElement('div');\n                    this.loading.classList.add('custombox-loading');\n\n                    var wrapper = document.createElement('div');\n                    for ( var i = 0, t = this.cb[this.item].settings.loading.parent.length; i < t; i++ ) {\n                        wrapper.classList.add(this.cb[this.item].settings.loading.parent[i]);\n                    }\n\n                    this.loading.appendChild(wrapper);\n                    this.loading.style.zIndex = cb.settings.zIndex + 3;\n\n                    if ( this.cb[this.item].settings.loading.childrens ) {\n                        for ( var e = 0, te = this.cb[this.item].settings.loading.childrens.length; e < te; e++ ) {\n                            var tmp = document.createElement('div');\n                            for ( var r = 0, tr = this.cb[this.item].settings.loading.childrens[e].length; r < tr; r++ ) {\n                                tmp.classList.add(this.cb[this.item].settings.loading.childrens[e][r]);\n                            }\n                            wrapper.appendChild(tmp);\n                        }\n                    }\n\n                    document.body.appendChild(this.loading);\n                    break;\n            }\n\n            return this;\n        },\n        load: function() {\n            var cb = this.cb[this.item];\n\n            // Check if callback 'open'.\n            if ( typeof cb.settings.open === 'function' ) {\n                cb.settings.open.call();\n            }\n\n            // Trigger open.\n            if ( document.createEvent ) {\n                var topen = document.createEvent('Event');\n                topen.initEvent('custombox.open', true, true);\n                document.dispatchEvent(topen);\n            }\n\n            // Convert the string to array.\n            if ( cb.settings.target !== null && Array.isArray(cb.settings.position) ) {\n                if ( cb.settings.target.charAt(0) === '#' || ( cb.settings.target.charAt(0) === '.' && cb.settings.target.charAt(1) !== '/' ) ) {\n                    if ( document.querySelector(cb.settings.target) ) {\n                        cb.inline = document.createElement('div');\n                        cb.content = document.querySelector(cb.settings.target);\n                        cb.display = cb.content.style.display === 'none';\n                        cb.content.style.display = 'block';\n                        cb.content.parentNode.insertBefore(cb.inline, cb.content);\n                        this.size();\n                    } else {\n                        this.error();\n                    }\n                } else {\n                    this.ajax();\n                }\n            } else {\n                this.error();\n            }\n            return this;\n        },\n        size: function() {\n            var cb = this.cb[this.item],\n                customw = cb.content.offsetWidth;\n\n            if ( _config.oldIE ) {\n                window.innerHeight = document.documentElement.clientHeight;\n            }\n\n            if ( !cb.inline ) {\n                if ( _config.oldIE ) {\n                    cb.content.style.styleFloat = 'none';\n                } else {\n                    cb.content.style.cssFloat = 'none';\n                }\n            }\n\n            // Check width.\n            if ( cb.settings.width !== null ) {\n                if ( !isNaN( cb.settings.width ) ) {\n                    customw = parseInt( cb.settings.width, 0);\n                } else {\n                    customw = window.innerWidth;\n                    cb.content.style.height = window.innerHeight + 'px';\n                }\n            }\n\n            // Storage.\n            cb.size = customw;\n\n            // Width.\n            if ( cb.size + 60 >= window.innerWidth ) {\n                cb.container.style.width = 'auto';\n                if ( cb.settings.width !== 'full' ) {\n                    cb.container.style.margin = '5%';\n                }\n                cb.wrapper.style.width = window.innerWidth + 'px';\n                for ( var i = 0, elements = cb.content.querySelectorAll(':scope > *'), t = elements.length; i < t; i++ ) {\n                    if ( elements[i].offsetWidth > window.innerWidth ) {\n                        elements[i].style.width = 'auto';\n                    }\n                }\n            } else {\n                switch ( cb.settings.position[0].trim() ) {\n                    case 'left':\n                        cb.container.style.marginLeft = 0;\n                        break;\n                    case 'right':\n                        cb.container.style.marginRight = 0;\n                        break;\n                }\n                cb.container.style.width = cb.size + 'px';\n            }\n\n            cb.content.style.width = 'auto';\n            cb.modal.appendChild(cb.content);\n\n            // Top.\n            if ( cb.content.offsetHeight >= window.innerHeight && cb.settings.width !== 'full' ) {\n                cb.container.style.marginTop = '5%';\n                cb.container.style.marginBottom = '5%';\n            } else {\n                var result;\n                switch ( cb.settings.position[1].trim() ) {\n                    case 'top':\n                        result = 0;\n                        break;\n                    case 'bottom':\n                        result = window.innerHeight - cb.content.offsetHeight + 'px';\n                        break;\n                    default:\n                        result = window.innerHeight / 2 - cb.content.offsetHeight / 2 + 'px';\n                        break;\n                }\n                cb.container.style.marginTop = result;\n            }\n\n            if ( this.loading ) {\n                document.body.removeChild(this.loading);\n                delete this.loading;\n            }\n            cb.wrapper.classList.add('custombox-modal-open');\n        },\n        ajax: function() {\n            var _this = this,\n                cb = _this.cb[_this.item],\n                xhr = new XMLHttpRequest(),\n                modal = document.createElement('div');\n\n            xhr.onreadystatechange = function() {\n                if ( xhr.readyState === 4 ) {\n                    if( xhr.status === 200 ) {\n                        modal.innerHTML = xhr.responseText;\n                        cb.content = modal;\n                        cb.content.style.display = 'block';\n                        if ( _config.oldIE ) {\n                            cb.content.style.styleFloat = 'left';\n                        } else {\n                            cb.content.style.cssFloat = 'left';\n                        }\n                        cb.container.appendChild(cb.content);\n                        _this.size();\n                    } else {\n                        _this.error();\n                    }\n                }\n            };\n            xhr.open('GET', cb.settings.target + ( cb.settings.cache ? '' : ( /[?].+=/.test(cb.settings.target) ? '&_=' : '?_=' ) + Date.now() ), true);\n            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\n            xhr.send(null);\n        },\n        scrollbar: function() {\n            var scrollDiv = document.createElement('div');\n            scrollDiv.classList.add('custombox-scrollbar');\n            document.body.appendChild(scrollDiv);\n            var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;\n            document.body.removeChild(scrollDiv);\n            return scrollbarWidth;\n        },\n        open: function() {\n            var _this = this,\n                cb = _this.cb[_this.item],\n                scrollbar = _this.scrollbar();\n\n            if ( scrollbar ) {\n                document.body.style.paddingRight = scrollbar + 'px';\n            }\n\n            _this.main.classList.add('custombox-container-open');\n\n            if ( cb.settings.overlay ) {\n                if ( _config.overlay.perspective.indexOf(cb.settings.overlayEffect) > -1 || _config.overlay.together.indexOf( cb.settings.overlayEffect ) > -1 ) {\n                    // Add class perspective.\n                    cb.overlay.classList.add('custombox-overlay-open');\n                } else {\n                    cb.overlay.style.opacity = cb.settings.overlayOpacity;\n                }\n\n                if ( _config.overlay.together.indexOf( cb.settings.overlayEffect ) > -1 || _config.oldIE ) {\n                    // Load target.\n                    _this.load();\n\n                    if ( cb.inline) {\n                        cb.wrapper.classList.add('custombox-modal-open');\n                    }\n                } else {\n                    var open = function() {\n                        cb.overlay.removeEventListener('transitionend', open);\n\n                        // Load target.\n                        _this.load();\n\n                        if ( cb.inline) {\n                            cb.wrapper.classList.add('custombox-modal-open');\n                        }\n                    };\n                    cb.overlay.addEventListener('transitionend', open, false);\n                }\n            } else {\n                // Load target.\n                _this.load();\n\n                if ( cb.inline) {\n                    cb.wrapper.classList.add('custombox-modal-open');\n                }\n            }\n            return _this;\n        },\n        clean: function( item ) {\n            var _this = this,\n                cb = this.cb[item];\n\n            document.documentElement.classList.remove('custombox-open-' + cb.settings.overlayEffect);\n\n            if ( cb.settings.overlay ) {\n                if ( cb.overlay.style.opacity ) {\n                    cb.overlay.style.opacity = 0;\n                }\n\n                cb.overlay.classList.remove('custombox-overlay-open');\n                _this.main.classList.remove('custombox-container-open');\n            }\n\n            // Listener overlay.\n            if ( _config.oldIE || _config.oldMobile || !cb.overlay ) {\n                _this.remove(item);\n            } else {\n                var overlay = function() {\n                    cb.overlay.removeEventListener('transitionend', overlay);\n                    _this.remove(item);\n                };\n                cb.overlay.addEventListener('transitionend', overlay, false);\n            }\n        },\n        remove: function( item ) {\n            var _this = this,\n                cb = this.cb[item];\n\n            // Remove classes from html tag.\n            if ( _this.cb.length === 1 ) {\n                document.documentElement.classList.remove('custombox-open', 'custombox-perspective');\n                if ( _this.scrollbar() ) {\n                    document.body.style.paddingRight = 0;\n                }\n\n                if ( typeof cb.scroll !== 'undefined' ) {\n                    window.scrollTo(0, cb.scroll);\n                }\n            }\n\n            if ( cb.inline ) {\n                // Remove property width and display.\n                if ( _config.oldIE ) {\n                    cb.content.style.removeAttribute('width');\n                    cb.content.style.removeAttribute('height');\n                    cb.content.style.removeAttribute('display');\n                } else {\n                    cb.content.style.removeProperty('width');\n                    cb.content.style.removeProperty('height');\n                    cb.content.style.removeProperty('display');\n                }\n\n                if ( cb.display ) {\n                    cb.content.style.display = 'none';\n                }\n\n                // Insert restore div.\n                cb.inline.parentNode.replaceChild(cb.content, cb.inline);\n            }\n\n            _this.main.classList.remove('custombox-container-' + cb.settings.overlayEffect);\n\n            // Remove modal.\n            cb.wrapper.parentNode.removeChild(cb.wrapper);\n\n            // Remove overlay.\n            if ( cb.settings.overlay ) {\n                cb.overlay.parentNode.removeChild(cb.overlay);\n            }\n\n            // Callback close.\n            if ( typeof cb.settings.close === 'function' ) {\n                cb.settings.close.call();\n            }\n\n            // Trigger close.\n            if ( document.createEvent ) {\n                var tclose = document.createEvent('Event');\n                tclose.initEvent('custombox.close', true, true);\n                document.dispatchEvent(tclose);\n            }\n\n            // Unwrap.\n            if ( _this.cb.length === 1 ) {\n                for ( var contents = document.querySelectorAll('.custombox-container > *'), i = 0, t = contents.length; i < t; i++ ) {\n                    document.body.insertBefore(contents[i], _this.main);\n                }\n                if ( _this.main.parentNode ) {\n                    _this.main.parentNode.removeChild(_this.main);\n                }\n                delete _this.main;\n            }\n\n            // Remove items.\n            _this.cb.splice(item, 1);\n        },\n        close: function( target ) {\n            var _this = this,\n                item;\n\n            if ( target ) {\n                for ( var i = 0, t = this.cb.length; i < t; i++ ) {\n                    if ( this.cb[i].settings.target === target ) {\n                        item = i;\n                        break;\n                    }\n                }\n            } else {\n                item = _this.cb.length - 1;\n            }\n\n            var cb = _this.cb[item];\n\n            // Modal\n            if ( _config.modal.position.indexOf( cb.settings.effect ) > -1 && cb.settings.animation.length > 1 ) {\n                cb.modal.classList.remove('custombox-modal-' + cb.settings.effect + '-' + cb.settings.animation[0]);\n                cb.modal.classList.add('custombox-modal-' + cb.settings.effect + '-' + cb.settings.animation[1].trim());\n            }\n\n            // Remove classes.\n            cb.wrapper.classList.remove('custombox-modal-open');\n\n            if ( _config.oldIE || _config.oldMobile || _config.overlay.together.indexOf( cb.settings.overlayEffect ) > -1 ) {\n                _this.clean(item);\n            } else {\n                // Listener wrapper.\n                var wrapper = function() {\n                    cb.wrapper.removeEventListener('transitionend', wrapper);\n                    _this.clean(item);\n                };\n\n                if ( _config.modal.animationend.indexOf(cb.settings.effect) > -1 ) {\n                    cb.wrapper.addEventListener('animationend', wrapper, false);\n                } else {\n                    cb.wrapper.addEventListener('transitionend', wrapper, false);\n                }\n            }\n        },\n        responsive: function() {\n            if ( _config.oldIE ) {\n                window.innerHeight = document.documentElement.clientHeight;\n            }\n\n            for ( var i = 0, t = this.cb.length, result; i < t; i++ ) {\n                // Width.\n                if ( this.cb[i].size + 60 >= window.innerWidth ) {\n                    if ( this.cb[i].settings.width !== 'full' ) {\n                        this.cb[i].container.style.marginLeft = '5%';\n                        this.cb[i].container.style.marginRight = '5%';\n                    }\n                    this.cb[i].container.style.width = 'auto';\n                    this.cb[i].wrapper.style.width = window.innerWidth + 'px';\n                } else {\n                    switch ( this.cb[i].settings.position[0].trim() ) {\n                        case 'left':\n                            this.cb[i].container.style.marginLeft = 0;\n                            break;\n                        case 'right':\n                            this.cb[i].container.style.marginRight = 0;\n                            break;\n                        default:\n                            this.cb[i].container.style.marginLeft = 'auto';\n                            this.cb[i].container.style.marginRight = 'auto';\n                            break;\n                    }\n                    this.cb[i].container.style.width = this.cb[i].size + 'px';\n                    this.cb[i].wrapper.style.width = 'auto';\n                }\n\n                // Top.\n                if ( this.cb[i].content.offsetHeight >= window.innerHeight && this.cb[i].settings.width !== 'full' ) {\n                    this.cb[i].container.style.marginTop = '5%';\n                    this.cb[i].container.style.marginBottom = '5%';\n                } else {\n                    switch ( this.cb[i].settings.position[1].trim() ) {\n                        case 'top':\n                            result = 0;\n                            break;\n                        case 'bottom':\n                            result = window.innerHeight - this.cb[i].content.offsetHeight + 'px';\n                            break;\n                        default:\n                            result = window.innerHeight / 2 - this.cb[i].content.offsetHeight / 2 + 'px';\n                            break;\n                    }\n                    this.cb[i].container.style.marginTop = result;\n                }\n            }\n        },\n        binds: function() {\n            var _this = this,\n                cb = _this.cb[_this.item],\n                stop = false;\n\n            // Esc.\n            if ( _this.cb.length === 1 ) {\n                _this.esc = function( event ) {\n                    if ( _this.cb.length === 1 ) {\n                        document.removeEventListener('keydown', _this.esc);\n                    }\n                    event = event || window.event;\n                    if ( !stop && event.keyCode === 27 && _this.get() && _this.get().settings.escKey ) {\n                        stop = true;\n                        _this.close();\n                    }\n                };\n                document.addEventListener('keydown', _this.esc, false);\n\n                // Listener responsive.\n                window.addEventListener('onorientationchange' in window ? 'orientationchange' : 'resize', function() {\n                    _this.responsive();\n                }, false);\n            }\n\n            // Overlay close.\n            cb.wrapper.event = function ( event ) {\n                if ( _this.cb.length === 1 ) {\n                    document.removeEventListener('keydown', cb.wrapper.event);\n                }\n                if ( !stop && event.target === cb.wrapper && _this.get() && _this.get().settings.overlayClose ) {\n                    stop = true;\n                    _this.close();\n                }\n            };\n            cb.wrapper.addEventListener('click', cb.wrapper.event, false);\n\n            document.addEventListener('custombox.close', function() {\n                stop = false;\n            });\n\n            var callback = function() {\n                // Execute the scripts.\n                if ( !cb.inline ) {\n                    for ( var i = 0, script = cb.modal.getElementsByTagName('script'), t = script.length; i < t; i++ ) {\n                        new Function( script[i].text )();\n                    }\n                }\n\n                if ( cb.settings && typeof cb.settings.complete === 'function' ) {\n                    cb.settings.complete.call();\n                }\n\n                // Trigger complete.\n                if ( document.createEvent ) {\n                    var tcomplete = document.createEvent('Event');\n                    tcomplete.initEvent('custombox.complete', true, true);\n                    document.dispatchEvent(tcomplete);\n                }\n            };\n\n            // Callback complete.\n            var complete = function() {\n                callback();\n                cb.modal.removeEventListener('transitionend', complete);\n            };\n\n            if ( _config.oldIE || _config.oldMobile ) {\n                setTimeout(function() {\n                    callback();\n                }, cb.settings.overlaySpeed);\n            } else {\n                if ( cb.settings.effect !== 'slit' ) {\n                    cb.modal.addEventListener('transitionend', complete, false);\n                } else {\n                    cb.modal.addEventListener('animationend', complete, false);\n                }\n            }\n        },\n        error: function() {\n            var _this = this,\n                item = _this.cb.length - 1;\n\n            alert('Error to load this target: ' + _this.cb[item].settings.target);\n            _this.remove(item);\n        }\n    };\n\n    return {\n        /**\n         * @desc Set options defaults.\n         * @param {object} options - Auto built.\n         */\n        set: function( options ) {\n            if ( options.autobuild ) {\n                _private.built('container');\n            }\n        },\n        /**\n         * @desc Open Custombox.\n         * @param {object} options - Options for the custombox.\n         */\n        open: function( options ) {\n            _private.set(options);\n            _private.init();\n        },\n        /**\n         * @desc Close Custombox.\n         * @param {string} options - Target.\n         */\n        close: function( target ) {\n            _private.close(target);\n        }\n    };\n}));"
  },
  {
    "path": "static/assets/plugins/custombox/src/js/legacy.js",
    "content": "/**\n * Add getComputedStyle support to elements\n */\n(function ( w ) {\n    if ( !w.getComputedStyle ) {\n        w.getComputedStyle = function( el ) {\n            this.el = el;\n            this.getPropertyValue = function( prop ) {\n                var re = /(\\-([a-z]){1})/g;\n                if ( prop == 'float' ) prop = 'styleFloat';\n                if ( re.test(prop) ) {\n                    prop = prop.replace(re, function () {\n                        return arguments[2].toUpperCase();\n                    });\n                }\n                return el.currentStyle[prop] ? el.currentStyle[prop] : null;\n            };\n            return this;\n        };\n    }\n})(window);\n\n/**\n * Add dataset support to elements\n * No globals, no overriding prototype with non-standard methods,\n *   handles CamelCase properly, attempts to use standard\n *   Object.defineProperty() (and Function bind()) methods,\n *   falls back to native implementation when existing\n * Inspired by http://code.eligrey.com/html5/dataset/\n *   (via https://github.com/adalgiso/html5-dataset/blob/master/html5-dataset.js )\n * Depends on Function.bind and Object.defineProperty/Object.getOwnPropertyDescriptor (shims below)\n * Licensed under the X11/MIT License\n */\n\n// Inspired by https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind#Compatibility\nif (!Function.prototype.bind) {\n    Function.prototype.bind = function (oThis) {\n        'use strict';\n        if (typeof this !== \"function\") {\n            // closest thing possible to the ECMAScript 5 internal IsCallable function\n            throw new TypeError(\"Function.prototype.bind - what is trying to be bound is not callable\");\n        }\n\n        var aArgs = Array.prototype.slice.call(arguments, 1),\n            fToBind = this,\n            FNOP = function () {},\n            fBound = function () {\n                return fToBind.apply(\n                    this instanceof FNOP && oThis ? this : oThis,\n                    aArgs.concat(Array.prototype.slice.call(arguments))\n                );\n            };\n\n        FNOP.prototype = this.prototype;\n        fBound.prototype = new FNOP();\n\n        return fBound;\n    };\n}\n\n/*\n * Xccessors Standard: Cross-browser ECMAScript 5 accessors\n * http://purl.eligrey.com/github/Xccessors\n * \n * 2010-06-21\n * \n * By Eli Grey, http://eligrey.com\n * \n * A shim that partially implements Object.defineProperty,\n * Object.getOwnPropertyDescriptor, and Object.defineProperties in browsers that have\n * legacy __(define|lookup)[GS]etter__ support.\n * \n * Licensed under the X11/MIT License\n *   See LICENSE.md\n */\n\n// Removed a few JSLint options as Notepad++ JSLint validator complaining and \n//   made comply with JSLint; also moved 'use strict' inside function\n/*jslint white: true, undef: true, plusplus: true,\n bitwise: true, regexp: true, newcap: true, maxlen: 90 */\n\n/*! @source http://purl.eligrey.com/github/Xccessors/blob/master/xccessors-standard.js*/\n\n(function () {\n    'use strict';\n    var ObjectProto = Object.prototype,\n        defineGetter = ObjectProto.__defineGetter__,\n        defineSetter = ObjectProto.__defineSetter__,\n        lookupGetter = ObjectProto.__lookupGetter__,\n        lookupSetter = ObjectProto.__lookupSetter__,\n        hasOwnProp = ObjectProto.hasOwnProperty;\n\n    if (defineGetter && defineSetter && lookupGetter && lookupSetter) {\n\n        if (!Object.defineProperty) {\n            Object.defineProperty = function (obj, prop, descriptor) {\n                if (arguments.length < 3) { // all arguments required\n                    throw new TypeError(\"Arguments not optional\");\n                }\n\n                prop += \"\"; // convert prop to string\n\n                if (hasOwnProp.call(descriptor, \"value\")) {\n                    if (!lookupGetter.call(obj, prop) && !lookupSetter.call(obj, prop)) {\n                        // data property defined and no pre-existing accessors\n                        obj[prop] = descriptor.value;\n                    }\n\n                    if ((hasOwnProp.call(descriptor, \"get\") ||\n                        hasOwnProp.call(descriptor, \"set\")))\n                    {\n                        // descriptor has a value prop but accessor already exists\n                        throw new TypeError(\"Cannot specify an accessor and a value\");\n                    }\n                }\n\n                // can't switch off these features in ECMAScript 3\n                // so throw a TypeError if any are false\n                if (!(descriptor.writable && descriptor.enumerable &&\n                    descriptor.configurable))\n                {\n                    throw new TypeError(\n                        \"This implementation of Object.defineProperty does not support\" +\n                        \" false for configurable, enumerable, or writable.\"\n                    );\n                }\n\n                if (descriptor.get) {\n                    defineGetter.call(obj, prop, descriptor.get);\n                }\n                if (descriptor.set) {\n                    defineSetter.call(obj, prop, descriptor.set);\n                }\n\n                return obj;\n            };\n        }\n\n        if (!Object.getOwnPropertyDescriptor) {\n            Object.getOwnPropertyDescriptor = function (obj, prop) {\n                if (arguments.length < 2) { // all arguments required\n                    throw new TypeError(\"Arguments not optional.\");\n                }\n\n                prop += \"\"; // convert prop to string\n\n                var descriptor = {\n                        configurable: true,\n                        enumerable  : true,\n                        writable    : true\n                    },\n                    getter = lookupGetter.call(obj, prop),\n                    setter = lookupSetter.call(obj, prop);\n\n                if (!hasOwnProp.call(obj, prop)) {\n                    // property doesn't exist or is inherited\n                    return descriptor;\n                }\n                if (!getter && !setter) { // not an accessor so return prop\n                    descriptor.value = obj[prop];\n                    return descriptor;\n                }\n\n                // there is an accessor, remove descriptor.writable;\n                // populate descriptor.get and descriptor.set (IE's behavior)\n                delete descriptor.writable;\n                descriptor.get = descriptor.set = undefined;\n\n                if (getter) {\n                    descriptor.get = getter;\n                }\n                if (setter) {\n                    descriptor.set = setter;\n                }\n\n                return descriptor;\n            };\n        }\n\n        if (!Object.defineProperties) {\n            Object.defineProperties = function (obj, props) {\n                var prop;\n                for (prop in props) {\n                    if (hasOwnProp.call(props, prop)) {\n                        Object.defineProperty(obj, prop, props[prop]);\n                    }\n                }\n            };\n        }\n    }\n}());\n\n// Begin dataset code\n\nif (!document.documentElement.dataset &&\n        // FF is empty while IE gives empty object\n    (!Object.getOwnPropertyDescriptor(Element.prototype, 'dataset')  ||\n    !Object.getOwnPropertyDescriptor(Element.prototype, 'dataset').get)\n) {\n    var propDescriptor = {\n        enumerable: true,\n        get: function () {\n            'use strict';\n            var i,\n                that = this,\n                HTML5_DOMStringMap,\n                attrVal, attrName, propName,\n                attribute,\n                attributes = this.attributes,\n                attsLength = attributes.length,\n                toUpperCase = function (n0) {\n                    return n0.charAt(1).toUpperCase();\n                },\n                getter = function () {\n                    return this;\n                },\n                setter = function (attrName, value) {\n                    return (typeof value !== 'undefined') ?\n                        this.setAttribute(attrName, value) :\n                        this.removeAttribute(attrName);\n                };\n            try { // Simulate DOMStringMap w/accessor support\n                // Test setting accessor on normal object\n                ({}).__defineGetter__('test', function () {});\n                HTML5_DOMStringMap = {};\n            }\n            catch (e1) { // Use a DOM object for IE8\n                HTML5_DOMStringMap = document.createElement('div');\n            }\n            for (i = 0; i < attsLength; i++) {\n                attribute = attributes[i];\n                // Fix: This test really should allow any XML Name without \n                //         colons (and non-uppercase for XHTML)\n                if (attribute && attribute.name &&\n                    (/^data-\\w[\\w\\-]*$/).test(attribute.name)) {\n                    attrVal = attribute.value;\n                    attrName = attribute.name;\n                    // Change to CamelCase\n                    propName = attrName.substr(5).replace(/-./g, toUpperCase);\n                    try {\n                        Object.defineProperty(HTML5_DOMStringMap, propName, {\n                            enumerable: this.enumerable,\n                            get: getter.bind(attrVal || ''),\n                            set: setter.bind(that, attrName)\n                        });\n                    }\n                    catch (e2) { // if accessors are not working\n                        HTML5_DOMStringMap[propName] = attrVal;\n                    }\n                }\n            }\n            return HTML5_DOMStringMap;\n        }\n    };\n    try {\n        // FF enumerates over element's dataset, but not \n        //   Element.prototype.dataset; IE9 iterates over both\n        Object.defineProperty(Element.prototype, 'dataset', propDescriptor);\n    } catch (e) {\n        propDescriptor.enumerable = false; // IE8 does not allow setting to true\n        Object.defineProperty(Element.prototype, 'dataset', propDescriptor);\n    }\n}\n\n/*\n * classList.js: Cross-browser full element.classList implementation.\n * 2014-12-13\n *\n * By Eli Grey, http://eligrey.com\n * Public Domain.\n * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.\n */\n\n/*global self, document, DOMException */\n\n/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */\n\nif (\"document\" in self) {\n\n// Full polyfill for browsers with no classList support\n    if (!(\"classList\" in document.createElement(\"_\"))) {\n\n        (function (view) {\n\n            \"use strict\";\n\n            if (!('Element' in view)) return;\n\n            var\n                classListProp = \"classList\"\n                , protoProp = \"prototype\"\n                , elemCtrProto = view.Element[protoProp]\n                , objCtr = Object\n                , strTrim = String[protoProp].trim || function () {\n                        return this.replace(/^\\s+|\\s+$/g, \"\");\n                    }\n                , arrIndexOf = Array[protoProp].indexOf || function (item) {\n                        var\n                            i = 0\n                            , len = this.length\n                            ;\n                        for (; i < len; i++) {\n                            if (i in this && this[i] === item) {\n                                return i;\n                            }\n                        }\n                        return -1;\n                    }\n            // Vendors: please allow content code to instantiate DOMExceptions\n                , DOMEx = function (type, message) {\n                    this.name = type;\n                    this.code = DOMException[type];\n                    this.message = message;\n                }\n                , checkTokenAndGetIndex = function (classList, token) {\n                    if (token === \"\") {\n                        throw new DOMEx(\n                            \"SYNTAX_ERR\"\n                            , \"An invalid or illegal string was specified\"\n                        );\n                    }\n                    if (/\\s/.test(token)) {\n                        throw new DOMEx(\n                            \"INVALID_CHARACTER_ERR\"\n                            , \"String contains an invalid character\"\n                        );\n                    }\n                    return arrIndexOf.call(classList, token);\n                }\n                , ClassList = function (elem) {\n                    var\n                        trimmedClasses = strTrim.call(elem.getAttribute(\"class\") || \"\")\n                        , classes = trimmedClasses ? trimmedClasses.split(/\\s+/) : []\n                        , i = 0\n                        , len = classes.length\n                        ;\n                    for (; i < len; i++) {\n                        this.push(classes[i]);\n                    }\n                    this._updateClassName = function () {\n                        elem.setAttribute(\"class\", this.toString());\n                    };\n                }\n                , classListProto = ClassList[protoProp] = []\n                , classListGetter = function () {\n                    return new ClassList(this);\n                }\n                ;\n// Most DOMException implementations don't allow calling DOMException's toString()\n// on non-DOMExceptions. Error's toString() is sufficient here.\n            DOMEx[protoProp] = Error[protoProp];\n            classListProto.item = function (i) {\n                return this[i] || null;\n            };\n            classListProto.contains = function (token) {\n                token += \"\";\n                return checkTokenAndGetIndex(this, token) !== -1;\n            };\n            classListProto.add = function () {\n                var\n                    tokens = arguments\n                    , i = 0\n                    , l = tokens.length\n                    , token\n                    , updated = false\n                    ;\n                do {\n                    token = tokens[i] + \"\";\n                    if (checkTokenAndGetIndex(this, token) === -1) {\n                        this.push(token);\n                        updated = true;\n                    }\n                }\n                while (++i < l);\n\n                if (updated) {\n                    this._updateClassName();\n                }\n            };\n            classListProto.remove = function () {\n                var\n                    tokens = arguments\n                    , i = 0\n                    , l = tokens.length\n                    , token\n                    , updated = false\n                    , index\n                    ;\n                do {\n                    token = tokens[i] + \"\";\n                    index = checkTokenAndGetIndex(this, token);\n                    while (index !== -1) {\n                        this.splice(index, 1);\n                        updated = true;\n                        index = checkTokenAndGetIndex(this, token);\n                    }\n                }\n                while (++i < l);\n\n                if (updated) {\n                    this._updateClassName();\n                }\n            };\n            classListProto.toggle = function (token, force) {\n                token += \"\";\n\n                var\n                    result = this.contains(token)\n                    , method = result ?\n                    force !== true && \"remove\"\n                        :\n                    force !== false && \"add\"\n                    ;\n\n                if (method) {\n                    this[method](token);\n                }\n\n                if (force === true || force === false) {\n                    return force;\n                } else {\n                    return !result;\n                }\n            };\n            classListProto.toString = function () {\n                return this.join(\" \");\n            };\n\n            if (objCtr.defineProperty) {\n                var classListPropDesc = {\n                    get: classListGetter\n                    , enumerable: true\n                    , configurable: true\n                };\n                try {\n                    objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);\n                } catch (ex) { // IE 8 doesn't support enumerable:true\n                    if (ex.number === -0x7FF5EC54) {\n                        classListPropDesc.enumerable = false;\n                        objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);\n                    }\n                }\n            } else if (objCtr[protoProp].__defineGetter__) {\n                elemCtrProto.__defineGetter__(classListProp, classListGetter);\n            }\n\n        }(self));\n\n    } else {\n// There is full or partial native classList support, so just check if we need\n// to normalize the add/remove and toggle APIs.\n\n        (function () {\n            \"use strict\";\n\n            var testElement = document.createElement(\"_\");\n\n            testElement.classList.add(\"c1\", \"c2\");\n\n            // Polyfill for IE 10/11 and Firefox <26, where classList.add and\n            // classList.remove exist but support only one argument at a time.\n            if (!testElement.classList.contains(\"c2\")) {\n                var createMethod = function(method) {\n                    var original = DOMTokenList.prototype[method];\n\n                    DOMTokenList.prototype[method] = function(token) {\n                        var i, len = arguments.length;\n\n                        for (i = 0; i < len; i++) {\n                            token = arguments[i];\n                            original.call(this, token);\n                        }\n                    };\n                };\n                createMethod('add');\n                createMethod('remove');\n            }\n\n            testElement.classList.toggle(\"c3\", false);\n\n            // Polyfill for IE 10 and Firefox <24, where classList.toggle does not\n            // support the second argument.\n            if (testElement.classList.contains(\"c3\")) {\n                var _toggle = DOMTokenList.prototype.toggle;\n\n                DOMTokenList.prototype.toggle = function(token, force) {\n                    if (1 in arguments && !this.contains(token) === !force) {\n                        return force;\n                    } else {\n                        return _toggle.call(this, token);\n                    }\n                };\n\n            }\n\n            testElement = null;\n        }());\n\n    }\n\n}\n\n/**\n * Running the following code before any other code will create trim() if it's not natively available.\n */\nif (!String.prototype.trim) {\n    (function() {\n        // Make sure we trim BOM and NBSP\n        var rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n        String.prototype.trim = function() {\n            return this.replace(rtrim, '');\n        };\n    })();\n}\n\n/**\n * The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.\n */\n// Production steps of ECMA-262, Edition 5, 15.4.4.14\n// Reference: http://es5.github.io/#x15.4.4.14\nif (!Array.prototype.indexOf) {\n    Array.prototype.indexOf = function(searchElement, fromIndex) {\n\n        var k;\n\n        // 1. Let O be the result of calling ToObject passing\n        //    the this value as the argument.\n        if (this == null) {\n            throw new TypeError('\"this\" is null or not defined');\n        }\n\n        var O = Object(this);\n\n        // 2. Let lenValue be the result of calling the Get\n        //    internal method of O with the argument \"length\".\n        // 3. Let len be ToUint32(lenValue).\n        var len = O.length >>> 0;\n\n        // 4. If len is 0, return -1.\n        if (len === 0) {\n            return -1;\n        }\n\n        // 5. If argument fromIndex was passed let n be\n        //    ToInteger(fromIndex); else let n be 0.\n        var n = +fromIndex || 0;\n\n        if (Math.abs(n) === Infinity) {\n            n = 0;\n        }\n\n        // 6. If n >= len, return -1.\n        if (n >= len) {\n            return -1;\n        }\n\n        // 7. If n >= 0, then Let k be n.\n        // 8. Else, n<0, Let k be len - abs(n).\n        //    If k is less than 0, then let k be 0.\n        k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);\n\n        // 9. Repeat, while k < len\n        while (k < len) {\n            // a. Let Pk be ToString(k).\n            //   This is implicit for LHS operands of the in operator\n            // b. Let kPresent be the result of calling the\n            //    HasProperty internal method of O with argument Pk.\n            //   This step can be combined with c\n            // c. If kPresent is true, then\n            //    i.  Let elementK be the result of calling the Get\n            //        internal method of O with the argument ToString(k).\n            //   ii.  Let same be the result of applying the\n            //        Strict Equality Comparison Algorithm to\n            //        searchElement and elementK.\n            //  iii.  If same is true, return k.\n            if (k in O && O[k] === searchElement) {\n                return k;\n            }\n            k++;\n        }\n        return -1;\n    };\n}\n\n/**\n * @license addEventListener polyfill 1.0 / Eirik Backer / MIT Licence\n * https://gist.github.com/2864711/946225eb3822c203e8d6218095d888aac5e1748e\n */\n(function (window, document, listeners_prop_name) {\n    if ((!window.addEventListener || !window.removeEventListener) && window.attachEvent && window.detachEvent) {\n        /**\n         * @param {*} value\n         * @return {boolean}\n         */\n        var is_callable = function (value) {\n            return typeof value === 'function';\n        };\n        /**\n         * @param {!Window|HTMLDocument|Node} self\n         * @param {EventListener|function(!Event):(boolean|undefined)} listener\n         * @return {!function(Event)|undefined}\n         */\n        var listener_get = function (self, listener) {\n            var listeners = listener[listeners_prop_name];\n            if (listeners) {\n                var lis;\n                var i = listeners.length;\n                while (i--) {\n                    lis = listeners[i];\n                    if (lis[0] === self) {\n                        return lis[1];\n                    }\n                }\n            }\n        };\n        /**\n         * @param {!Window|HTMLDocument|Node} self\n         * @param {EventListener|function(!Event):(boolean|undefined)} listener\n         * @param {!function(Event)} callback\n         * @return {!function(Event)}\n         */\n        var listener_set = function (self, listener, callback) {\n            var listeners = listener[listeners_prop_name] || (listener[listeners_prop_name] = []);\n            return listener_get(self, listener) || (listeners[listeners.length] = [self, callback], callback);\n        };\n        /**\n         * @param {string} methodName\n         */\n        var docHijack = function (methodName) {\n            var old = document[methodName];\n            document[methodName] = function (v) {\n                return addListen(old(v));\n            };\n        };\n        /**\n         * @this {!Window|HTMLDocument|Node}\n         * @param {string} type\n         * @param {EventListener|function(!Event):(boolean|undefined)} listener\n         * @param {boolean=} useCapture\n         */\n        var addEvent = function (type, listener, useCapture) {\n            if (is_callable(listener)) {\n                var self = this;\n                self.attachEvent(\n                    'on' + type,\n                    listener_set(self, listener, function (e) {\n                        e = e || window.event;\n                        e.preventDefault = e.preventDefault || function () { e.returnValue = false };\n                        e.stopPropagation = e.stopPropagation || function () { e.cancelBubble = true };\n                        e.target = e.target || e.srcElement || document.documentElement;\n                        e.currentTarget = e.currentTarget || self;\n                        e.timeStamp = e.timeStamp || (new Date()).getTime();\n                        listener.call(self, e);\n                    })\n                );\n            }\n        };\n        /**\n         * @this {!Window|HTMLDocument|Node}\n         * @param {string} type\n         * @param {EventListener|function(!Event):(boolean|undefined)} listener\n         * @param {boolean=} useCapture\n         */\n        var removeEvent = function (type, listener, useCapture) {\n            if (is_callable(listener)) {\n                var self = this;\n                var lis = listener_get(self, listener);\n                if (lis) {\n                    self.detachEvent('on' + type, lis);\n                }\n            }\n        };\n        /**\n         * @param {!Node|NodeList|Array} obj\n         * @return {!Node|NodeList|Array}\n         */\n        var addListen = function (obj) {\n            var i = obj.length;\n            if (i) {\n                while (i--) {\n                    obj[i].addEventListener = addEvent;\n                    obj[i].removeEventListener = removeEvent;\n                }\n            } else {\n                obj.addEventListener = addEvent;\n                obj.removeEventListener = removeEvent;\n            }\n            return obj;\n        };\n\n        addListen([document, window]);\n        if ('Element' in window) {\n            /**\n             * IE8\n             */\n            var element = window.Element;\n            element.prototype.addEventListener = addEvent;\n            element.prototype.removeEventListener = removeEvent;\n        } else {\n            /**\n             * IE < 8\n             */\n                //Make sure we also init at domReady\n            document.attachEvent('onreadystatechange', function () { addListen(document.all) });\n            docHijack('getElementsByTagName');\n            docHijack('getElementById');\n            docHijack('createElement');\n            addListen(document.all);\n        }\n    }\n})(window, document, 'x-ms-event-listeners');\n\n// Production steps of ECMA-262, Edition 5, 15.4.4.18\n// Reference: http://es5.github.com/#x15.4.4.18\nif (!Array.prototype.forEach) {\n\n    Array.prototype.forEach = function forEach(callback, thisArg) {\n        'use strict';\n        var T, k;\n\n        if (this == null) {\n            throw new TypeError(\"this is null or not defined\");\n        }\n\n        var kValue,\n        // 1. Let O be the result of calling ToObject passing the |this| value as the argument.\n            O = Object(this),\n\n        // 2. Let lenValue be the result of calling the Get internal method of O with the argument \"length\".\n        // 3. Let len be ToUint32(lenValue).\n            len = O.length >>> 0; // Hack to convert O.length to a UInt32\n\n        // 4. If IsCallable(callback) is false, throw a TypeError exception.\n        // See: http://es5.github.com/#x9.11\n        if ({}.toString.call(callback) !== \"[object Function]\") {\n            throw new TypeError(callback + \" is not a function\");\n        }\n\n        // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.\n        if (arguments.length >= 2) {\n            T = thisArg;\n        }\n\n        // 6. Let k be 0\n        k = 0;\n\n        // 7. Repeat, while k < len\n        while (k < len) {\n\n            // a. Let Pk be ToString(k).\n            //   This is implicit for LHS operands of the in operator\n            // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.\n            //   This step can be combined with c\n            // c. If kPresent is true, then\n            if (k in O) {\n\n                // i. Let kValue be the result of calling the Get internal method of O with argument Pk.\n                kValue = O[k];\n\n                // ii. Call the Call internal method of callback with T as the this value and\n                // argument list containing kValue, k, and O.\n                callback.call(T, kValue, k, O);\n            }\n            // d. Increase k by 1.\n            k++;\n        }\n        // 8. return undefined\n    };\n}\n\n/**\n * :scope polyfill\n * http://stackoverflow.com/questions/6481612/queryselector-search-immediate-children\n */\n(function(doc, proto) {\n    try { // check if browser supports :scope natively\n        doc.querySelector(':scope body');\n    } catch (err) { // polyfill native methods if it doesn't\n        ['querySelector', 'querySelectorAll'].forEach(function(method) {\n            var native = proto[method];\n            proto[method] = function(selectors) {\n                if (/(^|,)\\s*:scope/.test(selectors)) { // only if selectors contains :scope\n                    var id = this.id; // remember current element id\n                    this.id = 'ID_' + Date.now(); // assign new unique id\n                    selectors = selectors.replace(/((^|,)\\s*):scope/g, '$1#' + this.id); // replace :scope with #ID\n                    var result = doc[method](selectors);\n                    this.id = id; // restore previous id\n                    return result;\n                } else {\n                    return native.call(this, selectors); // use native code for other selectors\n                }\n            }\n        });\n    }\n})(window.document, Element.prototype);\n\nif (navigator.appVersion.indexOf('MSIE 8.') === -1 && navigator.appVersion.indexOf('MSIE 9.') === -1) {\n    /**\n     * The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.\n     * https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Object/assign\n     */\n    if (!Object.assign) {\n        Object.defineProperty(Object, 'assign', {\n            enumerable: false,\n            configurable: true,\n            writable: true,\n            value: function(target, firstSource) {\n                'use strict';\n                if (target === undefined || target === null) {\n                    throw new TypeError('Cannot convert first argument to object');\n                }\n\n                var to = Object(target);\n                for (var i = 1; i < arguments.length; i++) {\n                    var nextSource = arguments[i];\n                    if (nextSource === undefined || nextSource === null) {\n                        continue;\n                    }\n\n                    var keysArray = Object.keys(Object(nextSource));\n                    for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {\n                        var nextKey = keysArray[nextIndex];\n                        var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);\n                        if (desc !== undefined && desc.enumerable) {\n                            to[nextKey] = nextSource[nextKey];\n                        }\n                    }\n                }\n                return to;\n            }\n        });\n    }\n}\n\n/*\n * The Array.isArray() method returns true if an object is an array, false if it is not.\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray\n */\nif (!Array.isArray) {\n    Array.isArray = function(arg) {\n        return Object.prototype.toString.call(arg) === '[object Array]';\n    };\n}\n\nfunction cbExtendObjects () {\n    for ( var i = 1, arg = arguments.length; i < arg; i++ ) {\n        for ( var key in arguments[i] ) {\n            if( arguments[i].hasOwnProperty(key) ) {\n                arguments[0][key] = arguments[i][key];\n            }\n        }\n    }\n    return arguments[0];\n}"
  },
  {
    "path": "static/assets/plugins/datatables/dataTables.bootstrap.js",
    "content": "/*! DataTables Bootstrap 3 integration\n * ©2011-2014 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and\n * DataTables 1.10 or newer.\n *\n * This file sets the defaults and adds options to DataTables to style its\n * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap\n * for further information.\n */\n(function(window, document, undefined){\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\n\n/* Set the defaults for DataTables initialisation */\n$.extend( true, DataTable.defaults, {\n\tdom:\n\t\t\"<'row'<'col-sm-6'l><'col-sm-6'f>>\" +\n\t\t\"<'row'<'col-sm-12'tr>>\" +\n\t\t\"<'row'<'col-sm-6'i><'col-sm-6'p>>\",\n\trenderer: 'bootstrap'\n} );\n\n\n/* Default class modification */\n$.extend( DataTable.ext.classes, {\n\tsWrapper:      \"dataTables_wrapper form-inline dt-bootstrap\",\n\tsFilterInput:  \"form-control input-sm\",\n\tsLengthSelect: \"form-control input-sm\"\n} );\n\n\n/* Bootstrap paging button renderer */\nDataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {\n\tvar api     = new DataTable.Api( settings );\n\tvar classes = settings.oClasses;\n\tvar lang    = settings.oLanguage.oPaginate;\n\tvar btnDisplay, btnClass;\n\n\tvar attach = function( container, buttons ) {\n\t\tvar i, ien, node, button;\n\t\tvar clickHandler = function ( e ) {\n\t\t\te.preventDefault();\n\t\t\tif ( !$(e.currentTarget).hasClass('disabled') ) {\n\t\t\t\tapi.page( e.data.action ).draw( false );\n\t\t\t}\n\t\t};\n\n\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\tbutton = buttons[i];\n\n\t\t\tif ( $.isArray( button ) ) {\n\t\t\t\tattach( container, button );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbtnDisplay = '';\n\t\t\t\tbtnClass = '';\n\n\t\t\t\tswitch ( button ) {\n\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\tbtnDisplay = '&hellip;';\n\t\t\t\t\t\tbtnClass = 'disabled';\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'first':\n\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'next':\n\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'last':\n\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t'active' : '';\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( btnDisplay ) {\n\t\t\t\t\tnode = $('<li>', {\n\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t'tabindex': settings.iTabIndex,\n\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.append( $('<a>', {\n\t\t\t\t\t\t\t\t'href': '#'\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.html( btnDisplay )\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.appendTo( container );\n\n\t\t\t\t\tsettings.oApi._fnBindAction(\n\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tattach(\n\t\t$(host).empty().html('<ul class=\"pagination\"/>').children('ul'),\n\t\tbuttons\n\t);\n};\n\n\n/*\n * TableTools Bootstrap compatibility\n * Required TableTools 2.1+\n */\nif ( DataTable.TableTools ) {\n\t// Set the classes that TableTools uses to something suitable for Bootstrap\n\t$.extend( true, DataTable.TableTools.classes, {\n\t\t\"container\": \"DTTT btn-group\",\n\t\t\"buttons\": {\n\t\t\t\"normal\": \"btn btn-default\",\n\t\t\t\"disabled\": \"disabled\"\n\t\t},\n\t\t\"collection\": {\n\t\t\t\"container\": \"DTTT_dropdown dropdown-menu\",\n\t\t\t\"buttons\": {\n\t\t\t\t\"normal\": \"\",\n\t\t\t\t\"disabled\": \"disabled\"\n\t\t\t}\n\t\t},\n\t\t\"print\": {\n\t\t\t\"info\": \"DTTT_print_info\"\n\t\t},\n\t\t\"select\": {\n\t\t\t\"row\": \"active\"\n\t\t}\n\t} );\n\n\t// Have the collection use a bootstrap compatible drop down\n\t$.extend( true, DataTable.TableTools.DEFAULTS.oTags, {\n\t\t\"collection\": {\n\t\t\t\"container\": \"ul\",\n\t\t\t\"button\": \"li\",\n\t\t\t\"liner\": \"a\"\n\t\t}\n\t} );\n}\n\n}; // /factory\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n})(window, document);\n\n"
  },
  {
    "path": "static/assets/plugins/flot-chart/jquery.flot.crosshair.js",
    "content": "/* Flot plugin for showing crosshairs when the mouse hovers over the plot.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin supports these options:\n\n\tcrosshair: {\n\t\tmode: null or \"x\" or \"y\" or \"xy\"\n\t\tcolor: color\n\t\tlineWidth: number\n\t}\n\nSet the mode to one of \"x\", \"y\" or \"xy\". The \"x\" mode enables a vertical\ncrosshair that lets you trace the values on the x axis, \"y\" enables a\nhorizontal crosshair and \"xy\" enables them both. \"color\" is the color of the\ncrosshair (default is \"rgba(170, 0, 0, 0.80)\"), \"lineWidth\" is the width of\nthe drawn lines (default is 1).\n\nThe plugin also adds four public methods:\n\n  - setCrosshair( pos )\n\n    Set the position of the crosshair. Note that this is cleared if the user\n    moves the mouse. \"pos\" is in coordinates of the plot and should be on the\n    form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple\n    axes), which is coincidentally the same format as what you get from a\n    \"plothover\" event. If \"pos\" is null, the crosshair is cleared.\n\n  - clearCrosshair()\n\n    Clear the crosshair.\n\n  - lockCrosshair(pos)\n\n    Cause the crosshair to lock to the current location, no longer updating if\n    the user moves the mouse. Optionally supply a position (passed on to\n    setCrosshair()) to move it to.\n\n    Example usage:\n\n\tvar myFlot = $.plot( $(\"#graph\"), ..., { crosshair: { mode: \"x\" } } };\n\t$(\"#graph\").bind( \"plothover\", function ( evt, position, item ) {\n\t\tif ( item ) {\n\t\t\t// Lock the crosshair to the data point being hovered\n\t\t\tmyFlot.lockCrosshair({\n\t\t\t\tx: item.datapoint[ 0 ],\n\t\t\t\ty: item.datapoint[ 1 ]\n\t\t\t});\n\t\t} else {\n\t\t\t// Return normal crosshair operation\n\t\t\tmyFlot.unlockCrosshair();\n\t\t}\n\t});\n\n  - unlockCrosshair()\n\n    Free the crosshair to move again after locking it.\n*/\n\n(function ($) {\n    var options = {\n        crosshair: {\n            mode: null, // one of null, \"x\", \"y\" or \"xy\",\n            color: \"rgba(170, 0, 0, 0.80)\",\n            lineWidth: 1\n        }\n    };\n    \n    function init(plot) {\n        // position of crosshair in pixels\n        var crosshair = { x: -1, y: -1, locked: false };\n\n        plot.setCrosshair = function setCrosshair(pos) {\n            if (!pos)\n                crosshair.x = -1;\n            else {\n                var o = plot.p2c(pos);\n                crosshair.x = Math.max(0, Math.min(o.left, plot.width()));\n                crosshair.y = Math.max(0, Math.min(o.top, plot.height()));\n            }\n            \n            plot.triggerRedrawOverlay();\n        };\n        \n        plot.clearCrosshair = plot.setCrosshair; // passes null for pos\n        \n        plot.lockCrosshair = function lockCrosshair(pos) {\n            if (pos)\n                plot.setCrosshair(pos);\n            crosshair.locked = true;\n        };\n\n        plot.unlockCrosshair = function unlockCrosshair() {\n            crosshair.locked = false;\n        };\n\n        function onMouseOut(e) {\n            if (crosshair.locked)\n                return;\n\n            if (crosshair.x != -1) {\n                crosshair.x = -1;\n                plot.triggerRedrawOverlay();\n            }\n        }\n\n        function onMouseMove(e) {\n            if (crosshair.locked)\n                return;\n                \n            if (plot.getSelection && plot.getSelection()) {\n                crosshair.x = -1; // hide the crosshair while selecting\n                return;\n            }\n                \n            var offset = plot.offset();\n            crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));\n            crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));\n            plot.triggerRedrawOverlay();\n        }\n        \n        plot.hooks.bindEvents.push(function (plot, eventHolder) {\n            if (!plot.getOptions().crosshair.mode)\n                return;\n\n            eventHolder.mouseout(onMouseOut);\n            eventHolder.mousemove(onMouseMove);\n        });\n\n        plot.hooks.drawOverlay.push(function (plot, ctx) {\n            var c = plot.getOptions().crosshair;\n            if (!c.mode)\n                return;\n\n            var plotOffset = plot.getPlotOffset();\n            \n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            if (crosshair.x != -1) {\n                var adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0;\n\n                ctx.strokeStyle = c.color;\n                ctx.lineWidth = c.lineWidth;\n                ctx.lineJoin = \"round\";\n\n                ctx.beginPath();\n                if (c.mode.indexOf(\"x\") != -1) {\n                    var drawX = Math.floor(crosshair.x) + adj;\n                    ctx.moveTo(drawX, 0);\n                    ctx.lineTo(drawX, plot.height());\n                }\n                if (c.mode.indexOf(\"y\") != -1) {\n                    var drawY = Math.floor(crosshair.y) + adj;\n                    ctx.moveTo(0, drawY);\n                    ctx.lineTo(plot.width(), drawY);\n                }\n                ctx.stroke();\n            }\n            ctx.restore();\n        });\n\n        plot.hooks.shutdown.push(function (plot, eventHolder) {\n            eventHolder.unbind(\"mouseout\", onMouseOut);\n            eventHolder.unbind(\"mousemove\", onMouseMove);\n        });\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'crosshair',\n        version: '1.0'\n    });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/flot-chart/jquery.flot.js",
    "content": "/* Javascript plotting library for jQuery, version 0.8.1.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\n*/\n\n// first an inline dependency, jquery.colorhelpers.js, we inline it here\n// for convenience\n\n/* Plugin for jQuery for working with colors.\n *\n * Version 1.1.\n *\n * Inspiration from jQuery color animation plugin by John Resig.\n *\n * Released under the MIT license by Ole Laursen, October 2009.\n *\n * Examples:\n *\n *   $.color.parse(\"#fff\").scale('rgb', 0.25).add('a', -0.5).toString()\n *   var c = $.color.extract($(\"#mydiv\"), 'background-color');\n *   console.log(c.r, c.g, c.b, c.a);\n *   $.color.make(100, 50, 25, 0.4).toString() // returns \"rgba(100,50,25,0.4)\"\n *\n * Note that .scale() and .add() return the same modified object\n * instead of making a new one.\n *\n * V. 1.1: Fix error handling so e.g. parsing an empty string does\n * produce a color rather than just crashing.\n */\n(function(B){B.color={};B.color.make=function(F,E,C,D){var G={};G.r=F||0;G.g=E||0;G.b=C||0;G.a=D!=null?D:1;G.add=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]+=I}return G.normalize()};G.scale=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]*=I}return G.normalize()};G.toString=function(){if(G.a>=1){return\"rgb(\"+[G.r,G.g,G.b].join(\",\")+\")\"}else{return\"rgba(\"+[G.r,G.g,G.b,G.a].join(\",\")+\")\"}};G.normalize=function(){function H(J,K,I){return K<J?J:(K>I?I:K)}G.r=H(0,parseInt(G.r),255);G.g=H(0,parseInt(G.g),255);G.b=H(0,parseInt(G.b),255);G.a=H(0,G.a,1);return G};G.clone=function(){return B.color.make(G.r,G.b,G.g,G.a)};return G.normalize()};B.color.extract=function(D,C){var E;do{E=D.css(C).toLowerCase();if(E!=\"\"&&E!=\"transparent\"){break}D=D.parent()}while(!B.nodeName(D.get(0),\"body\"));if(E==\"rgba(0, 0, 0, 0)\"){E=\"transparent\"}return B.color.parse(E)};B.color.parse=function(F){var E,C=B.color.make;if(E=/rgb\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10))}if(E=/rgba\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10),parseFloat(E[4]))}if(E=/rgb\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*\\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55)}if(E=/rgba\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55,parseFloat(E[4]))}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return C(parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16))}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return C(parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16))}var D=B.trim(F).toLowerCase();if(D==\"transparent\"){return C(255,255,255,0)}else{E=A[D]||[0,0,0];return C(E[0],E[1],E[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);\n\n// the actual Flot code\n(function($) {\n\n\t// Cache the prototype hasOwnProperty for faster access\n\n\tvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// The Canvas object is a wrapper around an HTML5 <canvas> tag.\n\t//\n\t// @constructor\n\t// @param {string} cls List of classes to apply to the canvas.\n\t// @param {element} container Element onto which to append the canvas.\n\t//\n\t// Requiring a container is a little iffy, but unfortunately canvas\n\t// operations don't work unless the canvas is attached to the DOM.\n\n\tfunction Canvas(cls, container) {\n\n\t\tvar element = container.children(\".\" + cls)[0];\n\n\t\tif (element == null) {\n\n\t\t\telement = document.createElement(\"canvas\");\n\t\t\telement.className = cls;\n\n\t\t\t$(element).css({ direction: \"ltr\", position: \"absolute\", left: 0, top: 0 })\n\t\t\t\t.appendTo(container);\n\n\t\t\t// If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas\n\n\t\t\tif (!element.getContext) {\n\t\t\t\tif (window.G_vmlCanvasManager) {\n\t\t\t\t\telement = window.G_vmlCanvasManager.initElement(element);\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\"Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element = element;\n\n\t\tvar context = this.context = element.getContext(\"2d\");\n\n\t\t// Determine the screen's ratio of physical to device-independent\n\t\t// pixels.  This is the ratio between the canvas width that the browser\n\t\t// advertises and the number of pixels actually present in that space.\n\n\t\t// The iPhone 4, for example, has a device-independent width of 320px,\n\t\t// but its screen is actually 640px wide.  It therefore has a pixel\n\t\t// ratio of 2, while most normal devices have a ratio of 1.\n\n\t\tvar devicePixelRatio = window.devicePixelRatio || 1,\n\t\t\tbackingStoreRatio =\n\t\t\t\tcontext.webkitBackingStorePixelRatio ||\n\t\t\t\tcontext.mozBackingStorePixelRatio ||\n\t\t\t\tcontext.msBackingStorePixelRatio ||\n\t\t\t\tcontext.oBackingStorePixelRatio ||\n\t\t\t\tcontext.backingStorePixelRatio || 1;\n\n\t\tthis.pixelRatio = devicePixelRatio / backingStoreRatio;\n\n\t\t// Size the canvas to match the internal dimensions of its container\n\n\t\tthis.resize(container.width(), container.height());\n\n\t\t// Collection of HTML div layers for text overlaid onto the canvas\n\n\t\tthis.textContainer = null;\n\t\tthis.text = {};\n\n\t\t// Cache of text fragments and metrics, so we can avoid expensively\n\t\t// re-calculating them when the plot is re-rendered in a loop.\n\n\t\tthis._textCache = {};\n\t}\n\n\t// Resizes the canvas to the given dimensions.\n\t//\n\t// @param {number} width New width of the canvas, in pixels.\n\t// @param {number} width New height of the canvas, in pixels.\n\n\tCanvas.prototype.resize = function(width, height) {\n\n\t\tif (width <= 0 || height <= 0) {\n\t\t\tthrow new Error(\"Invalid dimensions for plot, width = \" + width + \", height = \" + height);\n\t\t}\n\n\t\tvar element = this.element,\n\t\t\tcontext = this.context,\n\t\t\tpixelRatio = this.pixelRatio;\n\n\t\t// Resize the canvas, increasing its density based on the display's\n\t\t// pixel ratio; basically giving it more pixels without increasing the\n\t\t// size of its element, to take advantage of the fact that retina\n\t\t// displays have that many more pixels in the same advertised space.\n\n\t\t// Resizing should reset the state (excanvas seems to be buggy though)\n\n\t\tif (this.width != width) {\n\t\t\telement.width = width * pixelRatio;\n\t\t\telement.style.width = width + \"px\";\n\t\t\tthis.width = width;\n\t\t}\n\n\t\tif (this.height != height) {\n\t\t\telement.height = height * pixelRatio;\n\t\t\telement.style.height = height + \"px\";\n\t\t\tthis.height = height;\n\t\t}\n\n\t\t// Save the context, so we can reset in case we get replotted.  The\n\t\t// restore ensure that we're really back at the initial state, and\n\t\t// should be safe even if we haven't saved the initial state yet.\n\n\t\tcontext.restore();\n\t\tcontext.save();\n\n\t\t// Scale the coordinate space to match the display density; so even though we\n\t\t// may have twice as many pixels, we still want lines and other drawing to\n\t\t// appear at the same size; the extra pixels will just make them crisper.\n\n\t\tcontext.scale(pixelRatio, pixelRatio);\n\t};\n\n\t// Clears the entire canvas area, not including any overlaid HTML text\n\n\tCanvas.prototype.clear = function() {\n\t\tthis.context.clearRect(0, 0, this.width, this.height);\n\t};\n\n\t// Finishes rendering the canvas, including managing the text overlay.\n\n\tCanvas.prototype.render = function() {\n\n\t\tvar cache = this._textCache;\n\n\t\t// For each text layer, add elements marked as active that haven't\n\t\t// already been rendered, and remove those that are no longer active.\n\n\t\tfor (var layerKey in cache) {\n\t\t\tif (hasOwnProperty.call(cache, layerKey)) {\n\n\t\t\t\tvar layer = this.getTextLayer(layerKey),\n\t\t\t\t\tlayerCache = cache[layerKey];\n\n\t\t\t\tlayer.hide();\n\n\t\t\t\tfor (var styleKey in layerCache) {\n\t\t\t\t\tif (hasOwnProperty.call(layerCache, styleKey)) {\n\t\t\t\t\t\tvar styleCache = layerCache[styleKey];\n\t\t\t\t\t\tfor (var key in styleCache) {\n\t\t\t\t\t\t\tif (hasOwnProperty.call(styleCache, key)) {\n\n\t\t\t\t\t\t\t\tvar positions = styleCache[key].positions;\n\n\t\t\t\t\t\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\t\t\t\t\t\tif (position.active) {\n\t\t\t\t\t\t\t\t\t\tif (!position.rendered) {\n\t\t\t\t\t\t\t\t\t\t\tlayer.append(position.element);\n\t\t\t\t\t\t\t\t\t\t\tposition.rendered = true;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tpositions.splice(i--, 1);\n\t\t\t\t\t\t\t\t\t\tif (position.rendered) {\n\t\t\t\t\t\t\t\t\t\t\tposition.element.detach();\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (positions.length == 0) {\n\t\t\t\t\t\t\t\t\tdelete styleCache[key];\n\t\t\t\t\t\t\t\t}\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\n\t\t\t\tlayer.show();\n\t\t\t}\n\t\t}\n\t};\n\n\t// Creates (if necessary) and returns the text overlay container.\n\t//\n\t// @param {string} classes String of space-separated CSS classes used to\n\t//     uniquely identify the text layer.\n\t// @return {object} The jQuery-wrapped text-layer div.\n\n\tCanvas.prototype.getTextLayer = function(classes) {\n\n\t\tvar layer = this.text[classes];\n\n\t\t// Create the text layer if it doesn't exist\n\n\t\tif (layer == null) {\n\n\t\t\t// Create the text layer container, if it doesn't exist\n\n\t\t\tif (this.textContainer == null) {\n\t\t\t\tthis.textContainer = $(\"<div class='flot-text'></div>\")\n\t\t\t\t\t.css({\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\tbottom: 0,\n\t\t\t\t\t\tright: 0,\n\t\t\t\t\t\t'font-size': \"smaller\",\n\t\t\t\t\t\tcolor: \"#545454\"\n\t\t\t\t\t})\n\t\t\t\t\t.insertAfter(this.element);\n\t\t\t}\n\n\t\t\tlayer = this.text[classes] = $(\"<div></div>\")\n\t\t\t\t.addClass(classes)\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0,\n\t\t\t\t\tbottom: 0,\n\t\t\t\t\tright: 0\n\t\t\t\t})\n\t\t\t\t.appendTo(this.textContainer);\n\t\t}\n\n\t\treturn layer;\n\t};\n\n\t// Creates (if necessary) and returns a text info object.\n\t//\n\t// The object looks like this:\n\t//\n\t// {\n\t//     width: Width of the text's wrapper div.\n\t//     height: Height of the text's wrapper div.\n\t//     element: The jQuery-wrapped HTML div containing the text.\n\t//     positions: Array of positions at which this text is drawn.\n\t// }\n\t//\n\t// The positions array contains objects that look like this:\n\t//\n\t// {\n\t//     active: Flag indicating whether the text should be visible.\n\t//     rendered: Flag indicating whether the text is currently visible.\n\t//     element: The jQuery-wrapped HTML div containing the text.\n\t//     x: X coordinate at which to draw the text.\n\t//     y: Y coordinate at which to draw the text.\n\t// }\n\t//\n\t// Each position after the first receives a clone of the original element.\n\t//\n\t// The idea is that that the width, height, and general 'identity' of the\n\t// text is constant no matter where it is placed; the placements are a\n\t// secondary property.\n\t//\n\t// Canvas maintains a cache of recently-used text info objects; getTextInfo\n\t// either returns the cached element or creates a new entry.\n\t//\n\t// @param {string} layer A string of space-separated CSS classes uniquely\n\t//     identifying the layer containing this text.\n\t// @param {string} text Text string to retrieve info for.\n\t// @param {(string|object)=} font Either a string of space-separated CSS\n\t//     classes or a font-spec object, defining the text's font and style.\n\t// @param {number=} angle Angle at which to rotate the text, in degrees.\n\t//     Angle is currently unused, it will be implemented in the future.\n\t// @param {number=} width Maximum width of the text before it wraps.\n\t// @return {object} a text info object.\n\n\tCanvas.prototype.getTextInfo = function(layer, text, font, angle, width) {\n\n\t\tvar textStyle, layerCache, styleCache, info;\n\n\t\t// Cast the value to a string, in case we were given a number or such\n\n\t\ttext = \"\" + text;\n\n\t\t// If the font is a font-spec object, generate a CSS font definition\n\n\t\tif (typeof font === \"object\") {\n\t\t\ttextStyle = font.style + \" \" + font.variant + \" \" + font.weight + \" \" + font.size + \"px/\" + font.lineHeight + \"px \" + font.family;\n\t\t} else {\n\t\t\ttextStyle = font;\n\t\t}\n\n\t\t// Retrieve (or create) the cache for the text's layer and styles\n\n\t\tlayerCache = this._textCache[layer];\n\n\t\tif (layerCache == null) {\n\t\t\tlayerCache = this._textCache[layer] = {};\n\t\t}\n\n\t\tstyleCache = layerCache[textStyle];\n\n\t\tif (styleCache == null) {\n\t\t\tstyleCache = layerCache[textStyle] = {};\n\t\t}\n\n\t\tinfo = styleCache[text];\n\n\t\t// If we can't find a matching element in our cache, create a new one\n\n\t\tif (info == null) {\n\n\t\t\tvar element = $(\"<div></div>\").html(text)\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t'max-width': width,\n\t\t\t\t\ttop: -9999\n\t\t\t\t})\n\t\t\t\t.appendTo(this.getTextLayer(layer));\n\n\t\t\tif (typeof font === \"object\") {\n\t\t\t\telement.css({\n\t\t\t\t\tfont: textStyle,\n\t\t\t\t\tcolor: font.color\n\t\t\t\t});\n\t\t\t} else if (typeof font === \"string\") {\n\t\t\t\telement.addClass(font);\n\t\t\t}\n\n\t\t\tinfo = styleCache[text] = {\n\t\t\t\twidth: element.outerWidth(true),\n\t\t\t\theight: element.outerHeight(true),\n\t\t\t\telement: element,\n\t\t\t\tpositions: []\n\t\t\t};\n\n\t\t\telement.detach();\n\t\t}\n\n\t\treturn info;\n\t};\n\n\t// Adds a text string to the canvas text overlay.\n\t//\n\t// The text isn't drawn immediately; it is marked as rendering, which will\n\t// result in its addition to the canvas on the next render pass.\n\t//\n\t// @param {string} layer A string of space-separated CSS classes uniquely\n\t//     identifying the layer containing this text.\n\t// @param {number} x X coordinate at which to draw the text.\n\t// @param {number} y Y coordinate at which to draw the text.\n\t// @param {string} text Text string to draw.\n\t// @param {(string|object)=} font Either a string of space-separated CSS\n\t//     classes or a font-spec object, defining the text's font and style.\n\t// @param {number=} angle Angle at which to rotate the text, in degrees.\n\t//     Angle is currently unused, it will be implemented in the future.\n\t// @param {number=} width Maximum width of the text before it wraps.\n\t// @param {string=} halign Horizontal alignment of the text; either \"left\",\n\t//     \"center\" or \"right\".\n\t// @param {string=} valign Vertical alignment of the text; either \"top\",\n\t//     \"middle\" or \"bottom\".\n\n\tCanvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {\n\n\t\tvar info = this.getTextInfo(layer, text, font, angle, width),\n\t\t\tpositions = info.positions;\n\n\t\t// Tweak the div's position to match the text's alignment\n\n\t\tif (halign == \"center\") {\n\t\t\tx -= info.width / 2;\n\t\t} else if (halign == \"right\") {\n\t\t\tx -= info.width;\n\t\t}\n\n\t\tif (valign == \"middle\") {\n\t\t\ty -= info.height / 2;\n\t\t} else if (valign == \"bottom\") {\n\t\t\ty -= info.height;\n\t\t}\n\n\t\t// Determine whether this text already exists at this position.\n\t\t// If so, mark it for inclusion in the next render pass.\n\n\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\tif (position.x == x && position.y == y) {\n\t\t\t\tposition.active = true;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// If the text doesn't exist at this position, create a new entry\n\n\t\t// For the very first position we'll re-use the original element,\n\t\t// while for subsequent ones we'll clone it.\n\n\t\tposition = {\n\t\t\tactive: true,\n\t\t\trendered: false,\n\t\t\telement: positions.length ? info.element.clone() : info.element,\n\t\t\tx: x,\n\t\t\ty: y\n\t\t}\n\n\t\tpositions.push(position);\n\n\t\t// Move the element to its final position within the container\n\n\t\tposition.element.css({\n\t\t\ttop: Math.round(y),\n\t\t\tleft: Math.round(x),\n\t\t\t'text-align': halign\t// In case the text wraps\n\t\t});\n\t};\n\n\t// Removes one or more text strings from the canvas text overlay.\n\t//\n\t// If no parameters are given, all text within the layer is removed.\n\t//\n\t// Note that the text is not immediately removed; it is simply marked as\n\t// inactive, which will result in its removal on the next render pass.\n\t// This avoids the performance penalty for 'clear and redraw' behavior,\n\t// where we potentially get rid of all text on a layer, but will likely\n\t// add back most or all of it later, as when redrawing axes, for example.\n\t//\n\t// @param {string} layer A string of space-separated CSS classes uniquely\n\t//     identifying the layer containing this text.\n\t// @param {number=} x X coordinate of the text.\n\t// @param {number=} y Y coordinate of the text.\n\t// @param {string=} text Text string to remove.\n\t// @param {(string|object)=} font Either a string of space-separated CSS\n\t//     classes or a font-spec object, defining the text's font and style.\n\t// @param {number=} angle Angle at which the text is rotated, in degrees.\n\t//     Angle is currently unused, it will be implemented in the future.\n\n\tCanvas.prototype.removeText = function(layer, x, y, text, font, angle) {\n\t\tif (text == null) {\n\t\t\tvar layerCache = this._textCache[layer];\n\t\t\tif (layerCache != null) {\n\t\t\t\tfor (var styleKey in layerCache) {\n\t\t\t\t\tif (hasOwnProperty.call(layerCache, styleKey)) {\n\t\t\t\t\t\tvar styleCache = layerCache[styleKey];\n\t\t\t\t\t\tfor (var key in styleCache) {\n\t\t\t\t\t\t\tif (hasOwnProperty.call(styleCache, key)) {\n\t\t\t\t\t\t\t\tvar positions = styleCache[key].positions;\n\t\t\t\t\t\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\t\t\t\t\t\tposition.active = false;\n\t\t\t\t\t\t\t\t}\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} else {\n\t\t\tvar positions = this.getTextInfo(layer, text, font, angle).positions;\n\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\tif (position.x == x && position.y == y) {\n\t\t\t\t\tposition.active = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// The top-level container for the entire plot.\n\n    function Plot(placeholder, data_, options_, plugins) {\n        // data is on the form:\n        //   [ series1, series2 ... ]\n        // where series is either just the data as [ [x1, y1], [x2, y2], ... ]\n        // or { data: [ [x1, y1], [x2, y2], ... ], label: \"some label\", ... }\n\n        var series = [],\n            options = {\n                // the color theme used for graphs\n                colors: [\"#edc240\", \"#afd8f8\", \"#cb4b4b\", \"#4da74d\", \"#9440ed\"],\n                legend: {\n                    show: true,\n                    noColumns: 1, // number of colums in legend table\n                    labelFormatter: null, // fn: string -> string\n                    labelBoxBorderColor: \"#ccc\", // border color for the little label boxes\n                    container: null, // container (as jQuery object) to put legend in, null means default on top of graph\n                    position: \"ne\", // position of default legend container within plot\n                    margin: 5, // distance from grid edge to default legend container within plot\n                    backgroundColor: null, // null means auto-detect\n                    backgroundOpacity: 0.85, // set to 0 to avoid background\n                    sorted: null    // default to no legend sorting\n                },\n                xaxis: {\n                    show: null, // null = auto-detect, true = always, false = never\n                    position: \"bottom\", // or \"top\"\n                    mode: null, // null or \"time\"\n                    font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: \"italic\", weight: \"bold\", family: \"sans-serif\", variant: \"small-caps\" }\n                    color: null, // base color, labels, ticks\n                    tickColor: null, // possibly different color of ticks, e.g. \"rgba(0,0,0,0.15)\"\n                    transform: null, // null or f: number -> number to transform axis\n                    inverseTransform: null, // if transform is set, this should be the inverse function\n                    min: null, // min. value to show, null means set automatically\n                    max: null, // max. value to show, null means set automatically\n                    autoscaleMargin: null, // margin in % to add if auto-setting min/max\n                    ticks: null, // either [1, 3] or [[1, \"a\"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks\n                    tickFormatter: null, // fn: number -> string\n                    labelWidth: null, // size of tick labels in pixels\n                    labelHeight: null,\n                    reserveSpace: null, // whether to reserve space even if axis isn't shown\n                    tickLength: null, // size in pixels of ticks, or \"full\" for whole line\n                    alignTicksWithAxis: null, // axis number or null for no sync\n                    tickDecimals: null, // no. of decimals, null means auto\n                    tickSize: null, // number or [number, \"unit\"]\n                    minTickSize: null // number or [number, \"unit\"]\n                },\n                yaxis: {\n                    autoscaleMargin: 0.02,\n                    position: \"left\" // or \"right\"\n                },\n                xaxes: [],\n                yaxes: [],\n                series: {\n                    points: {\n                        show: false,\n                        radius: 3,\n                        lineWidth: 2, // in pixels\n                        fill: true,\n                        fillColor: \"#ffffff\",\n                        symbol: \"circle\" // or callback\n                    },\n                    lines: {\n                        // we don't put in show: false so we can see\n                        // whether lines were actively disabled\n                        lineWidth: 2, // in pixels\n                        fill: false,\n                        fillColor: null,\n                        steps: false\n                        // Omit 'zero', so we can later default its value to\n                        // match that of the 'fill' option.\n                    },\n                    bars: {\n                        show: false,\n                        lineWidth: 2, // in pixels\n                        barWidth: 1, // in units of the x axis\n                        fill: true,\n                        fillColor: null,\n                        align: \"left\", // \"left\", \"right\", or \"center\"\n                        horizontal: false,\n                        zero: true\n                    },\n                    shadowSize: 3,\n                    highlightColor: null\n                },\n                grid: {\n                    show: true,\n                    aboveData: false,\n                    color: \"#545454\", // primary color used for outline and labels\n                    backgroundColor: null, // null for transparent, else color\n                    borderColor: null, // set if different from the grid color\n                    tickColor: null, // color for the ticks, e.g. \"rgba(0,0,0,0.15)\"\n                    margin: 0, // distance from the canvas edge to the grid\n                    labelMargin: 5, // in pixels\n                    axisMargin: 8, // in pixels\n                    borderWidth: 2, // in pixels\n                    minBorderMargin: null, // in pixels, null means taken from points radius\n                    markings: null, // array of ranges or fn: axes -> array of ranges\n                    markingsColor: \"#f4f4f4\",\n                    markingsLineWidth: 2,\n                    // interactive stuff\n                    clickable: false,\n                    hoverable: false,\n                    autoHighlight: true, // highlight in case mouse is near\n                    mouseActiveRadius: 10 // how far the mouse can be away to activate an item\n                },\n                interaction: {\n                    redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow\n                },\n                hooks: {}\n            },\n        surface = null,     // the canvas for the plot itself\n        overlay = null,     // canvas for interactive stuff on top of plot\n        eventHolder = null, // jQuery object that events should be bound to\n        ctx = null, octx = null,\n        xaxes = [], yaxes = [],\n        plotOffset = { left: 0, right: 0, top: 0, bottom: 0},\n        plotWidth = 0, plotHeight = 0,\n        hooks = {\n            processOptions: [],\n            processRawData: [],\n            processDatapoints: [],\n            processOffset: [],\n            drawBackground: [],\n            drawSeries: [],\n            draw: [],\n            bindEvents: [],\n            drawOverlay: [],\n            shutdown: []\n        },\n        plot = this;\n\n        // public functions\n        plot.setData = setData;\n        plot.setupGrid = setupGrid;\n        plot.draw = draw;\n        plot.getPlaceholder = function() { return placeholder; };\n        plot.getCanvas = function() { return surface.element; };\n        plot.getPlotOffset = function() { return plotOffset; };\n        plot.width = function () { return plotWidth; };\n        plot.height = function () { return plotHeight; };\n        plot.offset = function () {\n            var o = eventHolder.offset();\n            o.left += plotOffset.left;\n            o.top += plotOffset.top;\n            return o;\n        };\n        plot.getData = function () { return series; };\n        plot.getAxes = function () {\n            var res = {}, i;\n            $.each(xaxes.concat(yaxes), function (_, axis) {\n                if (axis)\n                    res[axis.direction + (axis.n != 1 ? axis.n : \"\") + \"axis\"] = axis;\n            });\n            return res;\n        };\n        plot.getXAxes = function () { return xaxes; };\n        plot.getYAxes = function () { return yaxes; };\n        plot.c2p = canvasToAxisCoords;\n        plot.p2c = axisToCanvasCoords;\n        plot.getOptions = function () { return options; };\n        plot.highlight = highlight;\n        plot.unhighlight = unhighlight;\n        plot.triggerRedrawOverlay = triggerRedrawOverlay;\n        plot.pointOffset = function(point) {\n            return {\n                left: parseInt(xaxes[axisNumber(point, \"x\") - 1].p2c(+point.x) + plotOffset.left, 10),\n                top: parseInt(yaxes[axisNumber(point, \"y\") - 1].p2c(+point.y) + plotOffset.top, 10)\n            };\n        };\n        plot.shutdown = shutdown;\n        plot.resize = function () {\n        \tvar width = placeholder.width(),\n        \t\theight = placeholder.height();\n            surface.resize(width, height);\n            overlay.resize(width, height);\n        };\n\n        // public attributes\n        plot.hooks = hooks;\n\n        // initialize\n        initPlugins(plot);\n        parseOptions(options_);\n        setupCanvases();\n        setData(data_);\n        setupGrid();\n        draw();\n        bindEvents();\n\n\n        function executeHooks(hook, args) {\n            args = [plot].concat(args);\n            for (var i = 0; i < hook.length; ++i)\n                hook[i].apply(this, args);\n        }\n\n        function initPlugins() {\n\n            // References to key classes, allowing plugins to modify them\n\n            var classes = {\n                Canvas: Canvas\n            };\n\n            for (var i = 0; i < plugins.length; ++i) {\n                var p = plugins[i];\n                p.init(plot, classes);\n                if (p.options)\n                    $.extend(true, options, p.options);\n            }\n        }\n\n        function parseOptions(opts) {\n\n            $.extend(true, options, opts);\n\n            // $.extend merges arrays, rather than replacing them.  When less\n            // colors are provided than the size of the default palette, we\n            // end up with those colors plus the remaining defaults, which is\n            // not expected behavior; avoid it by replacing them here.\n\n            if (opts && opts.colors) {\n            \toptions.colors = opts.colors;\n            }\n\n            if (options.xaxis.color == null)\n                options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();\n            if (options.yaxis.color == null)\n                options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();\n\n            if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility\n                options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color;\n            if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility\n                options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color;\n\n            if (options.grid.borderColor == null)\n                options.grid.borderColor = options.grid.color;\n            if (options.grid.tickColor == null)\n                options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString();\n\n            // Fill in defaults for axis options, including any unspecified\n            // font-spec fields, if a font-spec was provided.\n\n            // If no x/y axis options were provided, create one of each anyway,\n            // since the rest of the code assumes that they exist.\n\n            var i, axisOptions, axisCount,\n                fontDefaults = {\n                    style: placeholder.css(\"font-style\"),\n                    size: Math.round(0.8 * (+placeholder.css(\"font-size\").replace(\"px\", \"\") || 13)),\n                    variant: placeholder.css(\"font-variant\"),\n                    weight: placeholder.css(\"font-weight\"),\n                    family: placeholder.css(\"font-family\")\n                };\n\n            fontDefaults.lineHeight = fontDefaults.size * 1.15;\n\n            axisCount = options.xaxes.length || 1;\n            for (i = 0; i < axisCount; ++i) {\n\n                axisOptions = options.xaxes[i];\n                if (axisOptions && !axisOptions.tickColor) {\n                    axisOptions.tickColor = axisOptions.color;\n                }\n\n                axisOptions = $.extend(true, {}, options.xaxis, axisOptions);\n                options.xaxes[i] = axisOptions;\n\n                if (axisOptions.font) {\n                    axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);\n                    if (!axisOptions.font.color) {\n                        axisOptions.font.color = axisOptions.color;\n                    }\n                }\n            }\n\n            axisCount = options.yaxes.length || 1;\n            for (i = 0; i < axisCount; ++i) {\n\n                axisOptions = options.yaxes[i];\n                if (axisOptions && !axisOptions.tickColor) {\n                    axisOptions.tickColor = axisOptions.color;\n                }\n\n                axisOptions = $.extend(true, {}, options.yaxis, axisOptions);\n                options.yaxes[i] = axisOptions;\n\n                if (axisOptions.font) {\n                    axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);\n                    if (!axisOptions.font.color) {\n                        axisOptions.font.color = axisOptions.color;\n                    }\n                }\n            }\n\n            // backwards compatibility, to be removed in future\n            if (options.xaxis.noTicks && options.xaxis.ticks == null)\n                options.xaxis.ticks = options.xaxis.noTicks;\n            if (options.yaxis.noTicks && options.yaxis.ticks == null)\n                options.yaxis.ticks = options.yaxis.noTicks;\n            if (options.x2axis) {\n                options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);\n                options.xaxes[1].position = \"top\";\n            }\n            if (options.y2axis) {\n                options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);\n                options.yaxes[1].position = \"right\";\n            }\n            if (options.grid.coloredAreas)\n                options.grid.markings = options.grid.coloredAreas;\n            if (options.grid.coloredAreasColor)\n                options.grid.markingsColor = options.grid.coloredAreasColor;\n            if (options.lines)\n                $.extend(true, options.series.lines, options.lines);\n            if (options.points)\n                $.extend(true, options.series.points, options.points);\n            if (options.bars)\n                $.extend(true, options.series.bars, options.bars);\n            if (options.shadowSize != null)\n                options.series.shadowSize = options.shadowSize;\n            if (options.highlightColor != null)\n                options.series.highlightColor = options.highlightColor;\n\n            // save options on axes for future reference\n            for (i = 0; i < options.xaxes.length; ++i)\n                getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];\n            for (i = 0; i < options.yaxes.length; ++i)\n                getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i];\n\n            // add hooks from options\n            for (var n in hooks)\n                if (options.hooks[n] && options.hooks[n].length)\n                    hooks[n] = hooks[n].concat(options.hooks[n]);\n\n            executeHooks(hooks.processOptions, [options]);\n        }\n\n        function setData(d) {\n            series = parseData(d);\n            fillInSeriesOptions();\n            processData();\n        }\n\n        function parseData(d) {\n            var res = [];\n            for (var i = 0; i < d.length; ++i) {\n                var s = $.extend(true, {}, options.series);\n\n                if (d[i].data != null) {\n                    s.data = d[i].data; // move the data instead of deep-copy\n                    delete d[i].data;\n\n                    $.extend(true, s, d[i]);\n\n                    d[i].data = s.data;\n                }\n                else\n                    s.data = d[i];\n                res.push(s);\n            }\n\n            return res;\n        }\n\n        function axisNumber(obj, coord) {\n            var a = obj[coord + \"axis\"];\n            if (typeof a == \"object\") // if we got a real axis, extract number\n                a = a.n;\n            if (typeof a != \"number\")\n                a = 1; // default to first axis\n            return a;\n        }\n\n        function allAxes() {\n            // return flat array without annoying null entries\n            return $.grep(xaxes.concat(yaxes), function (a) { return a; });\n        }\n\n        function canvasToAxisCoords(pos) {\n            // return an object with x/y corresponding to all used axes\n            var res = {}, i, axis;\n            for (i = 0; i < xaxes.length; ++i) {\n                axis = xaxes[i];\n                if (axis && axis.used)\n                    res[\"x\" + axis.n] = axis.c2p(pos.left);\n            }\n\n            for (i = 0; i < yaxes.length; ++i) {\n                axis = yaxes[i];\n                if (axis && axis.used)\n                    res[\"y\" + axis.n] = axis.c2p(pos.top);\n            }\n\n            if (res.x1 !== undefined)\n                res.x = res.x1;\n            if (res.y1 !== undefined)\n                res.y = res.y1;\n\n            return res;\n        }\n\n        function axisToCanvasCoords(pos) {\n            // get canvas coords from the first pair of x/y found in pos\n            var res = {}, i, axis, key;\n\n            for (i = 0; i < xaxes.length; ++i) {\n                axis = xaxes[i];\n                if (axis && axis.used) {\n                    key = \"x\" + axis.n;\n                    if (pos[key] == null && axis.n == 1)\n                        key = \"x\";\n\n                    if (pos[key] != null) {\n                        res.left = axis.p2c(pos[key]);\n                        break;\n                    }\n                }\n            }\n\n            for (i = 0; i < yaxes.length; ++i) {\n                axis = yaxes[i];\n                if (axis && axis.used) {\n                    key = \"y\" + axis.n;\n                    if (pos[key] == null && axis.n == 1)\n                        key = \"y\";\n\n                    if (pos[key] != null) {\n                        res.top = axis.p2c(pos[key]);\n                        break;\n                    }\n                }\n            }\n\n            return res;\n        }\n\n        function getOrCreateAxis(axes, number) {\n            if (!axes[number - 1])\n                axes[number - 1] = {\n                    n: number, // save the number for future reference\n                    direction: axes == xaxes ? \"x\" : \"y\",\n                    options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)\n                };\n\n            return axes[number - 1];\n        }\n\n        function fillInSeriesOptions() {\n\n            var neededColors = series.length, maxIndex = -1, i;\n\n            // Subtract the number of series that already have fixed colors or\n            // color indexes from the number that we still need to generate.\n\n            for (i = 0; i < series.length; ++i) {\n                var sc = series[i].color;\n                if (sc != null) {\n                    neededColors--;\n                    if (typeof sc == \"number\" && sc > maxIndex) {\n                        maxIndex = sc;\n                    }\n                }\n            }\n\n            // If any of the series have fixed color indexes, then we need to\n            // generate at least as many colors as the highest index.\n\n            if (neededColors <= maxIndex) {\n                neededColors = maxIndex + 1;\n            }\n\n            // Generate all the colors, using first the option colors and then\n            // variations on those colors once they're exhausted.\n\n            var c, colors = [], colorPool = options.colors,\n                colorPoolSize = colorPool.length, variation = 0;\n\n            for (i = 0; i < neededColors; i++) {\n\n                c = $.color.parse(colorPool[i % colorPoolSize] || \"#666\");\n\n                // Each time we exhaust the colors in the pool we adjust\n                // a scaling factor used to produce more variations on\n                // those colors. The factor alternates negative/positive\n                // to produce lighter/darker colors.\n\n                // Reset the variation after every few cycles, or else\n                // it will end up producing only white or black colors.\n\n                if (i % colorPoolSize == 0 && i) {\n                    if (variation >= 0) {\n                        if (variation < 0.5) {\n                            variation = -variation - 0.2;\n                        } else variation = 0;\n                    } else variation = -variation;\n                }\n\n                colors[i] = c.scale('rgb', 1 + variation);\n            }\n\n            // Finalize the series options, filling in their colors\n\n            var colori = 0, s;\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n\n                // assign colors\n                if (s.color == null) {\n                    s.color = colors[colori].toString();\n                    ++colori;\n                }\n                else if (typeof s.color == \"number\")\n                    s.color = colors[s.color].toString();\n\n                // turn on lines automatically in case nothing is set\n                if (s.lines.show == null) {\n                    var v, show = true;\n                    for (v in s)\n                        if (s[v] && s[v].show) {\n                            show = false;\n                            break;\n                        }\n                    if (show)\n                        s.lines.show = true;\n                }\n\n                // If nothing was provided for lines.zero, default it to match\n                // lines.fill, since areas by default should extend to zero.\n\n                if (s.lines.zero == null) {\n                    s.lines.zero = !!s.lines.fill;\n                }\n\n                // setup axes\n                s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, \"x\"));\n                s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, \"y\"));\n            }\n        }\n\n        function processData() {\n            var topSentry = Number.POSITIVE_INFINITY,\n                bottomSentry = Number.NEGATIVE_INFINITY,\n                fakeInfinity = Number.MAX_VALUE,\n                i, j, k, m, length,\n                s, points, ps, x, y, axis, val, f, p,\n                data, format;\n\n            function updateAxis(axis, min, max) {\n                if (min < axis.datamin && min != -fakeInfinity)\n                    axis.datamin = min;\n                if (max > axis.datamax && max != fakeInfinity)\n                    axis.datamax = max;\n            }\n\n            $.each(allAxes(), function (_, axis) {\n                // init axis\n                axis.datamin = topSentry;\n                axis.datamax = bottomSentry;\n                axis.used = false;\n            });\n\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n                s.datapoints = { points: [] };\n\n                executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);\n            }\n\n            // first pass: clean and copy data\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n\n                data = s.data;\n                format = s.datapoints.format;\n\n                if (!format) {\n                    format = [];\n                    // find out how to copy\n                    format.push({ x: true, number: true, required: true });\n                    format.push({ y: true, number: true, required: true });\n\n                    if (s.bars.show || (s.lines.show && s.lines.fill)) {\n                        var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));\n                        format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });\n                        if (s.bars.horizontal) {\n                            delete format[format.length - 1].y;\n                            format[format.length - 1].x = true;\n                        }\n                    }\n\n                    s.datapoints.format = format;\n                }\n\n                if (s.datapoints.pointsize != null)\n                    continue; // already filled in\n\n                s.datapoints.pointsize = format.length;\n\n                ps = s.datapoints.pointsize;\n                points = s.datapoints.points;\n\n                var insertSteps = s.lines.show && s.lines.steps;\n                s.xaxis.used = s.yaxis.used = true;\n\n                for (j = k = 0; j < data.length; ++j, k += ps) {\n                    p = data[j];\n\n                    var nullify = p == null;\n                    if (!nullify) {\n                        for (m = 0; m < ps; ++m) {\n                            val = p[m];\n                            f = format[m];\n\n                            if (f) {\n                                if (f.number && val != null) {\n                                    val = +val; // convert to number\n                                    if (isNaN(val))\n                                        val = null;\n                                    else if (val == Infinity)\n                                        val = fakeInfinity;\n                                    else if (val == -Infinity)\n                                        val = -fakeInfinity;\n                                }\n\n                                if (val == null) {\n                                    if (f.required)\n                                        nullify = true;\n\n                                    if (f.defaultValue != null)\n                                        val = f.defaultValue;\n                                }\n                            }\n\n                            points[k + m] = val;\n                        }\n                    }\n\n                    if (nullify) {\n                        for (m = 0; m < ps; ++m) {\n                            val = points[k + m];\n                            if (val != null) {\n                                f = format[m];\n                                // extract min/max info\n                                if (f.autoscale) {\n                                    if (f.x) {\n                                        updateAxis(s.xaxis, val, val);\n                                    }\n                                    if (f.y) {\n                                        updateAxis(s.yaxis, val, val);\n                                    }\n                                }\n                            }\n                            points[k + m] = null;\n                        }\n                    }\n                    else {\n                        // a little bit of line specific stuff that\n                        // perhaps shouldn't be here, but lacking\n                        // better means...\n                        if (insertSteps && k > 0\n                            && points[k - ps] != null\n                            && points[k - ps] != points[k]\n                            && points[k - ps + 1] != points[k + 1]) {\n                            // copy the point to make room for a middle point\n                            for (m = 0; m < ps; ++m)\n                                points[k + ps + m] = points[k + m];\n\n                            // middle point has same y\n                            points[k + 1] = points[k - ps + 1];\n\n                            // we've added a point, better reflect that\n                            k += ps;\n                        }\n                    }\n                }\n            }\n\n            // give the hooks a chance to run\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n\n                executeHooks(hooks.processDatapoints, [ s, s.datapoints]);\n            }\n\n            // second pass: find datamax/datamin for auto-scaling\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n                points = s.datapoints.points;\n                ps = s.datapoints.pointsize;\n                format = s.datapoints.format;\n\n                var xmin = topSentry, ymin = topSentry,\n                    xmax = bottomSentry, ymax = bottomSentry;\n\n                for (j = 0; j < points.length; j += ps) {\n                    if (points[j] == null)\n                        continue;\n\n                    for (m = 0; m < ps; ++m) {\n                        val = points[j + m];\n                        f = format[m];\n                        if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity)\n                            continue;\n\n                        if (f.x) {\n                            if (val < xmin)\n                                xmin = val;\n                            if (val > xmax)\n                                xmax = val;\n                        }\n                        if (f.y) {\n                            if (val < ymin)\n                                ymin = val;\n                            if (val > ymax)\n                                ymax = val;\n                        }\n                    }\n                }\n\n                if (s.bars.show) {\n                    // make sure we got room for the bar on the dancing floor\n                    var delta;\n\n                    switch (s.bars.align) {\n                        case \"left\":\n                            delta = 0;\n                            break;\n                        case \"right\":\n                            delta = -s.bars.barWidth;\n                            break;\n                        case \"center\":\n                            delta = -s.bars.barWidth / 2;\n                            break;\n                        default:\n                            throw new Error(\"Invalid bar alignment: \" + s.bars.align);\n                    }\n\n                    if (s.bars.horizontal) {\n                        ymin += delta;\n                        ymax += delta + s.bars.barWidth;\n                    }\n                    else {\n                        xmin += delta;\n                        xmax += delta + s.bars.barWidth;\n                    }\n                }\n\n                updateAxis(s.xaxis, xmin, xmax);\n                updateAxis(s.yaxis, ymin, ymax);\n            }\n\n            $.each(allAxes(), function (_, axis) {\n                if (axis.datamin == topSentry)\n                    axis.datamin = null;\n                if (axis.datamax == bottomSentry)\n                    axis.datamax = null;\n            });\n        }\n\n        function setupCanvases() {\n\n            // Make sure the placeholder is clear of everything except canvases\n            // from a previous plot in this container that we'll try to re-use.\n\n            placeholder.css(\"padding\", 0) // padding messes up the positioning\n                .children(\":not(.flot-base,.flot-overlay)\").remove();\n\n            if (placeholder.css(\"position\") == 'static')\n                placeholder.css(\"position\", \"relative\"); // for positioning labels and overlay\n\n            surface = new Canvas(\"flot-base\", placeholder);\n            overlay = new Canvas(\"flot-overlay\", placeholder); // overlay canvas for interactive features\n\n            ctx = surface.context;\n            octx = overlay.context;\n\n            // define which element we're listening for events on\n            eventHolder = $(overlay.element).unbind();\n\n            // If we're re-using a plot object, shut down the old one\n\n            var existing = placeholder.data(\"plot\");\n\n            if (existing) {\n                existing.shutdown();\n                overlay.clear();\n            }\n\n            // save in case we get replotted\n            placeholder.data(\"plot\", plot);\n        }\n\n        function bindEvents() {\n            // bind events\n            if (options.grid.hoverable) {\n                eventHolder.mousemove(onMouseMove);\n\n                // Use bind, rather than .mouseleave, because we officially\n                // still support jQuery 1.2.6, which doesn't define a shortcut\n                // for mouseenter or mouseleave.  This was a bug/oversight that\n                // was fixed somewhere around 1.3.x.  We can return to using\n                // .mouseleave when we drop support for 1.2.6.\n\n                eventHolder.bind(\"mouseleave\", onMouseLeave);\n            }\n\n            if (options.grid.clickable)\n                eventHolder.click(onClick);\n\n            executeHooks(hooks.bindEvents, [eventHolder]);\n        }\n\n        function shutdown() {\n            if (redrawTimeout)\n                clearTimeout(redrawTimeout);\n\n            eventHolder.unbind(\"mousemove\", onMouseMove);\n            eventHolder.unbind(\"mouseleave\", onMouseLeave);\n            eventHolder.unbind(\"click\", onClick);\n\n            executeHooks(hooks.shutdown, [eventHolder]);\n        }\n\n        function setTransformationHelpers(axis) {\n            // set helper functions on the axis, assumes plot area\n            // has been computed already\n\n            function identity(x) { return x; }\n\n            var s, m, t = axis.options.transform || identity,\n                it = axis.options.inverseTransform;\n\n            // precompute how much the axis is scaling a point\n            // in canvas space\n            if (axis.direction == \"x\") {\n                s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));\n                m = Math.min(t(axis.max), t(axis.min));\n            }\n            else {\n                s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));\n                s = -s;\n                m = Math.max(t(axis.max), t(axis.min));\n            }\n\n            // data point to canvas coordinate\n            if (t == identity) // slight optimization\n                axis.p2c = function (p) { return (p - m) * s; };\n            else\n                axis.p2c = function (p) { return (t(p) - m) * s; };\n            // canvas coordinate to data point\n            if (!it)\n                axis.c2p = function (c) { return m + c / s; };\n            else\n                axis.c2p = function (c) { return it(m + c / s); };\n        }\n\n        function measureTickLabels(axis) {\n\n            var opts = axis.options,\n                ticks = axis.ticks || [],\n                labelWidth = opts.labelWidth || 0,\n                labelHeight = opts.labelHeight || 0,\n                maxWidth = labelWidth || axis.direction == \"x\" ? Math.floor(surface.width / (ticks.length || 1)) : null;\n                legacyStyles = axis.direction + \"Axis \" + axis.direction + axis.n + \"Axis\",\n                layer = \"flot-\" + axis.direction + \"-axis flot-\" + axis.direction + axis.n + \"-axis \" + legacyStyles,\n                font = opts.font || \"flot-tick-label tickLabel\";\n\n            for (var i = 0; i < ticks.length; ++i) {\n\n                var t = ticks[i];\n\n                if (!t.label)\n                    continue;\n\n                var info = surface.getTextInfo(layer, t.label, font, null, maxWidth);\n\n                labelWidth = Math.max(labelWidth, info.width);\n                labelHeight = Math.max(labelHeight, info.height);\n            }\n\n            axis.labelWidth = opts.labelWidth || labelWidth;\n            axis.labelHeight = opts.labelHeight || labelHeight;\n        }\n\n        function allocateAxisBoxFirstPhase(axis) {\n            // find the bounding box of the axis by looking at label\n            // widths/heights and ticks, make room by diminishing the\n            // plotOffset; this first phase only looks at one\n            // dimension per axis, the other dimension depends on the\n            // other axes so will have to wait\n\n            var lw = axis.labelWidth,\n                lh = axis.labelHeight,\n                pos = axis.options.position,\n                tickLength = axis.options.tickLength,\n                axisMargin = options.grid.axisMargin,\n                padding = options.grid.labelMargin,\n                all = axis.direction == \"x\" ? xaxes : yaxes,\n                index, innermost;\n\n            // determine axis margin\n            var samePosition = $.grep(all, function (a) {\n                return a && a.options.position == pos && a.reserveSpace;\n            });\n            if ($.inArray(axis, samePosition) == samePosition.length - 1)\n                axisMargin = 0; // outermost\n\n            // determine tick length - if we're innermost, we can use \"full\"\n            if (tickLength == null) {\n                var sameDirection = $.grep(all, function (a) {\n                    return a && a.reserveSpace;\n                });\n\n                innermost = $.inArray(axis, sameDirection) == 0;\n                if (innermost)\n                    tickLength = \"full\";\n                else\n                    tickLength = 5;\n            }\n\n            if (!isNaN(+tickLength))\n                padding += +tickLength;\n\n            // compute box\n            if (axis.direction == \"x\") {\n                lh += padding;\n\n                if (pos == \"bottom\") {\n                    plotOffset.bottom += lh + axisMargin;\n                    axis.box = { top: surface.height - plotOffset.bottom, height: lh };\n                }\n                else {\n                    axis.box = { top: plotOffset.top + axisMargin, height: lh };\n                    plotOffset.top += lh + axisMargin;\n                }\n            }\n            else {\n                lw += padding;\n\n                if (pos == \"left\") {\n                    axis.box = { left: plotOffset.left + axisMargin, width: lw };\n                    plotOffset.left += lw + axisMargin;\n                }\n                else {\n                    plotOffset.right += lw + axisMargin;\n                    axis.box = { left: surface.width - plotOffset.right, width: lw };\n                }\n            }\n\n             // save for future reference\n            axis.position = pos;\n            axis.tickLength = tickLength;\n            axis.box.padding = padding;\n            axis.innermost = innermost;\n        }\n\n        function allocateAxisBoxSecondPhase(axis) {\n            // now that all axis boxes have been placed in one\n            // dimension, we can set the remaining dimension coordinates\n            if (axis.direction == \"x\") {\n                axis.box.left = plotOffset.left - axis.labelWidth / 2;\n                axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth;\n            }\n            else {\n                axis.box.top = plotOffset.top - axis.labelHeight / 2;\n                axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight;\n            }\n        }\n\n        function adjustLayoutForThingsStickingOut() {\n            // possibly adjust plot offset to ensure everything stays\n            // inside the canvas and isn't clipped off\n\n            var minMargin = options.grid.minBorderMargin,\n                margins = { x: 0, y: 0 }, i, axis;\n\n            // check stuff from the plot (FIXME: this should just read\n            // a value from the series, otherwise it's impossible to\n            // customize)\n            if (minMargin == null) {\n                minMargin = 0;\n                for (i = 0; i < series.length; ++i)\n                    minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2));\n            }\n\n            margins.x = margins.y = Math.ceil(minMargin);\n\n            // check axis labels, note we don't check the actual\n            // labels but instead use the overall width/height to not\n            // jump as much around with replots\n            $.each(allAxes(), function (_, axis) {\n                var dir = axis.direction;\n                if (axis.reserveSpace)\n                    margins[dir] = Math.ceil(Math.max(margins[dir], (dir == \"x\" ? axis.labelWidth : axis.labelHeight) / 2));\n            });\n\n            plotOffset.left = Math.max(margins.x, plotOffset.left);\n            plotOffset.right = Math.max(margins.x, plotOffset.right);\n            plotOffset.top = Math.max(margins.y, plotOffset.top);\n            plotOffset.bottom = Math.max(margins.y, plotOffset.bottom);\n        }\n\n        function setupGrid() {\n            var i, axes = allAxes(), showGrid = options.grid.show;\n\n            // Initialize the plot's offset from the edge of the canvas\n\n            for (var a in plotOffset) {\n                var margin = options.grid.margin || 0;\n                plotOffset[a] = typeof margin == \"number\" ? margin : margin[a] || 0;\n            }\n\n            executeHooks(hooks.processOffset, [plotOffset]);\n\n            // If the grid is visible, add its border width to the offset\n\n            for (var a in plotOffset) {\n                if(typeof(options.grid.borderWidth) == \"object\") {\n                    plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0;\n                }\n                else {\n                    plotOffset[a] += showGrid ? options.grid.borderWidth : 0;\n                }\n            }\n\n            // init axes\n            $.each(axes, function (_, axis) {\n                axis.show = axis.options.show;\n                if (axis.show == null)\n                    axis.show = axis.used; // by default an axis is visible if it's got data\n\n                axis.reserveSpace = axis.show || axis.options.reserveSpace;\n\n                setRange(axis);\n            });\n\n            if (showGrid) {\n\n                var allocatedAxes = $.grep(axes, function (axis) { return axis.reserveSpace; });\n\n                $.each(allocatedAxes, function (_, axis) {\n                    // make the ticks\n                    setupTickGeneration(axis);\n                    setTicks(axis);\n                    snapRangeToTicks(axis, axis.ticks);\n                    // find labelWidth/Height for axis\n                    measureTickLabels(axis);\n                });\n\n                // with all dimensions calculated, we can compute the\n                // axis bounding boxes, start from the outside\n                // (reverse order)\n                for (i = allocatedAxes.length - 1; i >= 0; --i)\n                    allocateAxisBoxFirstPhase(allocatedAxes[i]);\n\n                // make sure we've got enough space for things that\n                // might stick out\n                adjustLayoutForThingsStickingOut();\n\n                $.each(allocatedAxes, function (_, axis) {\n                    allocateAxisBoxSecondPhase(axis);\n                });\n            }\n\n            plotWidth = surface.width - plotOffset.left - plotOffset.right;\n            plotHeight = surface.height - plotOffset.bottom - plotOffset.top;\n\n            // now we got the proper plot dimensions, we can compute the scaling\n            $.each(axes, function (_, axis) {\n                setTransformationHelpers(axis);\n            });\n\n            if (showGrid) {\n                drawAxisLabels();\n            }\n\n            insertLegend();\n        }\n\n        function setRange(axis) {\n            var opts = axis.options,\n                min = +(opts.min != null ? opts.min : axis.datamin),\n                max = +(opts.max != null ? opts.max : axis.datamax),\n                delta = max - min;\n\n            if (delta == 0.0) {\n                // degenerate case\n                var widen = max == 0 ? 1 : 0.01;\n\n                if (opts.min == null)\n                    min -= widen;\n                // always widen max if we couldn't widen min to ensure we\n                // don't fall into min == max which doesn't work\n                if (opts.max == null || opts.min != null)\n                    max += widen;\n            }\n            else {\n                // consider autoscaling\n                var margin = opts.autoscaleMargin;\n                if (margin != null) {\n                    if (opts.min == null) {\n                        min -= delta * margin;\n                        // make sure we don't go below zero if all values\n                        // are positive\n                        if (min < 0 && axis.datamin != null && axis.datamin >= 0)\n                            min = 0;\n                    }\n                    if (opts.max == null) {\n                        max += delta * margin;\n                        if (max > 0 && axis.datamax != null && axis.datamax <= 0)\n                            max = 0;\n                    }\n                }\n            }\n            axis.min = min;\n            axis.max = max;\n        }\n\n        function setupTickGeneration(axis) {\n            var opts = axis.options;\n\n            // estimate number of ticks\n            var noTicks;\n            if (typeof opts.ticks == \"number\" && opts.ticks > 0)\n                noTicks = opts.ticks;\n            else\n                // heuristic based on the model a*sqrt(x) fitted to\n                // some data points that seemed reasonable\n                noTicks = 0.3 * Math.sqrt(axis.direction == \"x\" ? surface.width : surface.height);\n\n            var delta = (axis.max - axis.min) / noTicks,\n                dec = -Math.floor(Math.log(delta) / Math.LN10),\n                maxDec = opts.tickDecimals;\n\n            if (maxDec != null && dec > maxDec) {\n                dec = maxDec;\n            }\n\n            var magn = Math.pow(10, -dec),\n                norm = delta / magn, // norm is between 1.0 and 10.0\n                size;\n\n            if (norm < 1.5) {\n                size = 1;\n            } else if (norm < 3) {\n                size = 2;\n                // special case for 2.5, requires an extra decimal\n                if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {\n                    size = 2.5;\n                    ++dec;\n                }\n            } else if (norm < 7.5) {\n                size = 5;\n            } else {\n                size = 10;\n            }\n\n            size *= magn;\n\n            if (opts.minTickSize != null && size < opts.minTickSize) {\n                size = opts.minTickSize;\n            }\n\n            axis.delta = delta;\n            axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);\n            axis.tickSize = opts.tickSize || size;\n\n            // Time mode was moved to a plug-in in 0.8, but since so many people use this\n            // we'll add an especially friendly make sure they remembered to include it.\n\n            if (opts.mode == \"time\" && !axis.tickGenerator) {\n                throw new Error(\"Time mode requires the flot.time plugin.\");\n            }\n\n            // Flot supports base-10 axes; any other mode else is handled by a plug-in,\n            // like flot.time.js.\n\n            if (!axis.tickGenerator) {\n\n                axis.tickGenerator = function (axis) {\n\n                    var ticks = [],\n                        start = floorInBase(axis.min, axis.tickSize),\n                        i = 0,\n                        v = Number.NaN,\n                        prev;\n\n                    do {\n                        prev = v;\n                        v = start + i * axis.tickSize;\n                        ticks.push(v);\n                        ++i;\n                    } while (v < axis.max && v != prev);\n                    return ticks;\n                };\n\n\t\t\t\taxis.tickFormatter = function (value, axis) {\n\n\t\t\t\t\tvar factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1;\n\t\t\t\t\tvar formatted = \"\" + Math.round(value * factor) / factor;\n\n\t\t\t\t\t// If tickDecimals was specified, ensure that we have exactly that\n\t\t\t\t\t// much precision; otherwise default to the value's own precision.\n\n\t\t\t\t\tif (axis.tickDecimals != null) {\n\t\t\t\t\t\tvar decimal = formatted.indexOf(\".\");\n\t\t\t\t\t\tvar precision = decimal == -1 ? 0 : formatted.length - decimal - 1;\n\t\t\t\t\t\tif (precision < axis.tickDecimals) {\n\t\t\t\t\t\t\treturn (precision ? formatted : formatted + \".\") + (\"\" + factor).substr(1, axis.tickDecimals - precision);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n                    return formatted;\n                };\n            }\n\n            if ($.isFunction(opts.tickFormatter))\n                axis.tickFormatter = function (v, axis) { return \"\" + opts.tickFormatter(v, axis); };\n\n            if (opts.alignTicksWithAxis != null) {\n                var otherAxis = (axis.direction == \"x\" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1];\n                if (otherAxis && otherAxis.used && otherAxis != axis) {\n                    // consider snapping min/max to outermost nice ticks\n                    var niceTicks = axis.tickGenerator(axis);\n                    if (niceTicks.length > 0) {\n                        if (opts.min == null)\n                            axis.min = Math.min(axis.min, niceTicks[0]);\n                        if (opts.max == null && niceTicks.length > 1)\n                            axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]);\n                    }\n\n                    axis.tickGenerator = function (axis) {\n                        // copy ticks, scaled to this axis\n                        var ticks = [], v, i;\n                        for (i = 0; i < otherAxis.ticks.length; ++i) {\n                            v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);\n                            v = axis.min + v * (axis.max - axis.min);\n                            ticks.push(v);\n                        }\n                        return ticks;\n                    };\n\n                    // we might need an extra decimal since forced\n                    // ticks don't necessarily fit naturally\n                    if (!axis.mode && opts.tickDecimals == null) {\n                        var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1),\n                            ts = axis.tickGenerator(axis);\n\n                        // only proceed if the tick interval rounded\n                        // with an extra decimal doesn't give us a\n                        // zero at end\n                        if (!(ts.length > 1 && /\\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))\n                            axis.tickDecimals = extraDec;\n                    }\n                }\n            }\n        }\n\n        function setTicks(axis) {\n            var oticks = axis.options.ticks, ticks = [];\n            if (oticks == null || (typeof oticks == \"number\" && oticks > 0))\n                ticks = axis.tickGenerator(axis);\n            else if (oticks) {\n                if ($.isFunction(oticks))\n                    // generate the ticks\n                    ticks = oticks(axis);\n                else\n                    ticks = oticks;\n            }\n\n            // clean up/labelify the supplied ticks, copy them over\n            var i, v;\n            axis.ticks = [];\n            for (i = 0; i < ticks.length; ++i) {\n                var label = null;\n                var t = ticks[i];\n                if (typeof t == \"object\") {\n                    v = +t[0];\n                    if (t.length > 1)\n                        label = t[1];\n                }\n                else\n                    v = +t;\n                if (label == null)\n                    label = axis.tickFormatter(v, axis);\n                if (!isNaN(v))\n                    axis.ticks.push({ v: v, label: label });\n            }\n        }\n\n        function snapRangeToTicks(axis, ticks) {\n            if (axis.options.autoscaleMargin && ticks.length > 0) {\n                // snap to ticks\n                if (axis.options.min == null)\n                    axis.min = Math.min(axis.min, ticks[0].v);\n                if (axis.options.max == null && ticks.length > 1)\n                    axis.max = Math.max(axis.max, ticks[ticks.length - 1].v);\n            }\n        }\n\n        function draw() {\n\n            surface.clear();\n\n            executeHooks(hooks.drawBackground, [ctx]);\n\n            var grid = options.grid;\n\n            // draw background, if any\n            if (grid.show && grid.backgroundColor)\n                drawBackground();\n\n            if (grid.show && !grid.aboveData) {\n                drawGrid();\n            }\n\n            for (var i = 0; i < series.length; ++i) {\n                executeHooks(hooks.drawSeries, [ctx, series[i]]);\n                drawSeries(series[i]);\n            }\n\n            executeHooks(hooks.draw, [ctx]);\n\n            if (grid.show && grid.aboveData) {\n                drawGrid();\n            }\n\n            surface.render();\n\n            // A draw implies that either the axes or data have changed, so we\n            // should probably update the overlay highlights as well.\n\n            triggerRedrawOverlay();\n        }\n\n        function extractRange(ranges, coord) {\n            var axis, from, to, key, axes = allAxes();\n\n            for (var i = 0; i < axes.length; ++i) {\n                axis = axes[i];\n                if (axis.direction == coord) {\n                    key = coord + axis.n + \"axis\";\n                    if (!ranges[key] && axis.n == 1)\n                        key = coord + \"axis\"; // support x1axis as xaxis\n                    if (ranges[key]) {\n                        from = ranges[key].from;\n                        to = ranges[key].to;\n                        break;\n                    }\n                }\n            }\n\n            // backwards-compat stuff - to be removed in future\n            if (!ranges[key]) {\n                axis = coord == \"x\" ? xaxes[0] : yaxes[0];\n                from = ranges[coord + \"1\"];\n                to = ranges[coord + \"2\"];\n            }\n\n            // auto-reverse as an added bonus\n            if (from != null && to != null && from > to) {\n                var tmp = from;\n                from = to;\n                to = tmp;\n            }\n\n            return { from: from, to: to, axis: axis };\n        }\n\n        function drawBackground() {\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, \"rgba(255, 255, 255, 0)\");\n            ctx.fillRect(0, 0, plotWidth, plotHeight);\n            ctx.restore();\n        }\n\n        function drawGrid() {\n            var i, axes, bw, bc;\n\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            // draw markings\n            var markings = options.grid.markings;\n            if (markings) {\n                if ($.isFunction(markings)) {\n                    axes = plot.getAxes();\n                    // xmin etc. is backwards compatibility, to be\n                    // removed in the future\n                    axes.xmin = axes.xaxis.min;\n                    axes.xmax = axes.xaxis.max;\n                    axes.ymin = axes.yaxis.min;\n                    axes.ymax = axes.yaxis.max;\n\n                    markings = markings(axes);\n                }\n\n                for (i = 0; i < markings.length; ++i) {\n                    var m = markings[i],\n                        xrange = extractRange(m, \"x\"),\n                        yrange = extractRange(m, \"y\");\n\n                    // fill in missing\n                    if (xrange.from == null)\n                        xrange.from = xrange.axis.min;\n                    if (xrange.to == null)\n                        xrange.to = xrange.axis.max;\n                    if (yrange.from == null)\n                        yrange.from = yrange.axis.min;\n                    if (yrange.to == null)\n                        yrange.to = yrange.axis.max;\n\n                    // clip\n                    if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||\n                        yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)\n                        continue;\n\n                    xrange.from = Math.max(xrange.from, xrange.axis.min);\n                    xrange.to = Math.min(xrange.to, xrange.axis.max);\n                    yrange.from = Math.max(yrange.from, yrange.axis.min);\n                    yrange.to = Math.min(yrange.to, yrange.axis.max);\n\n                    if (xrange.from == xrange.to && yrange.from == yrange.to)\n                        continue;\n\n                    // then draw\n                    xrange.from = xrange.axis.p2c(xrange.from);\n                    xrange.to = xrange.axis.p2c(xrange.to);\n                    yrange.from = yrange.axis.p2c(yrange.from);\n                    yrange.to = yrange.axis.p2c(yrange.to);\n\n                    if (xrange.from == xrange.to || yrange.from == yrange.to) {\n                        // draw line\n                        ctx.beginPath();\n                        ctx.strokeStyle = m.color || options.grid.markingsColor;\n                        ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth;\n                        ctx.moveTo(xrange.from, yrange.from);\n                        ctx.lineTo(xrange.to, yrange.to);\n                        ctx.stroke();\n                    }\n                    else {\n                        // fill area\n                        ctx.fillStyle = m.color || options.grid.markingsColor;\n                        ctx.fillRect(xrange.from, yrange.to,\n                                     xrange.to - xrange.from,\n                                     yrange.from - yrange.to);\n                    }\n                }\n            }\n\n            // draw the ticks\n            axes = allAxes();\n            bw = options.grid.borderWidth;\n\n            for (var j = 0; j < axes.length; ++j) {\n                var axis = axes[j], box = axis.box,\n                    t = axis.tickLength, x, y, xoff, yoff;\n                if (!axis.show || axis.ticks.length == 0)\n                    continue;\n\n                ctx.lineWidth = 1;\n\n                // find the edges\n                if (axis.direction == \"x\") {\n                    x = 0;\n                    if (t == \"full\")\n                        y = (axis.position == \"top\" ? 0 : plotHeight);\n                    else\n                        y = box.top - plotOffset.top + (axis.position == \"top\" ? box.height : 0);\n                }\n                else {\n                    y = 0;\n                    if (t == \"full\")\n                        x = (axis.position == \"left\" ? 0 : plotWidth);\n                    else\n                        x = box.left - plotOffset.left + (axis.position == \"left\" ? box.width : 0);\n                }\n\n                // draw tick bar\n                if (!axis.innermost) {\n                    ctx.strokeStyle = axis.options.color;\n                    ctx.beginPath();\n                    xoff = yoff = 0;\n                    if (axis.direction == \"x\")\n                        xoff = plotWidth + 1;\n                    else\n                        yoff = plotHeight + 1;\n\n                    if (ctx.lineWidth == 1) {\n                        if (axis.direction == \"x\") {\n                            y = Math.floor(y) + 0.5;\n                        } else {\n                            x = Math.floor(x) + 0.5;\n                        }\n                    }\n\n                    ctx.moveTo(x, y);\n                    ctx.lineTo(x + xoff, y + yoff);\n                    ctx.stroke();\n                }\n\n                // draw ticks\n\n                ctx.strokeStyle = axis.options.tickColor;\n\n                ctx.beginPath();\n                for (i = 0; i < axis.ticks.length; ++i) {\n                    var v = axis.ticks[i].v;\n\n                    xoff = yoff = 0;\n\n                    if (isNaN(v) || v < axis.min || v > axis.max\n                        // skip those lying on the axes if we got a border\n                        || (t == \"full\"\n                            && ((typeof bw == \"object\" && bw[axis.position] > 0) || bw > 0)\n                            && (v == axis.min || v == axis.max)))\n                        continue;\n\n                    if (axis.direction == \"x\") {\n                        x = axis.p2c(v);\n                        yoff = t == \"full\" ? -plotHeight : t;\n\n                        if (axis.position == \"top\")\n                            yoff = -yoff;\n                    }\n                    else {\n                        y = axis.p2c(v);\n                        xoff = t == \"full\" ? -plotWidth : t;\n\n                        if (axis.position == \"left\")\n                            xoff = -xoff;\n                    }\n\n                    if (ctx.lineWidth == 1) {\n                        if (axis.direction == \"x\")\n                            x = Math.floor(x) + 0.5;\n                        else\n                            y = Math.floor(y) + 0.5;\n                    }\n\n                    ctx.moveTo(x, y);\n                    ctx.lineTo(x + xoff, y + yoff);\n                }\n\n                ctx.stroke();\n            }\n\n\n            // draw border\n            if (bw) {\n                // If either borderWidth or borderColor is an object, then draw the border\n                // line by line instead of as one rectangle\n                bc = options.grid.borderColor;\n                if(typeof bw == \"object\" || typeof bc == \"object\") {\n                    if (typeof bw !== \"object\") {\n                        bw = {top: bw, right: bw, bottom: bw, left: bw};\n                    }\n                    if (typeof bc !== \"object\") {\n                        bc = {top: bc, right: bc, bottom: bc, left: bc};\n                    }\n\n                    if (bw.top > 0) {\n                        ctx.strokeStyle = bc.top;\n                        ctx.lineWidth = bw.top;\n                        ctx.beginPath();\n                        ctx.moveTo(0 - bw.left, 0 - bw.top/2);\n                        ctx.lineTo(plotWidth, 0 - bw.top/2);\n                        ctx.stroke();\n                    }\n\n                    if (bw.right > 0) {\n                        ctx.strokeStyle = bc.right;\n                        ctx.lineWidth = bw.right;\n                        ctx.beginPath();\n                        ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top);\n                        ctx.lineTo(plotWidth + bw.right / 2, plotHeight);\n                        ctx.stroke();\n                    }\n\n                    if (bw.bottom > 0) {\n                        ctx.strokeStyle = bc.bottom;\n                        ctx.lineWidth = bw.bottom;\n                        ctx.beginPath();\n                        ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2);\n                        ctx.lineTo(0, plotHeight + bw.bottom / 2);\n                        ctx.stroke();\n                    }\n\n                    if (bw.left > 0) {\n                        ctx.strokeStyle = bc.left;\n                        ctx.lineWidth = bw.left;\n                        ctx.beginPath();\n                        ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom);\n                        ctx.lineTo(0- bw.left/2, 0);\n                        ctx.stroke();\n                    }\n                }\n                else {\n                    ctx.lineWidth = bw;\n                    ctx.strokeStyle = options.grid.borderColor;\n                    ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);\n                }\n            }\n\n            ctx.restore();\n        }\n\n        function drawAxisLabels() {\n\n            $.each(allAxes(), function (_, axis) {\n                if (!axis.show || axis.ticks.length == 0)\n                    return;\n\n                var box = axis.box,\n                    legacyStyles = axis.direction + \"Axis \" + axis.direction + axis.n + \"Axis\",\n                    layer = \"flot-\" + axis.direction + \"-axis flot-\" + axis.direction + axis.n + \"-axis \" + legacyStyles,\n                    font = axis.options.font || \"flot-tick-label tickLabel\",\n                    tick, x, y, halign, valign;\n\n                surface.removeText(layer);\n\n                for (var i = 0; i < axis.ticks.length; ++i) {\n\n                    tick = axis.ticks[i];\n                    if (!tick.label || tick.v < axis.min || tick.v > axis.max)\n                        continue;\n\n                    if (axis.direction == \"x\") {\n                        halign = \"center\";\n                        x = plotOffset.left + axis.p2c(tick.v);\n                        if (axis.position == \"bottom\") {\n                            y = box.top + box.padding;\n                        } else {\n                            y = box.top + box.height - box.padding;\n                            valign = \"bottom\";\n                        }\n                    } else {\n                        valign = \"middle\";\n                        y = plotOffset.top + axis.p2c(tick.v);\n                        if (axis.position == \"left\") {\n                            x = box.left + box.width - box.padding;\n                            halign = \"right\";\n                        } else {\n                            x = box.left + box.padding;\n                        }\n                    }\n\n                    surface.addText(layer, x, y, tick.label, font, null, null, halign, valign);\n                }\n            });\n        }\n\n        function drawSeries(series) {\n            if (series.lines.show)\n                drawSeriesLines(series);\n            if (series.bars.show)\n                drawSeriesBars(series);\n            if (series.points.show)\n                drawSeriesPoints(series);\n        }\n\n        function drawSeriesLines(series) {\n            function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {\n                var points = datapoints.points,\n                    ps = datapoints.pointsize,\n                    prevx = null, prevy = null;\n\n                ctx.beginPath();\n                for (var i = ps; i < points.length; i += ps) {\n                    var x1 = points[i - ps], y1 = points[i - ps + 1],\n                        x2 = points[i], y2 = points[i + 1];\n\n                    if (x1 == null || x2 == null)\n                        continue;\n\n                    // clip with ymin\n                    if (y1 <= y2 && y1 < axisy.min) {\n                        if (y2 < axisy.min)\n                            continue;   // line segment is outside\n                        // compute new intersection point\n                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y1 = axisy.min;\n                    }\n                    else if (y2 <= y1 && y2 < axisy.min) {\n                        if (y1 < axisy.min)\n                            continue;\n                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y2 = axisy.min;\n                    }\n\n                    // clip with ymax\n                    if (y1 >= y2 && y1 > axisy.max) {\n                        if (y2 > axisy.max)\n                            continue;\n                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y1 = axisy.max;\n                    }\n                    else if (y2 >= y1 && y2 > axisy.max) {\n                        if (y1 > axisy.max)\n                            continue;\n                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y2 = axisy.max;\n                    }\n\n                    // clip with xmin\n                    if (x1 <= x2 && x1 < axisx.min) {\n                        if (x2 < axisx.min)\n                            continue;\n                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x1 = axisx.min;\n                    }\n                    else if (x2 <= x1 && x2 < axisx.min) {\n                        if (x1 < axisx.min)\n                            continue;\n                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x2 = axisx.min;\n                    }\n\n                    // clip with xmax\n                    if (x1 >= x2 && x1 > axisx.max) {\n                        if (x2 > axisx.max)\n                            continue;\n                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x1 = axisx.max;\n                    }\n                    else if (x2 >= x1 && x2 > axisx.max) {\n                        if (x1 > axisx.max)\n                            continue;\n                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x2 = axisx.max;\n                    }\n\n                    if (x1 != prevx || y1 != prevy)\n                        ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);\n\n                    prevx = x2;\n                    prevy = y2;\n                    ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);\n                }\n                ctx.stroke();\n            }\n\n            function plotLineArea(datapoints, axisx, axisy) {\n                var points = datapoints.points,\n                    ps = datapoints.pointsize,\n                    bottom = Math.min(Math.max(0, axisy.min), axisy.max),\n                    i = 0, top, areaOpen = false,\n                    ypos = 1, segmentStart = 0, segmentEnd = 0;\n\n                // we process each segment in two turns, first forward\n                // direction to sketch out top, then once we hit the\n                // end we go backwards to sketch the bottom\n                while (true) {\n                    if (ps > 0 && i > points.length + ps)\n                        break;\n\n                    i += ps; // ps is negative if going backwards\n\n                    var x1 = points[i - ps],\n                        y1 = points[i - ps + ypos],\n                        x2 = points[i], y2 = points[i + ypos];\n\n                    if (areaOpen) {\n                        if (ps > 0 && x1 != null && x2 == null) {\n                            // at turning point\n                            segmentEnd = i;\n                            ps = -ps;\n                            ypos = 2;\n                            continue;\n                        }\n\n                        if (ps < 0 && i == segmentStart + ps) {\n                            // done with the reverse sweep\n                            ctx.fill();\n                            areaOpen = false;\n                            ps = -ps;\n                            ypos = 1;\n                            i = segmentStart = segmentEnd + ps;\n                            continue;\n                        }\n                    }\n\n                    if (x1 == null || x2 == null)\n                        continue;\n\n                    // clip x values\n\n                    // clip with xmin\n                    if (x1 <= x2 && x1 < axisx.min) {\n                        if (x2 < axisx.min)\n                            continue;\n                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x1 = axisx.min;\n                    }\n                    else if (x2 <= x1 && x2 < axisx.min) {\n                        if (x1 < axisx.min)\n                            continue;\n                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x2 = axisx.min;\n                    }\n\n                    // clip with xmax\n                    if (x1 >= x2 && x1 > axisx.max) {\n                        if (x2 > axisx.max)\n                            continue;\n                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x1 = axisx.max;\n                    }\n                    else if (x2 >= x1 && x2 > axisx.max) {\n                        if (x1 > axisx.max)\n                            continue;\n                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x2 = axisx.max;\n                    }\n\n                    if (!areaOpen) {\n                        // open area\n                        ctx.beginPath();\n                        ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));\n                        areaOpen = true;\n                    }\n\n                    // now first check the case where both is outside\n                    if (y1 >= axisy.max && y2 >= axisy.max) {\n                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));\n                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));\n                        continue;\n                    }\n                    else if (y1 <= axisy.min && y2 <= axisy.min) {\n                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));\n                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));\n                        continue;\n                    }\n\n                    // else it's a bit more complicated, there might\n                    // be a flat maxed out rectangle first, then a\n                    // triangular cutout or reverse; to find these\n                    // keep track of the current x values\n                    var x1old = x1, x2old = x2;\n\n                    // clip the y values, without shortcutting, we\n                    // go through all cases in turn\n\n                    // clip with ymin\n                    if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {\n                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y1 = axisy.min;\n                    }\n                    else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {\n                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y2 = axisy.min;\n                    }\n\n                    // clip with ymax\n                    if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {\n                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y1 = axisy.max;\n                    }\n                    else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {\n                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y2 = axisy.max;\n                    }\n\n                    // if the x value was changed we got a rectangle\n                    // to fill\n                    if (x1 != x1old) {\n                        ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));\n                        // it goes to (x1, y1), but we fill that below\n                    }\n\n                    // fill triangular section, this sometimes result\n                    // in redundant points if (x1, y1) hasn't changed\n                    // from previous line to, but we just ignore that\n                    ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));\n                    ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));\n\n                    // fill the other rectangle if it's there\n                    if (x2 != x2old) {\n                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));\n                        ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));\n                    }\n                }\n            }\n\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n            ctx.lineJoin = \"round\";\n\n            var lw = series.lines.lineWidth,\n                sw = series.shadowSize;\n            // FIXME: consider another form of shadow when filling is turned on\n            if (lw > 0 && sw > 0) {\n                // draw shadow as a thick and thin line with transparency\n                ctx.lineWidth = sw;\n                ctx.strokeStyle = \"rgba(0,0,0,0.1)\";\n                // position shadow at angle from the mid of line\n                var angle = Math.PI/18;\n                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);\n                ctx.lineWidth = sw/2;\n                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);\n            }\n\n            ctx.lineWidth = lw;\n            ctx.strokeStyle = series.color;\n            var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);\n            if (fillStyle) {\n                ctx.fillStyle = fillStyle;\n                plotLineArea(series.datapoints, series.xaxis, series.yaxis);\n            }\n\n            if (lw > 0)\n                plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);\n            ctx.restore();\n        }\n\n        function drawSeriesPoints(series) {\n            function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {\n                var points = datapoints.points, ps = datapoints.pointsize;\n\n                for (var i = 0; i < points.length; i += ps) {\n                    var x = points[i], y = points[i + 1];\n                    if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)\n                        continue;\n\n                    ctx.beginPath();\n                    x = axisx.p2c(x);\n                    y = axisy.p2c(y) + offset;\n                    if (symbol == \"circle\")\n                        ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);\n                    else\n                        symbol(ctx, x, y, radius, shadow);\n                    ctx.closePath();\n\n                    if (fillStyle) {\n                        ctx.fillStyle = fillStyle;\n                        ctx.fill();\n                    }\n                    ctx.stroke();\n                }\n            }\n\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            var lw = series.points.lineWidth,\n                sw = series.shadowSize,\n                radius = series.points.radius,\n                symbol = series.points.symbol;\n\n            // If the user sets the line width to 0, we change it to a very \n            // small value. A line width of 0 seems to force the default of 1.\n            // Doing the conditional here allows the shadow setting to still be \n            // optional even with a lineWidth of 0.\n\n            if( lw == 0 )\n                lw = 0.0001;\n\n            if (lw > 0 && sw > 0) {\n                // draw shadow in two steps\n                var w = sw / 2;\n                ctx.lineWidth = w;\n                ctx.strokeStyle = \"rgba(0,0,0,0.1)\";\n                plotPoints(series.datapoints, radius, null, w + w/2, true,\n                           series.xaxis, series.yaxis, symbol);\n\n                ctx.strokeStyle = \"rgba(0,0,0,0.2)\";\n                plotPoints(series.datapoints, radius, null, w/2, true,\n                           series.xaxis, series.yaxis, symbol);\n            }\n\n            ctx.lineWidth = lw;\n            ctx.strokeStyle = series.color;\n            plotPoints(series.datapoints, radius,\n                       getFillStyle(series.points, series.color), 0, false,\n                       series.xaxis, series.yaxis, symbol);\n            ctx.restore();\n        }\n\n        function drawBar(x, y, b, barLeft, barRight, offset, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {\n            var left, right, bottom, top,\n                drawLeft, drawRight, drawTop, drawBottom,\n                tmp;\n\n            // in horizontal mode, we start the bar from the left\n            // instead of from the bottom so it appears to be\n            // horizontal rather than vertical\n            if (horizontal) {\n                drawBottom = drawRight = drawTop = true;\n                drawLeft = false;\n                left = b;\n                right = x;\n                top = y + barLeft;\n                bottom = y + barRight;\n\n                // account for negative bars\n                if (right < left) {\n                    tmp = right;\n                    right = left;\n                    left = tmp;\n                    drawLeft = true;\n                    drawRight = false;\n                }\n            }\n            else {\n                drawLeft = drawRight = drawTop = true;\n                drawBottom = false;\n                left = x + barLeft;\n                right = x + barRight;\n                bottom = b;\n                top = y;\n\n                // account for negative bars\n                if (top < bottom) {\n                    tmp = top;\n                    top = bottom;\n                    bottom = tmp;\n                    drawBottom = true;\n                    drawTop = false;\n                }\n            }\n\n            // clip\n            if (right < axisx.min || left > axisx.max ||\n                top < axisy.min || bottom > axisy.max)\n                return;\n\n            if (left < axisx.min) {\n                left = axisx.min;\n                drawLeft = false;\n            }\n\n            if (right > axisx.max) {\n                right = axisx.max;\n                drawRight = false;\n            }\n\n            if (bottom < axisy.min) {\n                bottom = axisy.min;\n                drawBottom = false;\n            }\n\n            if (top > axisy.max) {\n                top = axisy.max;\n                drawTop = false;\n            }\n\n            left = axisx.p2c(left);\n            bottom = axisy.p2c(bottom);\n            right = axisx.p2c(right);\n            top = axisy.p2c(top);\n\n            // fill the bar\n            if (fillStyleCallback) {\n                c.beginPath();\n                c.moveTo(left, bottom);\n                c.lineTo(left, top);\n                c.lineTo(right, top);\n                c.lineTo(right, bottom);\n                c.fillStyle = fillStyleCallback(bottom, top);\n                c.fill();\n            }\n\n            // draw outline\n            if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {\n                c.beginPath();\n\n                // FIXME: inline moveTo is buggy with excanvas\n                c.moveTo(left, bottom + offset);\n                if (drawLeft)\n                    c.lineTo(left, top + offset);\n                else\n                    c.moveTo(left, top + offset);\n                if (drawTop)\n                    c.lineTo(right, top + offset);\n                else\n                    c.moveTo(right, top + offset);\n                if (drawRight)\n                    c.lineTo(right, bottom + offset);\n                else\n                    c.moveTo(right, bottom + offset);\n                if (drawBottom)\n                    c.lineTo(left, bottom + offset);\n                else\n                    c.moveTo(left, bottom + offset);\n                c.stroke();\n            }\n        }\n\n        function drawSeriesBars(series) {\n            function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) {\n                var points = datapoints.points, ps = datapoints.pointsize;\n\n                for (var i = 0; i < points.length; i += ps) {\n                    if (points[i] == null)\n                        continue;\n                    drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, offset, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);\n                }\n            }\n\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            // FIXME: figure out a way to add shadows (for instance along the right edge)\n            ctx.lineWidth = series.bars.lineWidth;\n            ctx.strokeStyle = series.color;\n\n            var barLeft;\n\n            switch (series.bars.align) {\n                case \"left\":\n                    barLeft = 0;\n                    break;\n                case \"right\":\n                    barLeft = -series.bars.barWidth;\n                    break;\n                case \"center\":\n                    barLeft = -series.bars.barWidth / 2;\n                    break;\n                default:\n                    throw new Error(\"Invalid bar alignment: \" + series.bars.align);\n            }\n\n            var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;\n            plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, 0, fillStyleCallback, series.xaxis, series.yaxis);\n            ctx.restore();\n        }\n\n        function getFillStyle(filloptions, seriesColor, bottom, top) {\n            var fill = filloptions.fill;\n            if (!fill)\n                return null;\n\n            if (filloptions.fillColor)\n                return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);\n\n            var c = $.color.parse(seriesColor);\n            c.a = typeof fill == \"number\" ? fill : 0.4;\n            c.normalize();\n            return c.toString();\n        }\n\n        function insertLegend() {\n\n            placeholder.find(\".legend\").remove();\n\n            if (!options.legend.show)\n                return;\n\n            var fragments = [], entries = [], rowStarted = false,\n                lf = options.legend.labelFormatter, s, label;\n\n            // Build a list of legend entries, with each having a label and a color\n\n            for (var i = 0; i < series.length; ++i) {\n                s = series[i];\n                if (s.label) {\n                    label = lf ? lf(s.label, s) : s.label;\n                    if (label) {\n                        entries.push({\n                            label: label,\n                            color: s.color\n                        });\n                    }\n                }\n            }\n\n            // Sort the legend using either the default or a custom comparator\n\n            if (options.legend.sorted) {\n                if ($.isFunction(options.legend.sorted)) {\n                    entries.sort(options.legend.sorted);\n                } else if (options.legend.sorted == \"reverse\") {\n                \tentries.reverse();\n                } else {\n                    var ascending = options.legend.sorted != \"descending\";\n                    entries.sort(function(a, b) {\n                        return a.label == b.label ? 0 : (\n                            (a.label < b.label) != ascending ? 1 : -1   // Logical XOR\n                        );\n                    });\n                }\n            }\n\n            // Generate markup for the list of entries, in their final order\n\n            for (var i = 0; i < entries.length; ++i) {\n\n                var entry = entries[i];\n\n                if (i % options.legend.noColumns == 0) {\n                    if (rowStarted)\n                        fragments.push('</tr>');\n                    fragments.push('<tr>');\n                    rowStarted = true;\n                }\n\n                fragments.push(\n                    '<td class=\"legendColorBox\"><div style=\"border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px\"><div style=\"width:4px;height:0;border:5px solid ' + entry.color + ';overflow:hidden\"></div></div></td>' +\n                    '<td class=\"legendLabel\">' + entry.label + '</td>'\n                );\n            }\n\n            if (rowStarted)\n                fragments.push('</tr>');\n\n            if (fragments.length == 0)\n                return;\n\n            var table = '<table style=\"font-size:smaller;color:' + options.grid.color + '\">' + fragments.join(\"\") + '</table>';\n            if (options.legend.container != null)\n                $(options.legend.container).html(table);\n            else {\n                var pos = \"\",\n                    p = options.legend.position,\n                    m = options.legend.margin;\n                if (m[0] == null)\n                    m = [m, m];\n                if (p.charAt(0) == \"n\")\n                    pos += 'top:' + (m[1] + plotOffset.top) + 'px;';\n                else if (p.charAt(0) == \"s\")\n                    pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';\n                if (p.charAt(1) == \"e\")\n                    pos += 'right:' + (m[0] + plotOffset.right) + 'px;';\n                else if (p.charAt(1) == \"w\")\n                    pos += 'left:' + (m[0] + plotOffset.left) + 'px;';\n                var legend = $('<div class=\"legend\">' + table.replace('style=\"', 'style=\"position:absolute;' + pos +';') + '</div>').appendTo(placeholder);\n                if (options.legend.backgroundOpacity != 0.0) {\n                    // put in the transparent background\n                    // separately to avoid blended labels and\n                    // label boxes\n                    var c = options.legend.backgroundColor;\n                    if (c == null) {\n                        c = options.grid.backgroundColor;\n                        if (c && typeof c == \"string\")\n                            c = $.color.parse(c);\n                        else\n                            c = $.color.extract(legend, 'background-color');\n                        c.a = 1;\n                        c = c.toString();\n                    }\n                    var div = legend.children();\n                    $('<div style=\"position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';\"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity);\n                }\n            }\n        }\n\n\n        // interactive features\n\n        var highlights = [],\n            redrawTimeout = null;\n\n        // returns the data item the mouse is over, or null if none is found\n        function findNearbyItem(mouseX, mouseY, seriesFilter) {\n            var maxDistance = options.grid.mouseActiveRadius,\n                smallestDistance = maxDistance * maxDistance + 1,\n                item = null, foundPoint = false, i, j, ps;\n\n            for (i = series.length - 1; i >= 0; --i) {\n                if (!seriesFilter(series[i]))\n                    continue;\n\n                var s = series[i],\n                    axisx = s.xaxis,\n                    axisy = s.yaxis,\n                    points = s.datapoints.points,\n                    mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster\n                    my = axisy.c2p(mouseY),\n                    maxx = maxDistance / axisx.scale,\n                    maxy = maxDistance / axisy.scale;\n\n                ps = s.datapoints.pointsize;\n                // with inverse transforms, we can't use the maxx/maxy\n                // optimization, sadly\n                if (axisx.options.inverseTransform)\n                    maxx = Number.MAX_VALUE;\n                if (axisy.options.inverseTransform)\n                    maxy = Number.MAX_VALUE;\n\n                if (s.lines.show || s.points.show) {\n                    for (j = 0; j < points.length; j += ps) {\n                        var x = points[j], y = points[j + 1];\n                        if (x == null)\n                            continue;\n\n                        // For points and lines, the cursor must be within a\n                        // certain distance to the data point\n                        if (x - mx > maxx || x - mx < -maxx ||\n                            y - my > maxy || y - my < -maxy)\n                            continue;\n\n                        // We have to calculate distances in pixels, not in\n                        // data units, because the scales of the axes may be different\n                        var dx = Math.abs(axisx.p2c(x) - mouseX),\n                            dy = Math.abs(axisy.p2c(y) - mouseY),\n                            dist = dx * dx + dy * dy; // we save the sqrt\n\n                        // use <= to ensure last point takes precedence\n                        // (last generally means on top of)\n                        if (dist < smallestDistance) {\n                            smallestDistance = dist;\n                            item = [i, j / ps];\n                        }\n                    }\n                }\n\n                if (s.bars.show && !item) { // no other point can be nearby\n                    var barLeft = s.bars.align == \"left\" ? 0 : -s.bars.barWidth/2,\n                        barRight = barLeft + s.bars.barWidth;\n\n                    for (j = 0; j < points.length; j += ps) {\n                        var x = points[j], y = points[j + 1], b = points[j + 2];\n                        if (x == null)\n                            continue;\n\n                        // for a bar graph, the cursor must be inside the bar\n                        if (series[i].bars.horizontal ?\n                            (mx <= Math.max(b, x) && mx >= Math.min(b, x) &&\n                             my >= y + barLeft && my <= y + barRight) :\n                            (mx >= x + barLeft && mx <= x + barRight &&\n                             my >= Math.min(b, y) && my <= Math.max(b, y)))\n                                item = [i, j / ps];\n                    }\n                }\n            }\n\n            if (item) {\n                i = item[0];\n                j = item[1];\n                ps = series[i].datapoints.pointsize;\n\n                return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),\n                         dataIndex: j,\n                         series: series[i],\n                         seriesIndex: i };\n            }\n\n            return null;\n        }\n\n        function onMouseMove(e) {\n            if (options.grid.hoverable)\n                triggerClickHoverEvent(\"plothover\", e,\n                                       function (s) { return s[\"hoverable\"] != false; });\n        }\n\n        function onMouseLeave(e) {\n            if (options.grid.hoverable)\n                triggerClickHoverEvent(\"plothover\", e,\n                                       function (s) { return false; });\n        }\n\n        function onClick(e) {\n            triggerClickHoverEvent(\"plotclick\", e,\n                                   function (s) { return s[\"clickable\"] != false; });\n        }\n\n        // trigger click or hover event (they send the same parameters\n        // so we share their code)\n        function triggerClickHoverEvent(eventname, event, seriesFilter) {\n            var offset = eventHolder.offset(),\n                canvasX = event.pageX - offset.left - plotOffset.left,\n                canvasY = event.pageY - offset.top - plotOffset.top,\n            pos = canvasToAxisCoords({ left: canvasX, top: canvasY });\n\n            pos.pageX = event.pageX;\n            pos.pageY = event.pageY;\n\n            var item = findNearbyItem(canvasX, canvasY, seriesFilter);\n\n            if (item) {\n                // fill in mouse pos for any listeners out there\n                item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10);\n                item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10);\n            }\n\n            if (options.grid.autoHighlight) {\n                // clear auto-highlights\n                for (var i = 0; i < highlights.length; ++i) {\n                    var h = highlights[i];\n                    if (h.auto == eventname &&\n                        !(item && h.series == item.series &&\n                          h.point[0] == item.datapoint[0] &&\n                          h.point[1] == item.datapoint[1]))\n                        unhighlight(h.series, h.point);\n                }\n\n                if (item)\n                    highlight(item.series, item.datapoint, eventname);\n            }\n\n            placeholder.trigger(eventname, [ pos, item ]);\n        }\n\n        function triggerRedrawOverlay() {\n            var t = options.interaction.redrawOverlayInterval;\n            if (t == -1) {      // skip event queue\n                drawOverlay();\n                return;\n            }\n\n            if (!redrawTimeout)\n                redrawTimeout = setTimeout(drawOverlay, t);\n        }\n\n        function drawOverlay() {\n            redrawTimeout = null;\n\n            // draw highlights\n            octx.save();\n            overlay.clear();\n            octx.translate(plotOffset.left, plotOffset.top);\n\n            var i, hi;\n            for (i = 0; i < highlights.length; ++i) {\n                hi = highlights[i];\n\n                if (hi.series.bars.show)\n                    drawBarHighlight(hi.series, hi.point);\n                else\n                    drawPointHighlight(hi.series, hi.point);\n            }\n            octx.restore();\n\n            executeHooks(hooks.drawOverlay, [octx]);\n        }\n\n        function highlight(s, point, auto) {\n            if (typeof s == \"number\")\n                s = series[s];\n\n            if (typeof point == \"number\") {\n                var ps = s.datapoints.pointsize;\n                point = s.datapoints.points.slice(ps * point, ps * (point + 1));\n            }\n\n            var i = indexOfHighlight(s, point);\n            if (i == -1) {\n                highlights.push({ series: s, point: point, auto: auto });\n\n                triggerRedrawOverlay();\n            }\n            else if (!auto)\n                highlights[i].auto = false;\n        }\n\n        function unhighlight(s, point) {\n            if (s == null && point == null) {\n                highlights = [];\n                triggerRedrawOverlay();\n                return;\n            }\n\n            if (typeof s == \"number\")\n                s = series[s];\n\n            if (typeof point == \"number\") {\n                var ps = s.datapoints.pointsize;\n                point = s.datapoints.points.slice(ps * point, ps * (point + 1));\n            }\n\n            var i = indexOfHighlight(s, point);\n            if (i != -1) {\n                highlights.splice(i, 1);\n\n                triggerRedrawOverlay();\n            }\n        }\n\n        function indexOfHighlight(s, p) {\n            for (var i = 0; i < highlights.length; ++i) {\n                var h = highlights[i];\n                if (h.series == s && h.point[0] == p[0]\n                    && h.point[1] == p[1])\n                    return i;\n            }\n            return -1;\n        }\n\n        function drawPointHighlight(series, point) {\n            var x = point[0], y = point[1],\n                axisx = series.xaxis, axisy = series.yaxis,\n                highlightColor = (typeof series.highlightColor === \"string\") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString();\n\n            if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)\n                return;\n\n            var pointRadius = series.points.radius + series.points.lineWidth / 2;\n            octx.lineWidth = pointRadius;\n            octx.strokeStyle = highlightColor;\n            var radius = 1.5 * pointRadius;\n            x = axisx.p2c(x);\n            y = axisy.p2c(y);\n\n            octx.beginPath();\n            if (series.points.symbol == \"circle\")\n                octx.arc(x, y, radius, 0, 2 * Math.PI, false);\n            else\n                series.points.symbol(octx, x, y, radius, false);\n            octx.closePath();\n            octx.stroke();\n        }\n\n        function drawBarHighlight(series, point) {\n            var highlightColor = (typeof series.highlightColor === \"string\") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(),\n                fillStyle = highlightColor,\n                barLeft = series.bars.align == \"left\" ? 0 : -series.bars.barWidth/2;\n\n            octx.lineWidth = series.bars.lineWidth;\n            octx.strokeStyle = highlightColor;\n\n            drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,\n                    0, function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);\n        }\n\n        function getColorOrGradient(spec, bottom, top, defaultColor) {\n            if (typeof spec == \"string\")\n                return spec;\n            else {\n                // assume this is a gradient spec; IE currently only\n                // supports a simple vertical gradient properly, so that's\n                // what we support too\n                var gradient = ctx.createLinearGradient(0, top, 0, bottom);\n\n                for (var i = 0, l = spec.colors.length; i < l; ++i) {\n                    var c = spec.colors[i];\n                    if (typeof c != \"string\") {\n                        var co = $.color.parse(defaultColor);\n                        if (c.brightness != null)\n                            co = co.scale('rgb', c.brightness);\n                        if (c.opacity != null)\n                            co.a *= c.opacity;\n                        c = co.toString();\n                    }\n                    gradient.addColorStop(i / (l - 1), c);\n                }\n\n                return gradient;\n            }\n        }\n    }\n\n    // Add the plot function to the top level of the jQuery object\n\n    $.plot = function(placeholder, data, options) {\n        //var t0 = new Date();\n        var plot = new Plot($(placeholder), data, options, $.plot.plugins);\n        //(window.console ? console.log : alert)(\"time used (msecs): \" + ((new Date()).getTime() - t0.getTime()));\n        return plot;\n    };\n\n    $.plot.version = \"0.8.1\";\n\n    $.plot.plugins = [];\n\n    // Also add the plot function as a chainable property\n\n    $.fn.plot = function(data, options) {\n        return this.each(function() {\n            $.plot(this, data, options);\n        });\n    };\n\n    // round to nearby lower multiple of base\n    function floorInBase(n, base) {\n        return base * Math.floor(n / base);\n    }\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/flot-chart/jquery.flot.pie.js",
    "content": "/* Flot plugin for rendering pie charts.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin assumes that each series has a single data value, and that each\nvalue is a positive integer or zero.  Negative numbers don't make sense for a\npie chart, and have unpredictable results.  The values do NOT need to be\npassed in as percentages; the plugin will calculate the total and per-slice\npercentages internally.\n\n* Created by Brian Medendorp\n\n* Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars\n\nThe plugin supports these options:\n\n\tseries: {\n\t\tpie: {\n\t\t\tshow: true/false\n\t\t\tradius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'\n\t\t\tinnerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect\n\t\t\tstartAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result\n\t\t\ttilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)\n\t\t\toffset: {\n\t\t\t\ttop: integer value to move the pie up or down\n\t\t\t\tleft: integer value to move the pie left or right, or 'auto'\n\t\t\t},\n\t\t\tstroke: {\n\t\t\t\tcolor: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')\n\t\t\t\twidth: integer pixel width of the stroke\n\t\t\t},\n\t\t\tlabel: {\n\t\t\t\tshow: true/false, or 'auto'\n\t\t\t\tformatter:  a user-defined function that modifies the text/style of the label text\n\t\t\t\tradius: 0-1 for percentage of fullsize, or a specified pixel length\n\t\t\t\tbackground: {\n\t\t\t\t\tcolor: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')\n\t\t\t\t\topacity: 0-1\n\t\t\t\t},\n\t\t\t\tthreshold: 0-1 for the percentage value at which to hide labels (if they're too small)\n\t\t\t},\n\t\t\tcombine: {\n\t\t\t\tthreshold: 0-1 for the percentage value at which to combine slices (if they're too small)\n\t\t\t\tcolor: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined\n\t\t\t\tlabel: any text value of what the combined slice should be labeled\n\t\t\t}\n\t\t\thighlight: {\n\t\t\t\topacity: 0-1\n\t\t\t}\n\t\t}\n\t}\n\nMore detail and specific examples can be found in the included HTML file.\n\n*/\n\n(function($) {\n\n\t// Maximum redraw attempts when fitting labels within the plot\n\n\tvar REDRAW_ATTEMPTS = 10;\n\n\t// Factor by which to shrink the pie when fitting labels within the plot\n\n\tvar REDRAW_SHRINK = 0.95;\n\n\tfunction init(plot) {\n\n\t\tvar canvas = null,\n\t\t\ttarget = null,\n\t\t\toptions = null,\n\t\t\tmaxRadius = null,\n\t\t\tcenterLeft = null,\n\t\t\tcenterTop = null,\n\t\t\tprocessed = false,\n\t\t\tctx = null;\n\n\t\t// interactive variables\n\n\t\tvar highlights = [];\n\n\t\t// add hook to determine if pie plugin in enabled, and then perform necessary operations\n\n\t\tplot.hooks.processOptions.push(function(plot, options) {\n\t\t\tif (options.series.pie.show) {\n\n\t\t\t\toptions.grid.show = false;\n\n\t\t\t\t// set labels.show\n\n\t\t\t\tif (options.series.pie.label.show == \"auto\") {\n\t\t\t\t\tif (options.legend.show) {\n\t\t\t\t\t\toptions.series.pie.label.show = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toptions.series.pie.label.show = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// set radius\n\n\t\t\t\tif (options.series.pie.radius == \"auto\") {\n\t\t\t\t\tif (options.series.pie.label.show) {\n\t\t\t\t\t\toptions.series.pie.radius = 3/4;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toptions.series.pie.radius = 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// ensure sane tilt\n\n\t\t\t\tif (options.series.pie.tilt > 1) {\n\t\t\t\t\toptions.series.pie.tilt = 1;\n\t\t\t\t} else if (options.series.pie.tilt < 0) {\n\t\t\t\t\toptions.series.pie.tilt = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.bindEvents.push(function(plot, eventHolder) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tif (options.grid.hoverable) {\n\t\t\t\t\teventHolder.unbind(\"mousemove\").mousemove(onMouseMove);\n\t\t\t\t}\n\t\t\t\tif (options.grid.clickable) {\n\t\t\t\t\teventHolder.unbind(\"click\").click(onClick);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.processDatapoints.push(function(plot, series, data, datapoints) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tprocessDatapoints(plot, series, data, datapoints);\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.drawOverlay.push(function(plot, octx) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tdrawOverlay(plot, octx);\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.draw.push(function(plot, newCtx) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tdraw(plot, newCtx);\n\t\t\t}\n\t\t});\n\n\t\tfunction processDatapoints(plot, series, datapoints) {\n\t\t\tif (!processed)\t{\n\t\t\t\tprocessed = true;\n\t\t\t\tcanvas = plot.getCanvas();\n\t\t\t\ttarget = $(canvas).parent();\n\t\t\t\toptions = plot.getOptions();\n\t\t\t\tplot.setData(combine(plot.getData()));\n\t\t\t}\n\t\t}\n\n\t\tfunction combine(data) {\n\n\t\t\tvar total = 0,\n\t\t\t\tcombined = 0,\n\t\t\t\tnumCombined = 0,\n\t\t\t\tcolor = options.series.pie.combine.color,\n\t\t\t\tnewdata = [];\n\n\t\t\t// Fix up the raw data from Flot, ensuring the data is numeric\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\n\t\t\t\tvar value = data[i].data;\n\n\t\t\t\t// If the data is an array, we'll assume that it's a standard\n\t\t\t\t// Flot x-y pair, and are concerned only with the second value.\n\n\t\t\t\t// Note how we use the original array, rather than creating a\n\t\t\t\t// new one; this is more efficient and preserves any extra data\n\t\t\t\t// that the user may have stored in higher indexes.\n\n\t\t\t\tif ($.isArray(value) && value.length == 1) {\n    \t\t\t\tvalue = value[0];\n\t\t\t\t}\n\n\t\t\t\tif ($.isArray(value)) {\n\t\t\t\t\t// Equivalent to $.isNumeric() but compatible with jQuery < 1.7\n\t\t\t\t\tif (!isNaN(parseFloat(value[1])) && isFinite(value[1])) {\n\t\t\t\t\t\tvalue[1] = +value[1];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalue[1] = 0;\n\t\t\t\t\t}\n\t\t\t\t} else if (!isNaN(parseFloat(value)) && isFinite(value)) {\n\t\t\t\t\tvalue = [1, +value];\n\t\t\t\t} else {\n\t\t\t\t\tvalue = [1, 0];\n\t\t\t\t}\n\n\t\t\t\tdata[i].data = [value];\n\t\t\t}\n\n\t\t\t// Sum up all the slices, so we can calculate percentages for each\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\t\t\t\ttotal += data[i].data[0][1];\n\t\t\t}\n\n\t\t\t// Count the number of slices with percentages below the combine\n\t\t\t// threshold; if it turns out to be just one, we won't combine.\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\t\t\t\tvar value = data[i].data[0][1];\n\t\t\t\tif (value / total <= options.series.pie.combine.threshold) {\n\t\t\t\t\tcombined += value;\n\t\t\t\t\tnumCombined++;\n\t\t\t\t\tif (!color) {\n\t\t\t\t\t\tcolor = data[i].color;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\t\t\t\tvar value = data[i].data[0][1];\n\t\t\t\tif (numCombined < 2 || value / total > options.series.pie.combine.threshold) {\n\t\t\t\t\tnewdata.push(\n\t\t\t\t\t\t$.extend(data[i], {     /* extend to allow keeping all other original data values\n\t\t\t\t\t\t                           and using them e.g. in labelFormatter. */\n\t\t\t\t\t\t\tdata: [[1, value]],\n\t\t\t\t\t\t\tcolor: data[i].color,\n\t\t\t\t\t\t\tlabel: data[i].label,\n\t\t\t\t\t\t\tangle: value * Math.PI * 2 / total,\n\t\t\t\t\t\t\tpercent: value / (total / 100)\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\tif (numCombined > 1) {\n\t\t\t\tnewdata.push({\n\t\t\t\t\tdata: [[1, combined]],\n\t\t\t\t\tcolor: color,\n\t\t\t\t\tlabel: options.series.pie.combine.label,\n\t\t\t\t\tangle: combined * Math.PI * 2 / total,\n\t\t\t\t\tpercent: combined / (total / 100)\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn newdata;\n\t\t}\n\n\t\tfunction draw(plot, newCtx) {\n\n\t\t\tif (!target) {\n\t\t\t\treturn; // if no series were passed\n\t\t\t}\n\n\t\t\tvar canvasWidth = plot.getPlaceholder().width(),\n\t\t\t\tcanvasHeight = plot.getPlaceholder().height(),\n\t\t\t\tlegendWidth = target.children().filter(\".legend\").children().width() || 0;\n\n\t\t\tctx = newCtx;\n\n\t\t\t// WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE!\n\n\t\t\t// When combining smaller slices into an 'other' slice, we need to\n\t\t\t// add a new series.  Since Flot gives plugins no way to modify the\n\t\t\t// list of series, the pie plugin uses a hack where the first call\n\t\t\t// to processDatapoints results in a call to setData with the new\n\t\t\t// list of series, then subsequent processDatapoints do nothing.\n\n\t\t\t// The plugin-global 'processed' flag is used to control this hack;\n\t\t\t// it starts out false, and is set to true after the first call to\n\t\t\t// processDatapoints.\n\n\t\t\t// Unfortunately this turns future setData calls into no-ops; they\n\t\t\t// call processDatapoints, the flag is true, and nothing happens.\n\n\t\t\t// To fix this we'll set the flag back to false here in draw, when\n\t\t\t// all series have been processed, so the next sequence of calls to\n\t\t\t// processDatapoints once again starts out with a slice-combine.\n\t\t\t// This is really a hack; in 0.9 we need to give plugins a proper\n\t\t\t// way to modify series before any processing begins.\n\n\t\t\tprocessed = false;\n\n\t\t\t// calculate maximum radius and center point\n\n\t\t\tmaxRadius =  Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2;\n\t\t\tcenterTop = canvasHeight / 2 + options.series.pie.offset.top;\n\t\t\tcenterLeft = canvasWidth / 2;\n\n\t\t\tif (options.series.pie.offset.left == \"auto\") {\n\t\t\t\tif (options.legend.position.match(\"w\")) {\n\t\t\t\t\tcenterLeft += legendWidth / 2;\n\t\t\t\t} else {\n\t\t\t\t\tcenterLeft -= legendWidth / 2;\n\t\t\t\t}\n\t\t\t\tif (centerLeft < maxRadius) {\n\t\t\t\t\tcenterLeft = maxRadius;\n\t\t\t\t} else if (centerLeft > canvasWidth - maxRadius) {\n\t\t\t\t\tcenterLeft = canvasWidth - maxRadius;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcenterLeft += options.series.pie.offset.left;\n\t\t\t}\n\n\t\t\tvar slices = plot.getData(),\n\t\t\t\tattempts = 0;\n\n\t\t\t// Keep shrinking the pie's radius until drawPie returns true,\n\t\t\t// indicating that all the labels fit, or we try too many times.\n\n\t\t\tdo {\n\t\t\t\tif (attempts > 0) {\n\t\t\t\t\tmaxRadius *= REDRAW_SHRINK;\n\t\t\t\t}\n\t\t\t\tattempts += 1;\n\t\t\t\tclear();\n\t\t\t\tif (options.series.pie.tilt <= 0.8) {\n\t\t\t\t\tdrawShadow();\n\t\t\t\t}\n\t\t\t} while (!drawPie() && attempts < REDRAW_ATTEMPTS)\n\n\t\t\tif (attempts >= REDRAW_ATTEMPTS) {\n\t\t\t\tclear();\n\t\t\t\ttarget.prepend(\"<div class='error'>Could not draw pie with labels contained inside canvas</div>\");\n\t\t\t}\n\n\t\t\tif (plot.setSeries && plot.insertLegend) {\n\t\t\t\tplot.setSeries(slices);\n\t\t\t\tplot.insertLegend();\n\t\t\t}\n\n\t\t\t// we're actually done at this point, just defining internal functions at this point\n\n\t\t\tfunction clear() {\n\t\t\t\tctx.clearRect(0, 0, canvasWidth, canvasHeight);\n\t\t\t\ttarget.children().filter(\".pieLabel, .pieLabelBackground\").remove();\n\t\t\t}\n\n\t\t\tfunction drawShadow() {\n\n\t\t\t\tvar shadowLeft = options.series.pie.shadow.left;\n\t\t\t\tvar shadowTop = options.series.pie.shadow.top;\n\t\t\t\tvar edge = 10;\n\t\t\t\tvar alpha = options.series.pie.shadow.alpha;\n\t\t\t\tvar radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;\n\n\t\t\t\tif (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) {\n\t\t\t\t\treturn;\t// shadow would be outside canvas, so don't draw it\n\t\t\t\t}\n\n\t\t\t\tctx.save();\n\t\t\t\tctx.translate(shadowLeft,shadowTop);\n\t\t\t\tctx.globalAlpha = alpha;\n\t\t\t\tctx.fillStyle = \"#000\";\n\n\t\t\t\t// center and rotate to starting position\n\n\t\t\t\tctx.translate(centerLeft,centerTop);\n\t\t\t\tctx.scale(1, options.series.pie.tilt);\n\n\t\t\t\t//radius -= edge;\n\n\t\t\t\tfor (var i = 1; i <= edge; i++) {\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.arc(0, 0, radius, 0, Math.PI * 2, false);\n\t\t\t\t\tctx.fill();\n\t\t\t\t\tradius -= i;\n\t\t\t\t}\n\n\t\t\t\tctx.restore();\n\t\t\t}\n\n\t\t\tfunction drawPie() {\n\n\t\t\t\tvar startAngle = Math.PI * options.series.pie.startAngle;\n\t\t\t\tvar radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;\n\n\t\t\t\t// center and rotate to starting position\n\n\t\t\t\tctx.save();\n\t\t\t\tctx.translate(centerLeft,centerTop);\n\t\t\t\tctx.scale(1, options.series.pie.tilt);\n\t\t\t\t//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera\n\n\t\t\t\t// draw slices\n\n\t\t\t\tctx.save();\n\t\t\t\tvar currentAngle = startAngle;\n\t\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\t\t\t\t\tslices[i].startAngle = currentAngle;\n\t\t\t\t\tdrawSlice(slices[i].angle, slices[i].color, true);\n\t\t\t\t}\n\t\t\t\tctx.restore();\n\n\t\t\t\t// draw slice outlines\n\n\t\t\t\tif (options.series.pie.stroke.width > 0) {\n\t\t\t\t\tctx.save();\n\t\t\t\t\tctx.lineWidth = options.series.pie.stroke.width;\n\t\t\t\t\tcurrentAngle = startAngle;\n\t\t\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\t\t\t\t\t\tdrawSlice(slices[i].angle, options.series.pie.stroke.color, false);\n\t\t\t\t\t}\n\t\t\t\t\tctx.restore();\n\t\t\t\t}\n\n\t\t\t\t// draw donut hole\n\n\t\t\t\tdrawDonutHole(ctx);\n\n\t\t\t\tctx.restore();\n\n\t\t\t\t// Draw the labels, returning true if they fit within the plot\n\n\t\t\t\tif (options.series.pie.label.show) {\n\t\t\t\t\treturn drawLabels();\n\t\t\t\t} else return true;\n\n\t\t\t\tfunction drawSlice(angle, color, fill) {\n\n\t\t\t\t\tif (angle <= 0 || isNaN(angle)) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (fill) {\n\t\t\t\t\t\tctx.fillStyle = color;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tctx.strokeStyle = color;\n\t\t\t\t\t\tctx.lineJoin = \"round\";\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tif (Math.abs(angle - Math.PI * 2) > 0.000000001) {\n\t\t\t\t\t\tctx.moveTo(0, 0); // Center of the pie\n\t\t\t\t\t}\n\n\t\t\t\t\t//ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera\n\t\t\t\t\tctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false);\n\t\t\t\t\tctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\t//ctx.rotate(angle); // This doesn't work properly in Opera\n\t\t\t\t\tcurrentAngle += angle;\n\n\t\t\t\t\tif (fill) {\n\t\t\t\t\t\tctx.fill();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfunction drawLabels() {\n\n\t\t\t\t\tvar currentAngle = startAngle;\n\t\t\t\t\tvar radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius;\n\n\t\t\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\t\t\t\t\t\tif (slices[i].percent >= options.series.pie.label.threshold * 100) {\n\t\t\t\t\t\t\tif (!drawLabel(slices[i], currentAngle, i)) {\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentAngle += slices[i].angle;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t\tfunction drawLabel(slice, startAngle, index) {\n\n\t\t\t\t\t\tif (slice.data[0][1] == 0) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// format label text\n\n\t\t\t\t\t\tvar lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;\n\n\t\t\t\t\t\tif (lf) {\n\t\t\t\t\t\t\ttext = lf(slice.label, slice);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttext = slice.label;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (plf) {\n\t\t\t\t\t\t\ttext = plf(text, slice);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar halfAngle = ((startAngle + slice.angle) + startAngle) / 2;\n\t\t\t\t\t\tvar x = centerLeft + Math.round(Math.cos(halfAngle) * radius);\n\t\t\t\t\t\tvar y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;\n\n\t\t\t\t\t\tvar html = \"<span class='pieLabel' id='pieLabel\" + index + \"' style='position:absolute;top:\" + y + \"px;left:\" + x + \"px;'>\" + text + \"</span>\";\n\t\t\t\t\t\ttarget.append(html);\n\n\t\t\t\t\t\tvar label = target.children(\"#pieLabel\" + index);\n\t\t\t\t\t\tvar labelTop = (y - label.height() / 2);\n\t\t\t\t\t\tvar labelLeft = (x - label.width() / 2);\n\n\t\t\t\t\t\tlabel.css(\"top\", labelTop);\n\t\t\t\t\t\tlabel.css(\"left\", labelLeft);\n\n\t\t\t\t\t\t// check to make sure that the label is not outside the canvas\n\n\t\t\t\t\t\tif (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (options.series.pie.label.background.opacity != 0) {\n\n\t\t\t\t\t\t\t// put in the transparent background separately to avoid blended labels and label boxes\n\n\t\t\t\t\t\t\tvar c = options.series.pie.label.background.color;\n\n\t\t\t\t\t\t\tif (c == null) {\n\t\t\t\t\t\t\t\tc = slice.color;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar pos = \"top:\" + labelTop + \"px;left:\" + labelLeft + \"px;\";\n\t\t\t\t\t\t\t$(\"<div class='pieLabelBackground' style='position:absolute;width:\" + label.width() + \"px;height:\" + label.height() + \"px;\" + pos + \"background-color:\" + c + \";'></div>\")\n\t\t\t\t\t\t\t\t.css(\"opacity\", options.series.pie.label.background.opacity)\n\t\t\t\t\t\t\t\t.insertBefore(label);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} // end individual label function\n\t\t\t\t} // end drawLabels function\n\t\t\t} // end drawPie function\n\t\t} // end draw function\n\n\t\t// Placed here because it needs to be accessed from multiple locations\n\n\t\tfunction drawDonutHole(layer) {\n\t\t\tif (options.series.pie.innerRadius > 0) {\n\n\t\t\t\t// subtract the center\n\n\t\t\t\tlayer.save();\n\t\t\t\tvar innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;\n\t\t\t\tlayer.globalCompositeOperation = \"destination-out\"; // this does not work with excanvas, but it will fall back to using the stroke color\n\t\t\t\tlayer.beginPath();\n\t\t\t\tlayer.fillStyle = options.series.pie.stroke.color;\n\t\t\t\tlayer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);\n\t\t\t\tlayer.fill();\n\t\t\t\tlayer.closePath();\n\t\t\t\tlayer.restore();\n\n\t\t\t\t// add inner stroke\n\n\t\t\t\tlayer.save();\n\t\t\t\tlayer.beginPath();\n\t\t\t\tlayer.strokeStyle = options.series.pie.stroke.color;\n\t\t\t\tlayer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);\n\t\t\t\tlayer.stroke();\n\t\t\t\tlayer.closePath();\n\t\t\t\tlayer.restore();\n\n\t\t\t\t// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.\n\t\t\t}\n\t\t}\n\n\t\t//-- Additional Interactive related functions --\n\n\t\tfunction isPointInPoly(poly, pt) {\n\t\t\tfor(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)\n\t\t\t\t((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))\n\t\t\t\t&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])\n\t\t\t\t&& (c = !c);\n\t\t\treturn c;\n\t\t}\n\n\t\tfunction findNearbySlice(mouseX, mouseY) {\n\n\t\t\tvar slices = plot.getData(),\n\t\t\t\toptions = plot.getOptions(),\n\t\t\t\tradius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius,\n\t\t\t\tx, y;\n\n\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\n\t\t\t\tvar s = slices[i];\n\n\t\t\t\tif (s.pie.show) {\n\n\t\t\t\t\tctx.save();\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(0, 0); // Center of the pie\n\t\t\t\t\t//ctx.scale(1, options.series.pie.tilt);\t// this actually seems to break everything when here.\n\t\t\t\t\tctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false);\n\t\t\t\t\tctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tx = mouseX - centerLeft;\n\t\t\t\t\ty = mouseY - centerTop;\n\n\t\t\t\t\tif (ctx.isPointInPath) {\n\t\t\t\t\t\tif (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) {\n\t\t\t\t\t\t\tctx.restore();\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tdatapoint: [s.percent, s.data],\n\t\t\t\t\t\t\t\tdataIndex: 0,\n\t\t\t\t\t\t\t\tseries: s,\n\t\t\t\t\t\t\t\tseriesIndex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// excanvas for IE doesn;t support isPointInPath, this is a workaround.\n\n\t\t\t\t\t\tvar p1X = radius * Math.cos(s.startAngle),\n\t\t\t\t\t\t\tp1Y = radius * Math.sin(s.startAngle),\n\t\t\t\t\t\t\tp2X = radius * Math.cos(s.startAngle + s.angle / 4),\n\t\t\t\t\t\t\tp2Y = radius * Math.sin(s.startAngle + s.angle / 4),\n\t\t\t\t\t\t\tp3X = radius * Math.cos(s.startAngle + s.angle / 2),\n\t\t\t\t\t\t\tp3Y = radius * Math.sin(s.startAngle + s.angle / 2),\n\t\t\t\t\t\t\tp4X = radius * Math.cos(s.startAngle + s.angle / 1.5),\n\t\t\t\t\t\t\tp4Y = radius * Math.sin(s.startAngle + s.angle / 1.5),\n\t\t\t\t\t\t\tp5X = radius * Math.cos(s.startAngle + s.angle),\n\t\t\t\t\t\t\tp5Y = radius * Math.sin(s.startAngle + s.angle),\n\t\t\t\t\t\t\tarrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]],\n\t\t\t\t\t\t\tarrPoint = [x, y];\n\n\t\t\t\t\t\t// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?\n\n\t\t\t\t\t\tif (isPointInPoly(arrPoly, arrPoint)) {\n\t\t\t\t\t\t\tctx.restore();\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tdatapoint: [s.percent, s.data],\n\t\t\t\t\t\t\t\tdataIndex: 0,\n\t\t\t\t\t\t\t\tseries: s,\n\t\t\t\t\t\t\t\tseriesIndex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.restore();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tfunction onMouseMove(e) {\n\t\t\ttriggerClickHoverEvent(\"plothover\", e);\n\t\t}\n\n\t\tfunction onClick(e) {\n\t\t\ttriggerClickHoverEvent(\"plotclick\", e);\n\t\t}\n\n\t\t// trigger click or hover event (they send the same parameters so we share their code)\n\n\t\tfunction triggerClickHoverEvent(eventname, e) {\n\n\t\t\tvar offset = plot.offset();\n\t\t\tvar canvasX = parseInt(e.pageX - offset.left);\n\t\t\tvar canvasY =  parseInt(e.pageY - offset.top);\n\t\t\tvar item = findNearbySlice(canvasX, canvasY);\n\n\t\t\tif (options.grid.autoHighlight) {\n\n\t\t\t\t// clear auto-highlights\n\n\t\t\t\tfor (var i = 0; i < highlights.length; ++i) {\n\t\t\t\t\tvar h = highlights[i];\n\t\t\t\t\tif (h.auto == eventname && !(item && h.series == item.series)) {\n\t\t\t\t\t\tunhighlight(h.series);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// highlight the slice\n\n\t\t\tif (item) {\n\t\t\t\thighlight(item.series, eventname);\n\t\t\t}\n\n\t\t\t// trigger any hover bind events\n\n\t\t\tvar pos = { pageX: e.pageX, pageY: e.pageY };\n\t\t\ttarget.trigger(eventname, [pos, item]);\n\t\t}\n\n\t\tfunction highlight(s, auto) {\n\t\t\t//if (typeof s == \"number\") {\n\t\t\t//\ts = series[s];\n\t\t\t//}\n\n\t\t\tvar i = indexOfHighlight(s);\n\n\t\t\tif (i == -1) {\n\t\t\t\thighlights.push({ series: s, auto: auto });\n\t\t\t\tplot.triggerRedrawOverlay();\n\t\t\t} else if (!auto) {\n\t\t\t\thighlights[i].auto = false;\n\t\t\t}\n\t\t}\n\n\t\tfunction unhighlight(s) {\n\t\t\tif (s == null) {\n\t\t\t\thighlights = [];\n\t\t\t\tplot.triggerRedrawOverlay();\n\t\t\t}\n\n\t\t\t//if (typeof s == \"number\") {\n\t\t\t//\ts = series[s];\n\t\t\t//}\n\n\t\t\tvar i = indexOfHighlight(s);\n\n\t\t\tif (i != -1) {\n\t\t\t\thighlights.splice(i, 1);\n\t\t\t\tplot.triggerRedrawOverlay();\n\t\t\t}\n\t\t}\n\n\t\tfunction indexOfHighlight(s) {\n\t\t\tfor (var i = 0; i < highlights.length; ++i) {\n\t\t\t\tvar h = highlights[i];\n\t\t\t\tif (h.series == s)\n\t\t\t\t\treturn i;\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\n\t\tfunction drawOverlay(plot, octx) {\n\n\t\t\tvar options = plot.getOptions();\n\n\t\t\tvar radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;\n\n\t\t\toctx.save();\n\t\t\toctx.translate(centerLeft, centerTop);\n\t\t\toctx.scale(1, options.series.pie.tilt);\n\n\t\t\tfor (var i = 0; i < highlights.length; ++i) {\n\t\t\t\tdrawHighlight(highlights[i].series);\n\t\t\t}\n\n\t\t\tdrawDonutHole(octx);\n\n\t\t\toctx.restore();\n\n\t\t\tfunction drawHighlight(series) {\n\n\t\t\t\tif (series.angle <= 0 || isNaN(series.angle)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();\n\t\t\t\toctx.fillStyle = \"rgba(255, 255, 255, \" + options.series.pie.highlight.opacity + \")\"; // this is temporary until we have access to parseColor\n\t\t\t\toctx.beginPath();\n\t\t\t\tif (Math.abs(series.angle - Math.PI * 2) > 0.000000001) {\n\t\t\t\t\toctx.moveTo(0, 0); // Center of the pie\n\t\t\t\t}\n\t\t\t\toctx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false);\n\t\t\t\toctx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false);\n\t\t\t\toctx.closePath();\n\t\t\t\toctx.fill();\n\t\t\t}\n\t\t}\n\t} // end init (plugin body)\n\n\t// define pie specific options and their default values\n\n\tvar options = {\n\t\tseries: {\n\t\t\tpie: {\n\t\t\t\tshow: false,\n\t\t\t\tradius: \"auto\",\t// actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)\n\t\t\t\tinnerRadius: 0, /* for donut */\n\t\t\t\tstartAngle: 3/2,\n\t\t\t\ttilt: 1,\n\t\t\t\tshadow: {\n\t\t\t\t\tleft: 5,\t// shadow left offset\n\t\t\t\t\ttop: 15,\t// shadow top offset\n\t\t\t\t\talpha: 0.02\t// shadow alpha\n\t\t\t\t},\n\t\t\t\toffset: {\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: \"auto\"\n\t\t\t\t},\n\t\t\t\tstroke: {\n\t\t\t\t\tcolor: \"#fff\",\n\t\t\t\t\twidth: 1\n\t\t\t\t},\n\t\t\t\tlabel: {\n\t\t\t\t\tshow: \"auto\",\n\t\t\t\t\tformatter: function(label, slice) {\n\t\t\t\t\t\treturn \"<div style='font-size:x-small;text-align:center;padding:2px;color:\" + slice.color + \";'>\" + label + \"<br/>\" + Math.round(slice.percent) + \"%</div>\";\n\t\t\t\t\t},\t// formatter function\n\t\t\t\t\tradius: 1,\t// radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)\n\t\t\t\t\tbackground: {\n\t\t\t\t\t\tcolor: null,\n\t\t\t\t\t\topacity: 0\n\t\t\t\t\t},\n\t\t\t\t\tthreshold: 0\t// percentage at which to hide the label (i.e. the slice is too narrow)\n\t\t\t\t},\n\t\t\t\tcombine: {\n\t\t\t\t\tthreshold: -1,\t// percentage at which to combine little slices into one larger slice\n\t\t\t\t\tcolor: null,\t// color to give the new slice (auto-generated if null)\n\t\t\t\t\tlabel: \"Other\"\t// label to give the new slice\n\t\t\t\t},\n\t\t\t\thighlight: {\n\t\t\t\t\t//color: \"#fff\",\t\t// will add this functionality once parseColor is available\n\t\t\t\t\topacity: 0.5\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t$.plot.plugins.push({\n\t\tinit: init,\n\t\toptions: options,\n\t\tname: \"pie\",\n\t\tversion: \"1.1\"\n\t});\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/flot-chart/jquery.flot.resize.js",
    "content": "/* Flot plugin for automatically redrawing plots as the placeholder resizes.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nIt works by listening for changes on the placeholder div (through the jQuery\nresize event plugin) - if the size changes, it will redraw the plot.\n\nThere are no options. If you need to disable the plugin for some plots, you\ncan just fix the size of their placeholders.\n\n*/\n\n/* Inline dependency:\n * jQuery resize event - v1.1 - 3/14/2010\n * http://benalman.com/projects/jquery-resize-plugin/\n *\n * Copyright (c) 2010 \"Cowboy\" Ben Alman\n * Dual licensed under the MIT and GPL licenses.\n * http://benalman.com/about/license/\n */\n\n(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k=\"setTimeout\",j=\"resize\",d=j+\"-special-event\",b=\"delay\",f=\"throttleWindow\";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);\n\n(function ($) {\n    var options = { }; // no options\n\n    function init(plot) {\n        function onResize() {\n            var placeholder = plot.getPlaceholder();\n\n            // somebody might have hidden us and we can't plot\n            // when we don't have the dimensions\n            if (placeholder.width() == 0 || placeholder.height() == 0)\n                return;\n\n            plot.resize();\n            plot.setupGrid();\n            plot.draw();\n        }\n        \n        function bindEvents(plot, eventHolder) {\n            plot.getPlaceholder().resize(onResize);\n        }\n\n        function shutdown(plot, eventHolder) {\n            plot.getPlaceholder().unbind(\"resize\", onResize);\n        }\n        \n        plot.hooks.bindEvents.push(bindEvents);\n        plot.hooks.shutdown.push(shutdown);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'resize',\n        version: '1.0'\n    });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/flot-chart/jquery.flot.selection.js",
    "content": "/*\nFlot plugin for selecting regions.\n\nThe plugin defines the following options:\n\n  selection: {\n    mode: null or \"x\" or \"y\" or \"xy\",\n    color: color\n  }\n\nSelection support is enabled by setting the mode to one of \"x\", \"y\" or\n\"xy\". In \"x\" mode, the user will only be able to specify the x range,\nsimilarly for \"y\" mode. For \"xy\", the selection becomes a rectangle\nwhere both ranges can be specified. \"color\" is color of the selection\n(if you need to change the color later on, you can get to it with\nplot.getOptions().selection.color).\n\nWhen selection support is enabled, a \"plotselected\" event will be\nemitted on the DOM element you passed into the plot function. The\nevent handler gets a parameter with the ranges selected on the axes,\nlike this:\n\n  placeholder.bind(\"plotselected\", function(event, ranges) {\n    alert(\"You selected \" + ranges.xaxis.from + \" to \" + ranges.xaxis.to)\n    // similar for yaxis - with multiple axes, the extra ones are in\n    // x2axis, x3axis, ...\n  });\n\nThe \"plotselected\" event is only fired when the user has finished\nmaking the selection. A \"plotselecting\" event is fired during the\nprocess with the same parameters as the \"plotselected\" event, in case\nyou want to know what's happening while it's happening,\n\nA \"plotunselected\" event with no arguments is emitted when the user\nclicks the mouse to remove the selection.\n\nThe plugin allso adds the following methods to the plot object:\n\n- setSelection(ranges, preventEvent)\n\n  Set the selection rectangle. The passed in ranges is on the same\n  form as returned in the \"plotselected\" event. If the selection mode\n  is \"x\", you should put in either an xaxis range, if the mode is \"y\"\n  you need to put in an yaxis range and both xaxis and yaxis if the\n  selection mode is \"xy\", like this:\n\n    setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });\n\n  setSelection will trigger the \"plotselected\" event when called. If\n  you don't want that to happen, e.g. if you're inside a\n  \"plotselected\" handler, pass true as the second parameter. If you\n  are using multiple axes, you can specify the ranges on any of those,\n  e.g. as x2axis/x3axis/... instead of xaxis, the plugin picks the\n  first one it sees.\n  \n- clearSelection(preventEvent)\n\n  Clear the selection rectangle. Pass in true to avoid getting a\n  \"plotunselected\" event.\n\n- getSelection()\n\n  Returns the current selection in the same format as the\n  \"plotselected\" event. If there's currently no selection, the\n  function returns null.\n\n*/\n\n(function ($) {\n    function init(plot) {\n        var selection = {\n                first: { x: -1, y: -1}, second: { x: -1, y: -1},\n                show: false,\n                active: false\n            };\n\n        // FIXME: The drag handling implemented here should be\n        // abstracted out, there's some similar code from a library in\n        // the navigation plugin, this should be massaged a bit to fit\n        // the Flot cases here better and reused. Doing this would\n        // make this plugin much slimmer.\n        var savedhandlers = {};\n\n        var mouseUpHandler = null;\n        \n        function onMouseMove(e) {\n            if (selection.active) {\n                updateSelection(e);\n                \n                plot.getPlaceholder().trigger(\"plotselecting\", [ getSelection() ]);\n            }\n        }\n\n        function onMouseDown(e) {\n            if (e.which != 1)  // only accept left-click\n                return;\n            \n            // cancel out any text selections\n            document.body.focus();\n\n            // prevent text selection and drag in old-school browsers\n            if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {\n                savedhandlers.onselectstart = document.onselectstart;\n                document.onselectstart = function () { return false; };\n            }\n            if (document.ondrag !== undefined && savedhandlers.ondrag == null) {\n                savedhandlers.ondrag = document.ondrag;\n                document.ondrag = function () { return false; };\n            }\n\n            setSelectionPos(selection.first, e);\n\n            selection.active = true;\n\n            // this is a bit silly, but we have to use a closure to be\n            // able to whack the same handler again\n            mouseUpHandler = function (e) { onMouseUp(e); };\n            \n            $(document).one(\"mouseup\", mouseUpHandler);\n        }\n\n        function onMouseUp(e) {\n            mouseUpHandler = null;\n            \n            // revert drag stuff for old-school browsers\n            if (document.onselectstart !== undefined)\n                document.onselectstart = savedhandlers.onselectstart;\n            if (document.ondrag !== undefined)\n                document.ondrag = savedhandlers.ondrag;\n\n            // no more dragging\n            selection.active = false;\n            updateSelection(e);\n\n            if (selectionIsSane())\n                triggerSelectedEvent();\n            else {\n                // this counts as a clear\n                plot.getPlaceholder().trigger(\"plotunselected\", [ ]);\n                plot.getPlaceholder().trigger(\"plotselecting\", [ null ]);\n            }\n\n            return false;\n        }\n\n        function getSelection() {\n            if (!selectionIsSane())\n                return null;\n\n            var r = {}, c1 = selection.first, c2 = selection.second;\n            $.each(plot.getAxes(), function (name, axis) {\n                if (axis.used) {\n                    var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]); \n                    r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };\n                }\n            });\n            return r;\n        }\n\n        function triggerSelectedEvent() {\n            var r = getSelection();\n\n            plot.getPlaceholder().trigger(\"plotselected\", [ r ]);\n\n            // backwards-compat stuff, to be removed in future\n            if (r.xaxis && r.yaxis)\n                plot.getPlaceholder().trigger(\"selected\", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);\n        }\n\n        function clamp(min, value, max) {\n            return value < min ? min: (value > max ? max: value);\n        }\n\n        function setSelectionPos(pos, e) {\n            var o = plot.getOptions();\n            var offset = plot.getPlaceholder().offset();\n            var plotOffset = plot.getPlotOffset();\n            pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());\n            pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());\n\n            if (o.selection.mode == \"y\")\n                pos.x = pos == selection.first ? 0 : plot.width();\n\n            if (o.selection.mode == \"x\")\n                pos.y = pos == selection.first ? 0 : plot.height();\n        }\n\n        function updateSelection(pos) {\n            if (pos.pageX == null)\n                return;\n\n            setSelectionPos(selection.second, pos);\n            if (selectionIsSane()) {\n                selection.show = true;\n                plot.triggerRedrawOverlay();\n            }\n            else\n                clearSelection(true);\n        }\n\n        function clearSelection(preventEvent) {\n            if (selection.show) {\n                selection.show = false;\n                plot.triggerRedrawOverlay();\n                if (!preventEvent)\n                    plot.getPlaceholder().trigger(\"plotunselected\", [ ]);\n            }\n        }\n\n        // function taken from markings support in Flot\n        function extractRange(ranges, coord) {\n            var axis, from, to, key, axes = plot.getAxes();\n\n            for (var k in axes) {\n                axis = axes[k];\n                if (axis.direction == coord) {\n                    key = coord + axis.n + \"axis\";\n                    if (!ranges[key] && axis.n == 1)\n                        key = coord + \"axis\"; // support x1axis as xaxis\n                    if (ranges[key]) {\n                        from = ranges[key].from;\n                        to = ranges[key].to;\n                        break;\n                    }\n                }\n            }\n\n            // backwards-compat stuff - to be removed in future\n            if (!ranges[key]) {\n                axis = coord == \"x\" ? plot.getXAxes()[0] : plot.getYAxes()[0];\n                from = ranges[coord + \"1\"];\n                to = ranges[coord + \"2\"];\n            }\n\n            // auto-reverse as an added bonus\n            if (from != null && to != null && from > to) {\n                var tmp = from;\n                from = to;\n                to = tmp;\n            }\n            \n            return { from: from, to: to, axis: axis };\n        }\n        \n        function setSelection(ranges, preventEvent) {\n            var axis, range, o = plot.getOptions();\n\n            if (o.selection.mode == \"y\") {\n                selection.first.x = 0;\n                selection.second.x = plot.width();\n            }\n            else {\n                range = extractRange(ranges, \"x\");\n\n                selection.first.x = range.axis.p2c(range.from);\n                selection.second.x = range.axis.p2c(range.to);\n            }\n\n            if (o.selection.mode == \"x\") {\n                selection.first.y = 0;\n                selection.second.y = plot.height();\n            }\n            else {\n                range = extractRange(ranges, \"y\");\n\n                selection.first.y = range.axis.p2c(range.from);\n                selection.second.y = range.axis.p2c(range.to);\n            }\n\n            selection.show = true;\n            plot.triggerRedrawOverlay();\n            if (!preventEvent && selectionIsSane())\n                triggerSelectedEvent();\n        }\n\n        function selectionIsSane() {\n            var minSize = 5;\n            return Math.abs(selection.second.x - selection.first.x) >= minSize &&\n                Math.abs(selection.second.y - selection.first.y) >= minSize;\n        }\n\n        plot.clearSelection = clearSelection;\n        plot.setSelection = setSelection;\n        plot.getSelection = getSelection;\n\n        plot.hooks.bindEvents.push(function(plot, eventHolder) {\n            var o = plot.getOptions();\n            if (o.selection.mode != null) {\n                eventHolder.mousemove(onMouseMove);\n                eventHolder.mousedown(onMouseDown);\n            }\n        });\n\n\n        plot.hooks.drawOverlay.push(function (plot, ctx) {\n            // draw selection\n            if (selection.show && selectionIsSane()) {\n                var plotOffset = plot.getPlotOffset();\n                var o = plot.getOptions();\n\n                ctx.save();\n                ctx.translate(plotOffset.left, plotOffset.top);\n\n                var c = $.color.parse(o.selection.color);\n\n                ctx.strokeStyle = c.scale('a', 0.8).toString();\n                ctx.lineWidth = 1;\n                ctx.lineJoin = \"round\";\n                ctx.fillStyle = c.scale('a', 0.4).toString();\n\n                var x = Math.min(selection.first.x, selection.second.x),\n                    y = Math.min(selection.first.y, selection.second.y),\n                    w = Math.abs(selection.second.x - selection.first.x),\n                    h = Math.abs(selection.second.y - selection.first.y);\n\n                ctx.fillRect(x, y, w, h);\n                ctx.strokeRect(x, y, w, h);\n\n                ctx.restore();\n            }\n        });\n        \n        plot.hooks.shutdown.push(function (plot, eventHolder) {\n            eventHolder.unbind(\"mousemove\", onMouseMove);\n            eventHolder.unbind(\"mousedown\", onMouseDown);\n            \n            if (mouseUpHandler)\n                $(document).unbind(\"mouseup\", mouseUpHandler);\n        });\n\n    }\n\n    $.plot.plugins.push({\n        init: init,\n        options: {\n            selection: {\n                mode: null, // one of null, \"x\", \"y\" or \"xy\"\n                color: \"#e8cfac\"\n            }\n        },\n        name: 'selection',\n        version: '1.1'\n    });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/flot-chart/jquery.flot.stack.js",
    "content": "/*\nFlot plugin for stacking data sets, i.e. putting them on top of each\nother, for accumulative graphs.\n\nThe plugin assumes the data is sorted on x (or y if stacking\nhorizontally). For line charts, it is assumed that if a line has an\nundefined gap (from a null point), then the line above it should have\nthe same gap - insert zeros instead of \"null\" if you want another\nbehaviour. This also holds for the start and end of the chart. Note\nthat stacking a mix of positive and negative values in most instances\ndoesn't make sense (so it looks weird).\n\nTwo or more series are stacked when their \"stack\" attribute is set to\nthe same key (which can be any number or string or just \"true\"). To\nspecify the default stack, you can set\n\n  series: {\n    stack: null or true or key (number/string)\n  }\n\nor specify it for a specific series\n\n  $.plot($(\"#placeholder\"), [{ data: [ ... ], stack: true }])\n  \nThe stacking order is determined by the order of the data series in\nthe array (later series end up on top of the previous).\n\nInternally, the plugin modifies the datapoints in each series, adding\nan offset to the y value. For line series, extra data points are\ninserted through interpolation. If there's a second y value, it's also\nadjusted (e.g for bar charts or filled areas).\n*/\n\n(function ($) {\n    var options = {\n        series: { stack: null } // or number/string\n    };\n    \n    function init(plot) {\n        function findMatchingSeries(s, allseries) {\n            var res = null\n            for (var i = 0; i < allseries.length; ++i) {\n                if (s == allseries[i])\n                    break;\n                \n                if (allseries[i].stack == s.stack)\n                    res = allseries[i];\n            }\n            \n            return res;\n        }\n        \n        function stackData(plot, s, datapoints) {\n            if (s.stack == null)\n                return;\n\n            var other = findMatchingSeries(s, plot.getData());\n            if (!other)\n                return;\n\n            var ps = datapoints.pointsize,\n                points = datapoints.points,\n                otherps = other.datapoints.pointsize,\n                otherpoints = other.datapoints.points,\n                newpoints = [],\n                px, py, intery, qx, qy, bottom,\n                withlines = s.lines.show,\n                horizontal = s.bars.horizontal,\n                withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),\n                withsteps = withlines && s.lines.steps,\n                fromgap = true,\n                keyOffset = horizontal ? 1 : 0,\n                accumulateOffset = horizontal ? 0 : 1,\n                i = 0, j = 0, l;\n\n            while (true) {\n                if (i >= points.length)\n                    break;\n\n                l = newpoints.length;\n\n                if (points[i] == null) {\n                    // copy gaps\n                    for (m = 0; m < ps; ++m)\n                        newpoints.push(points[i + m]);\n                    i += ps;\n                }\n                else if (j >= otherpoints.length) {\n                    // for lines, we can't use the rest of the points\n                    if (!withlines) {\n                        for (m = 0; m < ps; ++m)\n                            newpoints.push(points[i + m]);\n                    }\n                    i += ps;\n                }\n                else if (otherpoints[j] == null) {\n                    // oops, got a gap\n                    for (m = 0; m < ps; ++m)\n                        newpoints.push(null);\n                    fromgap = true;\n                    j += otherps;\n                }\n                else {\n                    // cases where we actually got two points\n                    px = points[i + keyOffset];\n                    py = points[i + accumulateOffset];\n                    qx = otherpoints[j + keyOffset];\n                    qy = otherpoints[j + accumulateOffset];\n                    bottom = 0;\n\n                    if (px == qx) {\n                        for (m = 0; m < ps; ++m)\n                            newpoints.push(points[i + m]);\n\n                        newpoints[l + accumulateOffset] += qy;\n                        bottom = qy;\n                        \n                        i += ps;\n                        j += otherps;\n                    }\n                    else if (px > qx) {\n                        // we got past point below, might need to\n                        // insert interpolated extra point\n                        if (withlines && i > 0 && points[i - ps] != null) {\n                            intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);\n                            newpoints.push(qx);\n                            newpoints.push(intery + qy);\n                            for (m = 2; m < ps; ++m)\n                                newpoints.push(points[i + m]);\n                            bottom = qy; \n                        }\n\n                        j += otherps;\n                    }\n                    else { // px < qx\n                        if (fromgap && withlines) {\n                            // if we come from a gap, we just skip this point\n                            i += ps;\n                            continue;\n                        }\n                            \n                        for (m = 0; m < ps; ++m)\n                            newpoints.push(points[i + m]);\n                        \n                        // we might be able to interpolate a point below,\n                        // this can give us a better y\n                        if (withlines && j > 0 && otherpoints[j - otherps] != null)\n                            bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);\n\n                        newpoints[l + accumulateOffset] += bottom;\n                        \n                        i += ps;\n                    }\n\n                    fromgap = false;\n                    \n                    if (l != newpoints.length && withbottom)\n                        newpoints[l + 2] += bottom;\n                }\n\n                // maintain the line steps invariant\n                if (withsteps && l != newpoints.length && l > 0\n                    && newpoints[l] != null\n                    && newpoints[l] != newpoints[l - ps]\n                    && newpoints[l + 1] != newpoints[l - ps + 1]) {\n                    for (m = 0; m < ps; ++m)\n                        newpoints[l + ps + m] = newpoints[l + m];\n                    newpoints[l + 1] = newpoints[l - ps + 1];\n                }\n            }\n\n            datapoints.points = newpoints;\n        }\n        \n        plot.hooks.processDatapoints.push(stackData);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'stack',\n        version: '1.2'\n    });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/flot-chart/jquery.flot.time.js",
    "content": "/* Pretty handling of time axes.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nSet axis.mode to \"time\" to enable. See the section \"Time series data\" in\nAPI.txt for details.\n\n*/\n\n(function($) {\n\n\tvar options = {\n\t\txaxis: {\n\t\t\ttimezone: null,\t\t// \"browser\" for local to the client or timezone for timezone-js\n\t\t\ttimeformat: null,\t// format string to use\n\t\t\ttwelveHourClock: false,\t// 12 or 24 time in time mode\n\t\t\tmonthNames: null\t// list of names of months\n\t\t}\n\t};\n\n\t// round to nearby lower multiple of base\n\n\tfunction floorInBase(n, base) {\n\t\treturn base * Math.floor(n / base);\n\t}\n\n\t// Returns a string with the date d formatted according to fmt.\n\t// A subset of the Open Group's strftime format is supported.\n\n\tfunction formatDate(d, fmt, monthNames, dayNames) {\n\n\t\tif (typeof d.strftime == \"function\") {\n\t\t\treturn d.strftime(fmt);\n\t\t}\n\n\t\tvar leftPad = function(n, pad) {\n\t\t\tn = \"\" + n;\n\t\t\tpad = \"\" + (pad == null ? \"0\" : pad);\n\t\t\treturn n.length == 1 ? pad + n : n;\n\t\t};\n\n\t\tvar r = [];\n\t\tvar escape = false;\n\t\tvar hours = d.getHours();\n\t\tvar isAM = hours < 12;\n\n\t\tif (monthNames == null) {\n\t\t\tmonthNames = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n\t\t}\n\n\t\tif (dayNames == null) {\n\t\t\tdayNames = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\t\t}\n\n\t\tvar hours12;\n\n\t\tif (hours > 12) {\n\t\t\thours12 = hours - 12;\n\t\t} else if (hours == 0) {\n\t\t\thours12 = 12;\n\t\t} else {\n\t\t\thours12 = hours;\n\t\t}\n\n\t\tfor (var i = 0; i < fmt.length; ++i) {\n\n\t\t\tvar c = fmt.charAt(i);\n\n\t\t\tif (escape) {\n\t\t\t\tswitch (c) {\n\t\t\t\t\tcase 'a': c = \"\" + dayNames[d.getDay()]; break;\n\t\t\t\t\tcase 'b': c = \"\" + monthNames[d.getMonth()]; break;\n\t\t\t\t\tcase 'd': c = leftPad(d.getDate()); break;\n\t\t\t\t\tcase 'e': c = leftPad(d.getDate(), \" \"); break;\n\t\t\t\t\tcase 'h':\t// For back-compat with 0.7; remove in 1.0\n\t\t\t\t\tcase 'H': c = leftPad(hours); break;\n\t\t\t\t\tcase 'I': c = leftPad(hours12); break;\n\t\t\t\t\tcase 'l': c = leftPad(hours12, \" \"); break;\n\t\t\t\t\tcase 'm': c = leftPad(d.getMonth() + 1); break;\n\t\t\t\t\tcase 'M': c = leftPad(d.getMinutes()); break;\n\t\t\t\t\t// quarters not in Open Group's strftime specification\n\t\t\t\t\tcase 'q':\n\t\t\t\t\t\tc = \"\" + (Math.floor(d.getMonth() / 3) + 1); break;\n\t\t\t\t\tcase 'S': c = leftPad(d.getSeconds()); break;\n\t\t\t\t\tcase 'y': c = leftPad(d.getFullYear() % 100); break;\n\t\t\t\t\tcase 'Y': c = \"\" + d.getFullYear(); break;\n\t\t\t\t\tcase 'p': c = (isAM) ? (\"\" + \"am\") : (\"\" + \"pm\"); break;\n\t\t\t\t\tcase 'P': c = (isAM) ? (\"\" + \"AM\") : (\"\" + \"PM\"); break;\n\t\t\t\t\tcase 'w': c = \"\" + d.getDay(); break;\n\t\t\t\t}\n\t\t\t\tr.push(c);\n\t\t\t\tescape = false;\n\t\t\t} else {\n\t\t\t\tif (c == \"%\") {\n\t\t\t\t\tescape = true;\n\t\t\t\t} else {\n\t\t\t\t\tr.push(c);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn r.join(\"\");\n\t}\n\n\t// To have a consistent view of time-based data independent of which time\n\t// zone the client happens to be in we need a date-like object independent\n\t// of time zones.  This is done through a wrapper that only calls the UTC\n\t// versions of the accessor methods.\n\n\tfunction makeUtcWrapper(d) {\n\n\t\tfunction addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) {\n\t\t\tsourceObj[sourceMethod] = function() {\n\t\t\t\treturn targetObj[targetMethod].apply(targetObj, arguments);\n\t\t\t};\n\t\t};\n\n\t\tvar utc = {\n\t\t\tdate: d\n\t\t};\n\n\t\t// support strftime, if found\n\n\t\tif (d.strftime != undefined) {\n\t\t\taddProxyMethod(utc, \"strftime\", d, \"strftime\");\n\t\t}\n\n\t\taddProxyMethod(utc, \"getTime\", d, \"getTime\");\n\t\taddProxyMethod(utc, \"setTime\", d, \"setTime\");\n\n\t\tvar props = [\"Date\", \"Day\", \"FullYear\", \"Hours\", \"Milliseconds\", \"Minutes\", \"Month\", \"Seconds\"];\n\n\t\tfor (var p = 0; p < props.length; p++) {\n\t\t\taddProxyMethod(utc, \"get\" + props[p], d, \"getUTC\" + props[p]);\n\t\t\taddProxyMethod(utc, \"set\" + props[p], d, \"setUTC\" + props[p]);\n\t\t}\n\n\t\treturn utc;\n\t};\n\n\t// select time zone strategy.  This returns a date-like object tied to the\n\t// desired timezone\n\n\tfunction dateGenerator(ts, opts) {\n\t\tif (opts.timezone == \"browser\") {\n\t\t\treturn new Date(ts);\n\t\t} else if (!opts.timezone || opts.timezone == \"utc\") {\n\t\t\treturn makeUtcWrapper(new Date(ts));\n\t\t} else if (typeof timezoneJS != \"undefined\" && typeof timezoneJS.Date != \"undefined\") {\n\t\t\tvar d = new timezoneJS.Date();\n\t\t\t// timezone-js is fickle, so be sure to set the time zone before\n\t\t\t// setting the time.\n\t\t\td.setTimezone(opts.timezone);\n\t\t\td.setTime(ts);\n\t\t\treturn d;\n\t\t} else {\n\t\t\treturn makeUtcWrapper(new Date(ts));\n\t\t}\n\t}\n\t\n\t// map of app. size of time units in milliseconds\n\n\tvar timeUnitSize = {\n\t\t\"second\": 1000,\n\t\t\"minute\": 60 * 1000,\n\t\t\"hour\": 60 * 60 * 1000,\n\t\t\"day\": 24 * 60 * 60 * 1000,\n\t\t\"month\": 30 * 24 * 60 * 60 * 1000,\n\t\t\"quarter\": 3 * 30 * 24 * 60 * 60 * 1000,\n\t\t\"year\": 365.2425 * 24 * 60 * 60 * 1000\n\t};\n\n\t// the allowed tick sizes, after 1 year we use\n\t// an integer algorithm\n\n\tvar baseSpec = [\n\t\t[1, \"second\"], [2, \"second\"], [5, \"second\"], [10, \"second\"],\n\t\t[30, \"second\"], \n\t\t[1, \"minute\"], [2, \"minute\"], [5, \"minute\"], [10, \"minute\"],\n\t\t[30, \"minute\"], \n\t\t[1, \"hour\"], [2, \"hour\"], [4, \"hour\"],\n\t\t[8, \"hour\"], [12, \"hour\"],\n\t\t[1, \"day\"], [2, \"day\"], [3, \"day\"],\n\t\t[0.25, \"month\"], [0.5, \"month\"], [1, \"month\"],\n\t\t[2, \"month\"]\n\t];\n\n\t// we don't know which variant(s) we'll need yet, but generating both is\n\t// cheap\n\n\tvar specMonths = baseSpec.concat([[3, \"month\"], [6, \"month\"],\n\t\t[1, \"year\"]]);\n\tvar specQuarters = baseSpec.concat([[1, \"quarter\"], [2, \"quarter\"],\n\t\t[1, \"year\"]]);\n\n\tfunction init(plot) {\n\t\tplot.hooks.processOptions.push(function (plot, options) {\n\t\t\t$.each(plot.getAxes(), function(axisName, axis) {\n\n\t\t\t\tvar opts = axis.options;\n\n\t\t\t\tif (opts.mode == \"time\") {\n\t\t\t\t\taxis.tickGenerator = function(axis) {\n\n\t\t\t\t\t\tvar ticks = [];\n\t\t\t\t\t\tvar d = dateGenerator(axis.min, opts);\n\t\t\t\t\t\tvar minSize = 0;\n\n\t\t\t\t\t\t// make quarter use a possibility if quarters are\n\t\t\t\t\t\t// mentioned in either of these options\n\n\t\t\t\t\t\tvar spec = (opts.tickSize && opts.tickSize[1] ===\n\t\t\t\t\t\t\t\"quarter\") ||\n\t\t\t\t\t\t\t(opts.minTickSize && opts.minTickSize[1] ===\n\t\t\t\t\t\t\t\"quarter\") ? specQuarters : specMonths;\n\n\t\t\t\t\t\tif (opts.minTickSize != null) {\n\t\t\t\t\t\t\tif (typeof opts.tickSize == \"number\") {\n\t\t\t\t\t\t\t\tminSize = opts.tickSize;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tminSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (var i = 0; i < spec.length - 1; ++i) {\n\t\t\t\t\t\t\tif (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]]\n\t\t\t\t\t\t\t\t\t\t\t  + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2\n\t\t\t\t\t\t\t\t&& spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar size = spec[i][0];\n\t\t\t\t\t\tvar unit = spec[i][1];\n\n\t\t\t\t\t\t// special-case the possibility of several years\n\n\t\t\t\t\t\tif (unit == \"year\") {\n\n\t\t\t\t\t\t\t// if given a minTickSize in years, just use it,\n\t\t\t\t\t\t\t// ensuring that it's an integer\n\n\t\t\t\t\t\t\tif (opts.minTickSize != null && opts.minTickSize[1] == \"year\") {\n\t\t\t\t\t\t\t\tsize = Math.floor(opts.minTickSize[0]);\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tvar magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10));\n\t\t\t\t\t\t\t\tvar norm = (axis.delta / timeUnitSize.year) / magn;\n\n\t\t\t\t\t\t\t\tif (norm < 1.5) {\n\t\t\t\t\t\t\t\t\tsize = 1;\n\t\t\t\t\t\t\t\t} else if (norm < 3) {\n\t\t\t\t\t\t\t\t\tsize = 2;\n\t\t\t\t\t\t\t\t} else if (norm < 7.5) {\n\t\t\t\t\t\t\t\t\tsize = 5;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tsize = 10;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tsize *= magn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// minimum size for years is 1\n\n\t\t\t\t\t\t\tif (size < 1) {\n\t\t\t\t\t\t\t\tsize = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\taxis.tickSize = opts.tickSize || [size, unit];\n\t\t\t\t\t\tvar tickSize = axis.tickSize[0];\n\t\t\t\t\t\tunit = axis.tickSize[1];\n\n\t\t\t\t\t\tvar step = tickSize * timeUnitSize[unit];\n\n\t\t\t\t\t\tif (unit == \"second\") {\n\t\t\t\t\t\t\td.setSeconds(floorInBase(d.getSeconds(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"minute\") {\n\t\t\t\t\t\t\td.setMinutes(floorInBase(d.getMinutes(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"hour\") {\n\t\t\t\t\t\t\td.setHours(floorInBase(d.getHours(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"month\") {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"quarter\") {\n\t\t\t\t\t\t\td.setMonth(3 * floorInBase(d.getMonth() / 3,\n\t\t\t\t\t\t\t\ttickSize));\n\t\t\t\t\t\t} else if (unit == \"year\") {\n\t\t\t\t\t\t\td.setFullYear(floorInBase(d.getFullYear(), tickSize));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// reset smaller components\n\n\t\t\t\t\t\td.setMilliseconds(0);\n\n\t\t\t\t\t\tif (step >= timeUnitSize.minute) {\n\t\t\t\t\t\t\td.setSeconds(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.hour) {\n\t\t\t\t\t\t\td.setMinutes(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.day) {\n\t\t\t\t\t\t\td.setHours(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.day * 4) {\n\t\t\t\t\t\t\td.setDate(1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.month * 2) {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), 3));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.quarter * 2) {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), 6));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.year) {\n\t\t\t\t\t\t\td.setMonth(0);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar carry = 0;\n\t\t\t\t\t\tvar v = Number.NaN;\n\t\t\t\t\t\tvar prev;\n\n\t\t\t\t\t\tdo {\n\n\t\t\t\t\t\t\tprev = v;\n\t\t\t\t\t\t\tv = d.getTime();\n\t\t\t\t\t\t\tticks.push(v);\n\n\t\t\t\t\t\t\tif (unit == \"month\" || unit == \"quarter\") {\n\t\t\t\t\t\t\t\tif (tickSize < 1) {\n\n\t\t\t\t\t\t\t\t\t// a bit complicated - we'll divide the\n\t\t\t\t\t\t\t\t\t// month/quarter up but we need to take\n\t\t\t\t\t\t\t\t\t// care of fractions so we don't end up in\n\t\t\t\t\t\t\t\t\t// the middle of a day\n\n\t\t\t\t\t\t\t\t\td.setDate(1);\n\t\t\t\t\t\t\t\t\tvar start = d.getTime();\n\t\t\t\t\t\t\t\t\td.setMonth(d.getMonth() +\n\t\t\t\t\t\t\t\t\t\t(unit == \"quarter\" ? 3 : 1));\n\t\t\t\t\t\t\t\t\tvar end = d.getTime();\n\t\t\t\t\t\t\t\t\td.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);\n\t\t\t\t\t\t\t\t\tcarry = d.getHours();\n\t\t\t\t\t\t\t\t\td.setHours(0);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\td.setMonth(d.getMonth() +\n\t\t\t\t\t\t\t\t\t\ttickSize * (unit == \"quarter\" ? 3 : 1));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (unit == \"year\") {\n\t\t\t\t\t\t\t\td.setFullYear(d.getFullYear() + tickSize);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\td.setTime(v + step);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} while (v < axis.max && v != prev);\n\n\t\t\t\t\t\treturn ticks;\n\t\t\t\t\t};\n\n\t\t\t\t\taxis.tickFormatter = function (v, axis) {\n\n\t\t\t\t\t\tvar d = dateGenerator(v, axis.options);\n\n\t\t\t\t\t\t// first check global format\n\n\t\t\t\t\t\tif (opts.timeformat != null) {\n\t\t\t\t\t\t\treturn formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// possibly use quarters if quarters are mentioned in\n\t\t\t\t\t\t// any of these places\n\n\t\t\t\t\t\tvar useQuarters = (axis.options.tickSize &&\n\t\t\t\t\t\t\t\taxis.options.tickSize[1] == \"quarter\") ||\n\t\t\t\t\t\t\t(axis.options.minTickSize &&\n\t\t\t\t\t\t\t\taxis.options.minTickSize[1] == \"quarter\");\n\n\t\t\t\t\t\tvar t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];\n\t\t\t\t\t\tvar span = axis.max - axis.min;\n\t\t\t\t\t\tvar suffix = (opts.twelveHourClock) ? \" %p\" : \"\";\n\t\t\t\t\t\tvar hourCode = (opts.twelveHourClock) ? \"%I\" : \"%H\";\n\t\t\t\t\t\tvar fmt;\n\n\t\t\t\t\t\tif (t < timeUnitSize.minute) {\n\t\t\t\t\t\t\tfmt = hourCode + \":%M:%S\" + suffix;\n\t\t\t\t\t\t} else if (t < timeUnitSize.day) {\n\t\t\t\t\t\t\tif (span < 2 * timeUnitSize.day) {\n\t\t\t\t\t\t\t\tfmt = hourCode + \":%M\" + suffix;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"%b %d \" + hourCode + \":%M\" + suffix;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (t < timeUnitSize.month) {\n\t\t\t\t\t\t\tfmt = \"%b %d\";\n\t\t\t\t\t\t} else if ((useQuarters && t < timeUnitSize.quarter) ||\n\t\t\t\t\t\t\t(!useQuarters && t < timeUnitSize.year)) {\n\t\t\t\t\t\t\tif (span < timeUnitSize.year) {\n\t\t\t\t\t\t\t\tfmt = \"%b\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"%b %Y\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (useQuarters && t < timeUnitSize.year) {\n\t\t\t\t\t\t\tif (span < timeUnitSize.year) {\n\t\t\t\t\t\t\t\tfmt = \"Q%q\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"Q%q %Y\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfmt = \"%Y\";\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar rt = formatDate(d, fmt, opts.monthNames, opts.dayNames);\n\n\t\t\t\t\t\treturn rt;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t$.plot.plugins.push({\n\t\tinit: init,\n\t\toptions: options,\n\t\tname: 'time',\n\t\tversion: '1.0'\n\t});\n\n\t// Time-axis support used to be in Flot core, which exposed the\n\t// formatDate function on the plot object.  Various plugins depend\n\t// on the function, so we need to re-expose it here.\n\n\t$.plot.formatDate = formatDate;\n\t$.plot.dateGenerator = dateGenerator;\n\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/footable/css/footable.core.css",
    "content": "@font-face {\n  font-family: 'footable';\n  src: url('fonts/footable.eot');\n  src: url('fonts/footable.eot?#iefix') format('embedded-opentype'), url('fonts/footable.woff') format('woff'), url('fonts/footable.ttf') format('truetype'), url('fonts/footable.svg#footable') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n  @font-face {\n    font-family: 'footable';\n    src: url('fonts/footable.svg#footable') format('svg');\n    font-weight: normal;\n    font-style: normal;\n  }\n}\n.footable {\n  width: 100%;\n  /** SORTING **/\n\n  /** PAGINATION **/\n\n}\n.footable.breakpoint > tbody > tr.footable-detail-show > td {\n  border-bottom: none;\n}\n.footable.breakpoint > tbody > tr.footable-detail-show > td > span.footable-toggle:before {\n  content: \"\\e001\";\n}\n.footable.breakpoint > tbody > tr:hover:not(.footable-row-detail) {\n  cursor: pointer;\n}\n.footable.breakpoint > tbody > tr > td.footable-cell-detail {\n  background: #eee;\n  border-top: none;\n}\n.footable.breakpoint > tbody > tr > td > span.footable-toggle {\n  display: inline-block;\n  font-family: 'footable';\n  speak: none;\n  font-style: normal;\n  font-weight: normal;\n  font-variant: normal;\n  text-transform: none;\n  -webkit-font-smoothing: antialiased;\n  padding-right: 10px;\n  color: #777;\n}\n.footable.breakpoint > tbody > tr > td > span.footable-toggle:before {\n  content: \"\\e000\";\n}\n.footable.breakpoint.toggle-circle > tbody > tr.footable-detail-show > td > span.footable-toggle:before {\n  content: \"\\e005\";\n}\n.footable.breakpoint.toggle-circle > tbody > tr > td > span.footable-toggle:before {\n  content: \"\\e004\";\n}\n.footable.breakpoint.toggle-circle-filled > tbody > tr.footable-detail-show > td > span.footable-toggle:before {\n  content: \"\\e003\";\n}\n.footable.breakpoint.toggle-circle-filled > tbody > tr > td > span.footable-toggle:before {\n  content: \"\\e002\";\n}\n.footable.breakpoint.toggle-square > tbody > tr.footable-detail-show > td > span.footable-toggle:before {\n  content: \"\\e007\";\n}\n.footable.breakpoint.toggle-square > tbody > tr > td > span.footable-toggle:before {\n  content: \"\\e006\";\n}\n.footable.breakpoint.toggle-square-filled > tbody > tr.footable-detail-show > td > span.footable-toggle:before {\n  content: \"\\e009\";\n}\n.footable.breakpoint.toggle-square-filled > tbody > tr > td > span.footable-toggle:before {\n  content: \"\\e008\";\n}\n.footable.breakpoint.toggle-arrow > tbody > tr.footable-detail-show > td > span.footable-toggle:before {\n  content: \"\\e00f\";\n}\n.footable.breakpoint.toggle-arrow > tbody > tr > td > span.footable-toggle:before {\n  content: \"\\e011\";\n}\n.footable.breakpoint.toggle-arrow-small > tbody > tr.footable-detail-show > td > span.footable-toggle:before {\n  content: \"\\e013\";\n}\n.footable.breakpoint.toggle-arrow-small > tbody > tr > td > span.footable-toggle:before {\n  content: \"\\e015\";\n}\n.footable.breakpoint.toggle-arrow-circle > tbody > tr.footable-detail-show > td > span.footable-toggle:before {\n  content: \"\\e01b\";\n}\n.footable.breakpoint.toggle-arrow-circle > tbody > tr > td > span.footable-toggle:before {\n  content: \"\\e01d\";\n}\n.footable.breakpoint.toggle-arrow-circle-filled > tbody > tr.footable-detail-show > td > span.footable-toggle:before {\n  content: \"\\e00b\";\n}\n.footable.breakpoint.toggle-arrow-circle-filled > tbody > tr > td > span.footable-toggle:before {\n  content: \"\\e00d\";\n}\n.footable.breakpoint.toggle-arrow-tiny > tbody > tr.footable-detail-show > td > span.footable-toggle:before {\n  content: \"\\e01f\";\n}\n.footable.breakpoint.toggle-arrow-tiny > tbody > tr > td > span.footable-toggle:before {\n  content: \"\\e021\";\n}\n.footable.breakpoint.toggle-arrow-alt > tbody > tr.footable-detail-show > td > span.footable-toggle:before {\n  content: \"\\e017\";\n}\n.footable.breakpoint.toggle-arrow-alt > tbody > tr > td > span.footable-toggle:before {\n  content: \"\\e019\";\n}\n.footable.breakpoint.toggle-medium > tbody > tr > td > span.footable-toggle {\n  font-size: 18px;\n}\n.footable.breakpoint.toggle-large > tbody > tr > td > span.footable-toggle {\n  font-size: 24px;\n}\n.footable > thead > tr > th {\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n  -khtml-user-select: none;\n  -moz-user-select: -moz-none;\n  -ms-user-select: none;\n  user-select: none;\n}\n.footable > thead > tr > th.footable-sortable:hover {\n  cursor: pointer;\n}\n.footable > thead > tr > th.footable-sorted > span.footable-sort-indicator:before {\n  content: \"\\e013\";\n}\n.footable > thead > tr > th.footable-sorted-desc > span.footable-sort-indicator:before {\n  content: \"\\e012\";\n}\n.footable > thead > tr > th > span.footable-sort-indicator {\n  display: inline-block;\n  font-family: 'footable';\n  speak: none;\n  font-style: normal;\n  font-weight: normal;\n  font-variant: normal;\n  text-transform: none;\n  -webkit-font-smoothing: antialiased;\n  padding-left: 5px;\n}\n.footable > thead > tr > th > span.footable-sort-indicator:before {\n  content: \"\\e022\";\n}\n.footable > tfoot .pagination {\n  margin: 0;\n}\n.footable.no-paging .hide-if-no-paging {\n  display: none;\n}\n.footable-row-detail{\n  background-color:#f5f5f5\n}\n.footable-row-detail-inner {\n  display: table;  \n}\n.footable-row-detail-row {\n  display: table-row;\n  line-height: 1.5em;\n}\n.footable-row-detail-group {\n  display: block;\n  line-height: 2em;\n  font-size: 1.2em;\n  font-weight: bold;\n}\n.footable-row-detail-name {\n  display: table-cell;\n  font-weight: 500;\n  padding-right: 1em;\n  padding-bottom: 5px;\n}\n.footable-row-detail-value {\n  display: table-cell;\n}\n.footable-odd {\n  background-color: #f7f7f7;\n}\n"
  },
  {
    "path": "static/assets/plugins/jquery-datatables-editable/dataTables.bootstrap.js",
    "content": "/*! DataTables Bootstrap 3 integration\n * ©2011-2014 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and\n * DataTables 1.10 or newer.\n *\n * This file sets the defaults and adds options to DataTables to style its\n * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap\n * for further information.\n */\n(function(window, document, undefined){\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\n\n/* Set the defaults for DataTables initialisation */\n$.extend( true, DataTable.defaults, {\n\tdom:\n\t\t\"<'row'<'col-sm-6'l><'col-sm-6'f>>\" +\n\t\t\"<'row'<'col-sm-12'tr>>\" +\n\t\t\"<'row'<'col-sm-6'i><'col-sm-6'p>>\",\n\trenderer: 'bootstrap'\n} );\n\n\n/* Default class modification */\n$.extend( DataTable.ext.classes, {\n\tsWrapper:      \"dataTables_wrapper form-inline dt-bootstrap\",\n\tsFilterInput:  \"form-control input-sm\",\n\tsLengthSelect: \"form-control input-sm\"\n} );\n\n\n/* Bootstrap paging button renderer */\nDataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {\n\tvar api     = new DataTable.Api( settings );\n\tvar classes = settings.oClasses;\n\tvar lang    = settings.oLanguage.oPaginate;\n\tvar btnDisplay, btnClass;\n\n\tvar attach = function( container, buttons ) {\n\t\tvar i, ien, node, button;\n\t\tvar clickHandler = function ( e ) {\n\t\t\te.preventDefault();\n\t\t\tif ( !$(e.currentTarget).hasClass('disabled') ) {\n\t\t\t\tapi.page( e.data.action ).draw( false );\n\t\t\t}\n\t\t};\n\n\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\tbutton = buttons[i];\n\n\t\t\tif ( $.isArray( button ) ) {\n\t\t\t\tattach( container, button );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbtnDisplay = '';\n\t\t\t\tbtnClass = '';\n\n\t\t\t\tswitch ( button ) {\n\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\tbtnDisplay = '&hellip;';\n\t\t\t\t\t\tbtnClass = 'disabled';\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'first':\n\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'next':\n\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'last':\n\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t'active' : '';\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( btnDisplay ) {\n\t\t\t\t\tnode = $('<li>', {\n\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t'tabindex': settings.iTabIndex,\n\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.append( $('<a>', {\n\t\t\t\t\t\t\t\t'href': '#'\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.html( btnDisplay )\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.appendTo( container );\n\n\t\t\t\t\tsettings.oApi._fnBindAction(\n\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tattach(\n\t\t$(host).empty().html('<ul class=\"pagination\"/>').children('ul'),\n\t\tbuttons\n\t);\n};\n\n\n/*\n * TableTools Bootstrap compatibility\n * Required TableTools 2.1+\n */\nif ( DataTable.TableTools ) {\n\t// Set the classes that TableTools uses to something suitable for Bootstrap\n\t$.extend( true, DataTable.TableTools.classes, {\n\t\t\"container\": \"DTTT btn-group\",\n\t\t\"buttons\": {\n\t\t\t\"normal\": \"btn btn-default\",\n\t\t\t\"disabled\": \"disabled\"\n\t\t},\n\t\t\"collection\": {\n\t\t\t\"container\": \"DTTT_dropdown dropdown-menu\",\n\t\t\t\"buttons\": {\n\t\t\t\t\"normal\": \"\",\n\t\t\t\t\"disabled\": \"disabled\"\n\t\t\t}\n\t\t},\n\t\t\"print\": {\n\t\t\t\"info\": \"DTTT_print_info\"\n\t\t},\n\t\t\"select\": {\n\t\t\t\"row\": \"active\"\n\t\t}\n\t} );\n\n\t// Have the collection use a bootstrap compatible drop down\n\t$.extend( true, DataTable.TableTools.DEFAULTS.oTags, {\n\t\t\"collection\": {\n\t\t\t\"container\": \"ul\",\n\t\t\t\"button\": \"li\",\n\t\t\t\"liner\": \"a\"\n\t\t}\n\t} );\n}\n\n}; // /factory\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n})(window, document);\n\n"
  },
  {
    "path": "static/assets/plugins/jquery-datatables-editable/datatables.css",
    "content": "div.dataTables_length label {\n\tfont-weight: normal;\n\ttext-align: left;\n\twhite-space: nowrap;\n}\n\ndiv.dataTables_length select {\n\twidth: 75px;\n\tdisplay: inline-block;\n}\n\ndiv.dataTables_filter {\n\ttext-align: right;\n}\n\ndiv.dataTables_filter label {\n\tfont-weight: normal;\n\twhite-space: nowrap;\n\ttext-align: left;\n}\n\ndiv.dataTables_filter input {\n\tmargin-left: 0.5em;\n\tdisplay: inline-block;\n}\n\ndiv.dataTables_info {\n\tpadding-top: 8px;\n\twhite-space: nowrap;\n}\n\ndiv.dataTables_paginate {\n\tmargin: 0;\n\twhite-space: nowrap;\n\ttext-align: right;\n}\n\ndiv.dataTables_paginate ul.pagination {\n\tmargin: 2px 0;\n\twhite-space: nowrap;\n}\n\n@media screen and (max-width: 767px) {\n\tdiv.dataTables_length,\n\tdiv.dataTables_filter,\n\tdiv.dataTables_info,\n\tdiv.dataTables_paginate {\n\t\ttext-align: center;\n\t}\n}\n\n\ntable.dataTable td,\ntable.dataTable th {\n\t-webkit-box-sizing: content-box;\n\t-moz-box-sizing: content-box;\n\tbox-sizing: content-box;\n}\n\n\ntable.dataTable {\n\tclear: both;\n\tmargin-top: 6px !important;\n\tmargin-bottom: 6px !important;\n\tmax-width: none !important;\n}\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\tcursor: pointer;\n\tposition: relative;\n}\n\ntable.dataTable thead .sorting:after,\ntable.dataTable thead .sorting_asc:after,\ntable.dataTable thead .sorting_desc:after {\n\tposition: absolute;\n\ttop: 8px;\n\tright: 8px;\n\tdisplay: block;\n\tfont-family: 'Glyphicons Halflings';\n\topacity: 0.5;\n}\ntable.dataTable thead .sorting:after {\n\topacity: 0.2;\n\tcontent: \"\\e150\"; /* sort */\n}\ntable.dataTable thead .sorting_asc:after {\n\tcontent: \"\\e155\"; /* sort-by-attributes */\n}\ntable.dataTable thead .sorting_desc:after {\n\tcontent: \"\\e156\"; /* sort-by-attributes-alt */\n}\n\ntable.dataTable thead .sorting_asc_disabled:after,\ntable.dataTable thead .sorting_desc_disabled:after {\n\tcolor: #eee;\n}\n\ntable.dataTable thead > tr > th {\n\tpadding-left: 8px;\n\tpadding-right: 30px;\n}\n\ntable.dataTable th:active {\n\toutline: none;\n}\n\n/* Scrolling */\ndiv.dataTables_scrollHead table {\n\tmargin-bottom: 0 !important;\n\tborder-bottom-left-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\ndiv.dataTables_scrollHead table thead tr:last-child th:first-child,\ndiv.dataTables_scrollHead table thead tr:last-child td:first-child {\n\tborder-bottom-left-radius: 0 !important;\n\tborder-bottom-right-radius: 0 !important;\n}\n\ndiv.dataTables_scrollBody table {\n\tborder-top: none;\n\tmargin-top: 0 !important;\n\tmargin-bottom: 0 !important;\n}\n\ndiv.dataTables_scrollBody tbody tr:first-child th,\ndiv.dataTables_scrollBody tbody tr:first-child td {\n\tborder-top: none;\n}\n\ndiv.dataTables_scrollFoot table {\n\tmargin-top: 0 !important;\n\tborder-top: none;\n}\n\n/* Frustratingly the border-collapse:collapse used by Bootstrap makes the column\n   width calculations when using scrolling impossible to align columns. We have\n   to use separate\n */\ntable.table-bordered.dataTable {\n\tborder-collapse: separate !important;\n}\ntable.table-bordered thead th,\ntable.table-bordered thead td {\n\tborder-left-width: 0;\n\tborder-top-width: 0;\n}\ntable.table-bordered tbody th,\ntable.table-bordered tbody td {\n\tborder-left-width: 0;\n\tborder-bottom-width: 0;\n}\ntable.table-bordered th:last-child,\ntable.table-bordered td:last-child {\n\tborder-right-width: 0;\n}\ndiv.dataTables_scrollHead table.table-bordered {\n\tborder-bottom-width: 0;\n}\n\n\n\n\n/*\n * TableTools styles\n */\n.table.dataTable tbody tr.active td,\n.table.dataTable tbody tr.active th {\n\tbackground-color: #08C;\n\tcolor: white;\n}\n\n.table.dataTable tbody tr.active:hover td,\n.table.dataTable tbody tr.active:hover th {\n\tbackground-color: #0075b0 !important;\n}\n\n.table.dataTable tbody tr.active th > a,\n.table.dataTable tbody tr.active td > a {\n\tcolor: white;\n}\n\n.table-striped.dataTable tbody tr.active:nth-child(odd) td,\n.table-striped.dataTable tbody tr.active:nth-child(odd) th {\n\tbackground-color: #017ebc;\n}\n\ntable.DTTT_selectable tbody tr {\n\tcursor: pointer;\n}\n\ndiv.DTTT .btn:hover {\n\ttext-decoration: none !important;\n}\n\nul.DTTT_dropdown.dropdown-menu {\n  z-index: 2003;\n}\n\nul.DTTT_dropdown.dropdown-menu a {\n\tcolor: #333 !important; /* needed only when demo_page.css is included */\n}\n\nul.DTTT_dropdown.dropdown-menu li {\n\tposition: relative;\n}\n\nul.DTTT_dropdown.dropdown-menu li:hover a {\n\tbackground-color: #0088cc;\n\tcolor: white !important;\n}\n\ndiv.DTTT_collection_background {\n\tz-index: 2002;\t\n}\n\n/* TableTools information display */\ndiv.DTTT_print_info {\n\tposition: fixed;\n\ttop: 50%;\n\tleft: 50%;\n\twidth: 400px;\n\theight: 150px;\n\tmargin-left: -200px;\n\tmargin-top: -75px;\n\ttext-align: center;\n\tcolor: #333;\n\tpadding: 10px 30px;\n\topacity: 0.95;\n\n\tbackground-color: white;\n\tborder: 1px solid rgba(0, 0, 0, 0.2);\n\tborder-radius: 6px;\n\t\n\t-webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);\n\t        box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);\n}\n\ndiv.DTTT_print_info h6 {\n\tfont-weight: normal;\n\tfont-size: 28px;\n\tline-height: 28px;\n\tmargin: 1em;\n}\n\ndiv.DTTT_print_info p {\n\tfont-size: 14px;\n\tline-height: 20px;\n}\n\ndiv.dataTables_processing {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    width: 100%;\n    height: 60px;\n    margin-left: -50%;\n    margin-top: -25px;\n    padding-top: 20px;\n    padding-bottom: 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\n\n\n/*\n * FixedColumns styles\n */\ndiv.DTFC_LeftHeadWrapper table,\ndiv.DTFC_LeftFootWrapper table,\ndiv.DTFC_RightHeadWrapper table,\ndiv.DTFC_RightFootWrapper table,\ntable.DTFC_Cloned tr.even {\n    background-color: white;\n    margin-bottom: 0;\n}\n \ndiv.DTFC_RightHeadWrapper table ,\ndiv.DTFC_LeftHeadWrapper table {\n\tborder-bottom: none !important;\n    margin-bottom: 0 !important;\n    border-top-right-radius: 0 !important;\n    border-bottom-left-radius: 0 !important;\n    border-bottom-right-radius: 0 !important;\n}\n \ndiv.DTFC_RightHeadWrapper table thead tr:last-child th:first-child,\ndiv.DTFC_RightHeadWrapper table thead tr:last-child td:first-child,\ndiv.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child,\ndiv.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child {\n    border-bottom-left-radius: 0 !important;\n    border-bottom-right-radius: 0 !important;\n}\n \ndiv.DTFC_RightBodyWrapper table,\ndiv.DTFC_LeftBodyWrapper table {\n    border-top: none;\n    margin: 0 !important;\n}\n \ndiv.DTFC_RightBodyWrapper tbody tr:first-child th,\ndiv.DTFC_RightBodyWrapper tbody tr:first-child td,\ndiv.DTFC_LeftBodyWrapper tbody tr:first-child th,\ndiv.DTFC_LeftBodyWrapper tbody tr:first-child td {\n    border-top: none;\n}\n \ndiv.DTFC_RightFootWrapper table,\ndiv.DTFC_LeftFootWrapper table {\n    border-top: none;\n    margin-top: 0 !important;\n}\n\n\n/*\n * FixedHeader styles\n */\ndiv.FixedHeader_Cloned table {\n\tmargin: 0 !important\n}\n"
  },
  {
    "path": "static/assets/plugins/jquery-datatables-editable/jquery.dataTables.js",
    "content": "/*! DataTables 1.10.7\n * ©2008-2014 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary     DataTables\n * @description Paginate, search and order HTML tables\n * @version     1.10.7\n * @file        jquery.dataTables.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2008-2014 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,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnScrollBarWidth,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/\n\n(/** @lends <global> */function( window, document, undefined ) {\n\n(function( factory ) {\n\t\"use strict\";\n\n\tif ( typeof define === 'function' && define.amd ) {\n\t\t// Define as an AMD module if possible\n\t\tdefine( 'datatables', ['jquery'], factory );\n\t}\n    else if ( typeof exports === 'object' ) {\n        // Node/CommonJS\n        module.exports = factory( require( 'jquery' ) );\n    }\n\telse if ( jQuery && !jQuery.fn.dataTable ) {\n\t\t// Define using browser globals otherwise\n\t\t// Prevent multiple instantiations if the script is loaded twice\n\t\tfactory( jQuery );\n\t}\n}\n(/** @lends <global> */function( $ ) {\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;\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/**\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// 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\tvar browser = settings.oBrowser;\n\t\n\t\t// Scrolling feature / quirks detection\n\t\tvar n = $('<div/>')\n\t\t\t.css( {\n\t\t\t\tposition: 'absolute',\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\theight: 1,\n\t\t\t\twidth: 1,\n\t\t\t\toverflow: 'hidden'\n\t\t\t} )\n\t\t\t.append(\n\t\t\t\t$('<div/>')\n\t\t\t\t\t.css( {\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: 1,\n\t\t\t\t\t\tleft: 1,\n\t\t\t\t\t\twidth: 100,\n\t\t\t\t\t\toverflow: 'scroll'\n\t\t\t\t\t} )\n\t\t\t\t\t.append(\n\t\t\t\t\t\t$('<div class=\"test\"/>')\n\t\t\t\t\t\t\t.css( {\n\t\t\t\t\t\t\t\twidth: '100%',\n\t\t\t\t\t\t\t\theight: 10\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t)\n\t\t\t)\n\t\t\t.appendTo( 'body' );\n\t\n\t\tvar test = n.find('.test');\n\t\n\t\t// IE6/7 will oversize a width 100% element inside a scrolling element, to\n\t\t// include the width of the scrollbar, while other browsers ensure the inner\n\t\t// element is contained without forcing scrolling\n\t\tbrowser.bScrollOversize = test[0].offsetWidth === 100;\n\t\n\t\t// In rtl text layout, some browsers (most, but not all) will place the\n\t\t// scrollbar on the left, rather than the right.\n\t\tbrowser.bScrollbarLeft = Math.round( test.offset().left ) !== 1;\n\t\n\t\tn.remove();\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\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\treturn _fnGetColumns( oSettings, 'bVisible' ).length;\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} );\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\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\n\t\t{\n\t\t\t// When working with a row, the data source object must be populated. In\n\t\t\t// all other cases, the data source object is already populated, so we\n\t\t\t// don't overwrite it, which might break bindings etc\n\t\t\tif ( nTr ) {\n\t\t\t\t_fnSetCellData( oSettings, iRow, i, _fnGetCellData( oSettings, iRow, i ) );\n\t\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\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, 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, we can use default column data */\n\t\tif ( (cellData === rowData || cellData === null) && defaultContent !== null ) {\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\tfor ( var j=0, jLen=data.length ; j<jLen ; j++ ) {\n\t\t\t\t\t\t\t\tout.push( fetchData( data[j], type, innerSrc ) );\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\tfor ( var j=0, jLen=val.length ; j<jLen ; j++ )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\to = {};\n\t\t\t\t\t\t\tsetData( o, val[j], innerSrc );\n\t\t\t\t\t\t\tdata[ a[i] ].push( o );\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}\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( 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 || objectRead ? {} : [];\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\t\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\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( 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\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{\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} DataTables row object for the row to be modified\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnRowAttributes( row )\n\t{\n\t\tvar tr = row.nTr;\n\t\tvar data = row._aData;\n\t\n\t\tif ( tr ) {\n\t\t\tif ( data.DT_RowId ) {\n\t\t\t\ttr.id = data.DT_RowId;\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.html() ) {\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}\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\tdisplayRows.push.apply( 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\tfunction _fnEscapeRegex ( sVal )\n\t{\n\t\treturn sVal.replace( _re_escape_regex, '\\\\$1' );\n\t}\n\t\n\t\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\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// 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' ) {\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// On an Ajax load we now have data and therefore want to apply the column\n\t\t// sizing\n\t\tif ( json ) {\n\t\t\t_fnAdjustColumnSizing( settings );\n\t\t}\n\t\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\t// This is fairly messy, but with x scrolling enabled, if the table has a\n\t\t// width attribute, regardless of any width applied using the column width\n\t\t// options, the browser will shrink or grow the table as needed to fit into\n\t\t// that 100%. That would make the width options useless. So we remove it.\n\t\t// This is okay, under the assumption that width:100% is applied to the\n\t\t// table in CSS (it is in the default stylesheet) which will set the table\n\t\t// width as appropriate (the attribute and css behave differently...)\n\t\tif ( scroll.sX && table.attr('width') === '100%' ) {\n\t\t\ttable.removeAttr('width');\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\toverflow: 'auto',\n\t\t\t\t\t\theight: size( scrollY ),\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\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\theaderTrgEls, footerTrgEls,\n\t\t\theaderSrcEls, footerSrcEls,\n\t\t\theaderCopy, footerCopy,\n\t\t\theaderWidths=[], footerWidths=[],\n\t\t\theaderContent=[],\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/*\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\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\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\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// If scroll collapse is enabled, when we put the headers back into the body for sizing, we\n\t\t// will end up forcing the scrollbar to appear, making our measurements wrong for when we\n\t\t// then hide it (end of this function), so add the header height to the body scroller.\n\t\tif ( scroll.bCollapse && scrollY !== \"\" ) {\n\t\t\tdivBodyStyle.height = (divBody[0].offsetHeight + header[0].offsetHeight)+\"px\";\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\t}\n\t\telse\n\t\t{\n\t\t\t// x scrolling\n\t\t\tif ( scrollXInner !== \"\" ) {\n\t\t\t\t// x scroll inner has been given - use it\n\t\t\t\ttableStyle.width = _fnStringToCss(scrollXInner);\n\t\t\t}\n\t\t\telse if ( sanityWidth == divBody.width() && divBody.height() < table.height() ) {\n\t\t\t\t// There is y-scrolling - try to take account of the y scroll bar\n\t\t\t\ttableStyle.width = _fnStringToCss( sanityWidth-barWidth );\n\t\t\t\tif ( table.outerWidth() > sanityWidth-barWidth ) {\n\t\t\t\t\t// Not possible to take account of it\n\t\t\t\t\ttableStyle.width = _fnStringToCss( sanityWidth );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// When all else fails\n\t\t\t\ttableStyle.width = _fnStringToCss( sanityWidth );\n\t\t\t}\n\t\t}\n\t\n\t\t// Recalculate the sanity width - now that we've applied the required width,\n\t\t// before it was a temporary variable. This is required because the column\n\t\t// width calculation is done before this table DOM is created.\n\t\tsanityWidth = table.outerWidth();\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\tnToSize.style.width = headerWidths[i];\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\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 = \"\";\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\tif ( scrollY && scroll.bCollapse ) {\n\t\t\tdivBodyStyle.height = _fnStringToCss( scrollY );\n\t\n\t\t\tvar iExtra = (scrollX && tableEl.offsetWidth > divBodyEl.offsetWidth) ?\n\t\t\t\tbarWidth :\n\t\t\t\t0;\n\t\n\t\t\tif ( tableEl.offsetHeight < divBodyEl.offsetHeight ) {\n\t\t\t\tdivBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+iExtra );\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/* 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\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 ( ! userInputs && ! scrollX && ! scrollY &&\n\t\t    columnCount == _fnVisbleColumns( oSettings ) &&\n\t\t\tcolumnCount == headerCells.length\n\t\t) {\n\t\t\tfor ( i=0 ; i<columnCount ; i++ ) {\n\t\t\t\tcolumns[i].sWidth = _fnStringToCss( headerCells.eq(i).width() );\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// 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\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// Table has been built, attach to the document so we can work with it\n\t\t\ttmpTable.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\n\t\t\t\tif ( tmpTable.width() < tableContainer.offsetWidth ) {\n\t\t\t\t\ttmpTable.width( tableContainer.offsetWidth );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( scrollY ) {\n\t\t\t\ttmpTable.width( tableContainer.offsetWidth );\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// Take into account the y scrollbar\n\t\t\t_fnScrollingWidthAdjust( oSettings, tmpTable[0] );\n\t\n\t\t\t// Browsers need a bit of a hand when a width is assigned to any columns\n\t\t\t// when x-scrolling as they tend to collapse the table to the min-width,\n\t\t\t// even if we sent the column widths. So we need to keep track of what\n\t\t\t// the table width should be by summing the user given values, and the\n\t\t\t// automatic values\n\t\t\tif ( scrollX )\n\t\t\t{\n\t\t\t\tvar total = 0;\n\t\n\t\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\t\t\tcolumn = columns[ visibleColumns[i] ];\n\t\t\t\t\touterWidth = $(headerCells[i]).outerWidth();\n\t\n\t\t\t\t\ttotal += column.sWidthOrig === null ?\n\t\t\t\t\t\touterWidth :\n\t\t\t\t\t\tparseInt( column.sWidth, 10 ) + outerWidth - $(headerCells[i]).width();\n\t\t\t\t}\n\t\n\t\t\t\ttmpTable.width( _fnStringToCss( total ) );\n\t\t\t\ttable.style.width = _fnStringToCss( total );\n\t\t\t}\n\t\n\t\t\t// Get the width of each column in the constructed table\n\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\t\tcolumn = columns[ visibleColumns[i] ];\n\t\t\t\twidth = $(headerCells[i]).width();\n\t\n\t\t\t\tif ( width ) {\n\t\t\t\t\tcolumn.sWidth = _fnStringToCss( width );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\ttable.style.width = _fnStringToCss( tmpTable.css('width') );\n\t\n\t\t\t// Finished with the table - ditch it\n\t\t\ttmpTable.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 ( oSettings.oBrowser.bScrollOversize ) {\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\tfunction _fnThrottle( fn, freq ) {\n\t\tvar\n\t\t\tfrequency = freq !== undefined ? freq : 200,\n\t\t\tlast,\n\t\t\ttimer;\n\t\n\t\treturn function () {\n\t\t\tvar\n\t\t\t\tthat = this,\n\t\t\t\tnow  = +new Date(),\n\t\t\t\targs = arguments;\n\t\n\t\t\tif ( last && now < last + frequency ) {\n\t\t\t\tclearTimeout( timer );\n\t\n\t\t\t\ttimer = setTimeout( function () {\n\t\t\t\t\tlast = undefined;\n\t\t\t\t\tfn.apply( that, args );\n\t\t\t\t}, frequency );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tlast = now;\n\t\t\t\tfn.apply( that, args );\n\t\t\t}\n\t\t};\n\t}\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 * Adjust a table's width to take account of vertical scroll bar\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {node} n table node\n\t *  @memberof DataTable#oApi\n\t */\n\t\n\tfunction _fnScrollingWidthAdjust ( settings, n )\n\t{\n\t\tvar scroll = settings.oScroll;\n\t\n\t\tif ( scroll.sX || scroll.sY ) {\n\t\t\t// When y-scrolling only, we want to remove the width of the scroll bar\n\t\t\t// so the table + scroll bar will fit into the area available, otherwise\n\t\t\t// we fix the table at its current size with no adjustment\n\t\t\tvar correction = ! scroll.sX ? scroll.iBarWidth : 0;\n\t\t\tn.style.width = _fnStringToCss( $(n).outerWidth() - correction );\n\t\t}\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\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\t * Get the width of a scroll bar in this browser being used\n\t *  @returns {int} width in pixels\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnScrollBarWidth ()\n\t{\n\t\t// On first run a static variable is set, since this is only needed once.\n\t\t// Subsequent runs will just use the previously calculated value\n\t\tvar width = DataTable.__scrollbarWidth;\n\t\n\t\tif ( width === undefined ) {\n\t\t\tvar sizer = $('<p/>').css( {\n\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0,\n\t\t\t\t\twidth: '100%',\n\t\t\t\t\theight: 150,\n\t\t\t\t\tpadding: 0,\n\t\t\t\t\toverflow: 'scroll',\n\t\t\t\t\tvisibility: 'hidden'\n\t\t\t\t} )\n\t\t\t\t.appendTo('body');\n\t\n\t\t\twidth = sizer[0].offsetWidth - sizer[0].clientWidth;\n\t\t\tDataTable.__scrollbarWidth = width;\n\t\n\t\t\tsizer.remove();\n\t\t}\n\t\n\t\treturn width;\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\tnestedSort.push.apply( 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!==null ? '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\t_fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );\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\tDataTable = 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[ \"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\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/* Calculate the scroll bar width and cache it for use later on */\n\t\t\tif ( oSettings.oScroll.sX !== \"\" || oSettings.oScroll.sY !== \"\" )\n\t\t\t{\n\t\t\t\toSettings.oScroll.iBarWidth = _fnScrollBarWidth();\n\t\t\t}\n\t\t\tif ( oSettings.oScroll.sX === true ) { // Easy initialisation of x-scrolling\n\t\t\t\toSettings.oScroll.sX = '100%';\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$.each( _fnGetRowElements( oSettings, rowOne[0] ).cells, 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/* Browser support detection */\n\t\t\t_fnBrowserDetect( oSettings );\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/**\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.push.apply( settings, 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\tthis.push.apply( this, data.toArray ? data.toArray() : 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_Api.prototype = /** @lends DataTables.Api */{\n\t\tany: function ()\n\t\t{\n\t\t\treturn this.flatten().length !== 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\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 * @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( 'draw()', function ( resetPaging ) {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnReDraw( settings, resetPaging===false );\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._iDisplayLength,\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};\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// Trigger xhr\n\t\t\t_fnProcessingDisplay( settings, true );\n\t\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.push.apply( out, 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 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 ( $.inArray( sel, nodes ) !== -1 ) {\n\t\t\t\t\treturn [ sel._DT_RowIndex ]; // sel is a TR node that is in the table\n\t\t\t\t\t                             // and DataTables adds a prop for fast lookup\n\t\t\t\t}\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().remove()', 'row().remove()', function () {\n\t\tvar that = this;\n\t\n\t\treturn this.iterator( 'row', function ( settings, row, thatIdx ) {\n\t\t\tvar data = settings.aoData;\n\t\n\t\t\tdata.splice( row, 1 );\n\t\n\t\t\t// Update the _DT_RowIndex parameter on all rows in the table\n\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\tif ( data[i].nTr !== null ) {\n\t\t\t\t\tdata[i].nTr._DT_RowIndex = i;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// Remove the target row from the search array\n\t\t\tvar displayIndex = $.inArray( row, settings.aiDisplay );\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\t} );\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\tmodRows.push.apply( modRows, newRows.toArray() );\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._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\t\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\t\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\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// jQuery selector on the TH elements for the columns\n\t\t\t\treturn $( nodes )\n\t\t\t\t\t.filter( s )\n\t\t\t\t\t.map( function () {\n\t\t\t\t\t\treturn $.inArray( this, nodes ); // `nodes` is column index complete and in order\n\t\t\t\t\t} )\n\t\t\t\t\t.toArray();\n\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, recalc ) {\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\tif ( recalc === undefined || recalc ) {\n\t\t\t// Automatically adjust column sizing\n\t\t\t_fnAdjustColumnSizing( settings );\n\t\n\t\t\t// Realign columns for scrolling\n\t\t\tif ( settings.oScroll.sX || settings.oScroll.sY ) {\n\t\t\t\t_fnScrollDraw( settings );\n\t\t\t}\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis] );\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\treturn 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, calc );\n\t\t} );\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\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 = settings.aoData[ 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\treturn allCells\n\t\t\t\t.filter( s )\n\t\t\t\t.map( function (i, el) {\n\t\t\t\t\trow = el.parentNode._DT_RowIndex;\n\t\n\t\t\t\t\treturn {\n\t\t\t\t\t\trow: row,\n\t\t\t\t\t\tcolumn: $.inArray( el, data[ row ].anCells )\n\t\t\t\t\t};\n\t\t\t\t} )\n\t\t\t\t.toArray();\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 cells = settings.aoData[ row ].anCells;\n\t\t\treturn cells ?\n\t\t\t\tcells[ 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 ( ! $.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// 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\treturn $.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\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: _fnThrottle,\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} sVal string to escape\n\t\t *  @returns {string} escaped string\n\t\t */\n\t\tescapeRegex: _fnEscapeRegex\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\t// Remove the DataTables generated nodes, events and classes\n\t\t\tjqTable.detach();\n\t\t\tjqWrapper.detach();\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\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\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// Restore the width of the original table - was read from the style property,\n\t\t\t// so we can restore directly to that\n\t\t\tjqTable\n\t\t\t\t.css( 'width', settings.sDestroyWidth )\n\t\t\t\t.removeClass( classes.sTable );\n\t\n\t\t\t// If the were originally stripe classes - then we add them back here.\n\t\t\t// Note this is not fool proof (for example if not all rows had stripe\n\t\t\t// classes - but it's a good effort without getting carried away\n\t\t\tien = settings.asDestroyStripes.length;\n\t\n\t\t\tif ( ien ) {\n\t\t\t\tjqTbody.children().each( function (i) {\n\t\t\t\t\t$(this).addClass( settings.asDestroyStripes[i % ien] );\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\treturn this.iterator( type, function ( settings, idx, idx2 ) {\n\t\t\t\t// idx2 is undefined for rows and columns.\n\t\t\t\tfn.call( new _Api( settings )[ type ]( idx, idx2 ) );\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.7\";\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\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_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\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 * 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\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 * 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\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 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 = '';\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 ) {\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'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 = $(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\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 4 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 *\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 ) {\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\td = Math.abs( parseFloat( d ) );\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}\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_fnScrollingWidthAdjust: _fnScrollingWidthAdjust,\n\t\t_fnGetWidestNode: _fnGetWidestNode,\n\t\t_fnGetMaxLenString: _fnGetMaxLenString,\n\t\t_fnStringToCss: _fnStringToCss,\n\t\t_fnScrollBarWidth: _fnScrollBarWidth,\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// 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\n}(window, document));\n\n"
  },
  {
    "path": "static/assets/plugins/jquery-knob/excanvas.js",
    "content": "// Copyright 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// Known Issues:\n//\n// * Patterns are not implemented.\n// * Radial gradient are not implemented. The VML version of these look very\n//   different from the canvas one.\n// * Clipping paths are not implemented.\n// * Coordsize. The width and height attribute have higher priority than the\n//   width and height style values which isn't correct.\n// * Painting mode isn't implemented.\n// * Canvas width/height should is using content-box by default. IE in\n//   Quirks mode will draw the canvas using border-box. Either change your\n//   doctype to HTML5\n//   (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)\n//   or use Box Sizing Behavior from WebFX\n//   (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)\n// * Non uniform scaling does not correctly scale strokes.\n// * Optimize. There is always room for speed improvements.\n\n// Only add this code if we do not already have a canvas implementation\nif (!document.createElement('canvas').getContext) {\n\n(function() {\n\n  // alias some functions to make (compiled) code shorter\n  var m = Math;\n  var mr = m.round;\n  var ms = m.sin;\n  var mc = m.cos;\n  var abs = m.abs;\n  var sqrt = m.sqrt;\n\n  // this is used for sub pixel precision\n  var Z = 10;\n  var Z2 = Z / 2;\n\n  /**\n   * This funtion is assigned to the <canvas> elements as element.getContext().\n   * @this {HTMLElement}\n   * @return {CanvasRenderingContext2D_}\n   */\n  function getContext() {\n    return this.context_ ||\n        (this.context_ = new CanvasRenderingContext2D_(this));\n  }\n\n  var slice = Array.prototype.slice;\n\n  /**\n   * Binds a function to an object. The returned function will always use the\n   * passed in {@code obj} as {@code this}.\n   *\n   * Example:\n   *\n   *   g = bind(f, obj, a, b)\n   *   g(c, d) // will do f.call(obj, a, b, c, d)\n   *\n   * @param {Function} f The function to bind the object to\n   * @param {Object} obj The object that should act as this when the function\n   *     is called\n   * @param {*} var_args Rest arguments that will be used as the initial\n   *     arguments when the function is called\n   * @return {Function} A new function that has bound this\n   */\n  function bind(f, obj, var_args) {\n    var a = slice.call(arguments, 2);\n    return function() {\n      return f.apply(obj, a.concat(slice.call(arguments)));\n    };\n  }\n\n  var G_vmlCanvasManager_ = {\n    init: function(opt_doc) {\n      if (/MSIE/.test(navigator.userAgent) && !window.opera) {\n        var doc = opt_doc || document;\n        // Create a dummy element so that IE will allow canvas elements to be\n        // recognized.\n        doc.createElement('canvas');\n        doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));\n      }\n    },\n\n    init_: function(doc) {\n      // create xmlns\n      if (!doc.namespaces['g_vml_']) {\n        doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml',\n                           '#default#VML');\n\n      }\n      if (!doc.namespaces['g_o_']) {\n        doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office',\n                           '#default#VML');\n      }\n\n      // Setup default CSS.  Only add one style sheet per document\n      if (!doc.styleSheets['ex_canvas_']) {\n        var ss = doc.createStyleSheet();\n        ss.owningElement.id = 'ex_canvas_';\n        ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +\n            // default size is 300x150 in Gecko and Opera\n            'text-align:left;width:300px;height:150px}' +\n            'g_vml_\\\\:*{behavior:url(#default#VML)}' +\n            'g_o_\\\\:*{behavior:url(#default#VML)}';\n\n      }\n\n      // find all canvas elements\n      var els = doc.getElementsByTagName('canvas');\n      for (var i = 0; i < els.length; i++) {\n        this.initElement(els[i]);\n      }\n    },\n\n    /**\n     * Public initializes a canvas element so that it can be used as canvas\n     * element from now on. This is called automatically before the page is\n     * loaded but if you are creating elements using createElement you need to\n     * make sure this is called on the element.\n     * @param {HTMLElement} el The canvas element to initialize.\n     * @return {HTMLElement} the element that was created.\n     */\n    initElement: function(el) {\n      if (!el.getContext) {\n\n        el.getContext = getContext;\n\n        // Remove fallback content. There is no way to hide text nodes so we\n        // just remove all childNodes. We could hide all elements and remove\n        // text nodes but who really cares about the fallback content.\n        el.innerHTML = '';\n\n        // do not use inline function because that will leak memory\n        el.attachEvent('onpropertychange', onPropertyChange);\n        el.attachEvent('onresize', onResize);\n\n        var attrs = el.attributes;\n        if (attrs.width && attrs.width.specified) {\n          // TODO: use runtimeStyle and coordsize\n          // el.getContext().setWidth_(attrs.width.nodeValue);\n          el.style.width = attrs.width.nodeValue + 'px';\n        } else {\n          el.width = el.clientWidth;\n        }\n        if (attrs.height && attrs.height.specified) {\n          // TODO: use runtimeStyle and coordsize\n          // el.getContext().setHeight_(attrs.height.nodeValue);\n          el.style.height = attrs.height.nodeValue + 'px';\n        } else {\n          el.height = el.clientHeight;\n        }\n        //el.getContext().setCoordsize_()\n      }\n      return el;\n    }\n  };\n\n  function onPropertyChange(e) {\n    var el = e.srcElement;\n\n    switch (e.propertyName) {\n      case 'width':\n        el.style.width = el.attributes.width.nodeValue + 'px';\n        el.getContext().clearRect();\n        break;\n      case 'height':\n        el.style.height = el.attributes.height.nodeValue + 'px';\n        el.getContext().clearRect();\n        break;\n    }\n  }\n\n  function onResize(e) {\n    var el = e.srcElement;\n    if (el.firstChild) {\n      el.firstChild.style.width =  el.clientWidth + 'px';\n      el.firstChild.style.height = el.clientHeight + 'px';\n    }\n  }\n\n  G_vmlCanvasManager_.init();\n\n  // precompute \"00\" to \"FF\"\n  var dec2hex = [];\n  for (var i = 0; i < 16; i++) {\n    for (var j = 0; j < 16; j++) {\n      dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);\n    }\n  }\n\n  function createMatrixIdentity() {\n    return [\n      [1, 0, 0],\n      [0, 1, 0],\n      [0, 0, 1]\n    ];\n  }\n\n  function matrixMultiply(m1, m2) {\n    var result = createMatrixIdentity();\n\n    for (var x = 0; x < 3; x++) {\n      for (var y = 0; y < 3; y++) {\n        var sum = 0;\n\n        for (var z = 0; z < 3; z++) {\n          sum += m1[x][z] * m2[z][y];\n        }\n\n        result[x][y] = sum;\n      }\n    }\n    return result;\n  }\n\n  function copyState(o1, o2) {\n    o2.fillStyle     = o1.fillStyle;\n    o2.lineCap       = o1.lineCap;\n    o2.lineJoin      = o1.lineJoin;\n    o2.lineWidth     = o1.lineWidth;\n    o2.miterLimit    = o1.miterLimit;\n    o2.shadowBlur    = o1.shadowBlur;\n    o2.shadowColor   = o1.shadowColor;\n    o2.shadowOffsetX = o1.shadowOffsetX;\n    o2.shadowOffsetY = o1.shadowOffsetY;\n    o2.strokeStyle   = o1.strokeStyle;\n    o2.globalAlpha   = o1.globalAlpha;\n    o2.arcScaleX_    = o1.arcScaleX_;\n    o2.arcScaleY_    = o1.arcScaleY_;\n    o2.lineScale_    = o1.lineScale_;\n  }\n\n  function processStyle(styleString) {\n    var str, alpha = 1;\n\n    styleString = String(styleString);\n    if (styleString.substring(0, 3) == 'rgb') {\n      var start = styleString.indexOf('(', 3);\n      var end = styleString.indexOf(')', start + 1);\n      var guts = styleString.substring(start + 1, end).split(',');\n\n      str = '#';\n      for (var i = 0; i < 3; i++) {\n        str += dec2hex[Number(guts[i])];\n      }\n\n      if (guts.length == 4 && styleString.substr(3, 1) == 'a') {\n        alpha = guts[3];\n      }\n    } else {\n      str = styleString;\n    }\n\n    return {color: str, alpha: alpha};\n  }\n\n  function processLineCap(lineCap) {\n    switch (lineCap) {\n      case 'butt':\n        return 'flat';\n      case 'round':\n        return 'round';\n      case 'square':\n      default:\n        return 'square';\n    }\n  }\n\n  /**\n   * This class implements CanvasRenderingContext2D interface as described by\n   * the WHATWG.\n   * @param {HTMLElement} surfaceElement The element that the 2D context should\n   * be associated with\n   */\n  function CanvasRenderingContext2D_(surfaceElement) {\n    this.m_ = createMatrixIdentity();\n\n    this.mStack_ = [];\n    this.aStack_ = [];\n    this.currentPath_ = [];\n\n    // Canvas context properties\n    this.strokeStyle = '#000';\n    this.fillStyle = '#000';\n\n    this.lineWidth = 1;\n    this.lineJoin = 'miter';\n    this.lineCap = 'butt';\n    this.miterLimit = Z * 1;\n    this.globalAlpha = 1;\n    this.canvas = surfaceElement;\n\n    var el = surfaceElement.ownerDocument.createElement('div');\n    el.style.width =  surfaceElement.clientWidth + 'px';\n    el.style.height = surfaceElement.clientHeight + 'px';\n    el.style.overflow = 'hidden';\n    el.style.position = 'absolute';\n    surfaceElement.appendChild(el);\n\n    this.element_ = el;\n    this.arcScaleX_ = 1;\n    this.arcScaleY_ = 1;\n    this.lineScale_ = 1;\n  }\n\n  var contextPrototype = CanvasRenderingContext2D_.prototype;\n  contextPrototype.clearRect = function() {\n    this.element_.innerHTML = '';\n  };\n\n  contextPrototype.beginPath = function() {\n    // TODO: Branch current matrix so that save/restore has no effect\n    //       as per safari docs.\n    this.currentPath_ = [];\n  };\n\n  contextPrototype.moveTo = function(aX, aY) {\n    var p = this.getCoords_(aX, aY);\n    this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});\n    this.currentX_ = p.x;\n    this.currentY_ = p.y;\n  };\n\n  contextPrototype.lineTo = function(aX, aY) {\n    var p = this.getCoords_(aX, aY);\n    this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});\n\n    this.currentX_ = p.x;\n    this.currentY_ = p.y;\n  };\n\n  contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,\n                                            aCP2x, aCP2y,\n                                            aX, aY) {\n    var p = this.getCoords_(aX, aY);\n    var cp1 = this.getCoords_(aCP1x, aCP1y);\n    var cp2 = this.getCoords_(aCP2x, aCP2y);\n    bezierCurveTo(this, cp1, cp2, p);\n  };\n\n  // Helper function that takes the already fixed cordinates.\n  function bezierCurveTo(self, cp1, cp2, p) {\n    self.currentPath_.push({\n      type: 'bezierCurveTo',\n      cp1x: cp1.x,\n      cp1y: cp1.y,\n      cp2x: cp2.x,\n      cp2y: cp2.y,\n      x: p.x,\n      y: p.y\n    });\n    self.currentX_ = p.x;\n    self.currentY_ = p.y;\n  }\n\n  contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {\n    // the following is lifted almost directly from\n    // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes\n\n    var cp = this.getCoords_(aCPx, aCPy);\n    var p = this.getCoords_(aX, aY);\n\n    var cp1 = {\n      x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),\n      y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)\n    };\n    var cp2 = {\n      x: cp1.x + (p.x - this.currentX_) / 3.0,\n      y: cp1.y + (p.y - this.currentY_) / 3.0\n    };\n\n    bezierCurveTo(this, cp1, cp2, p);\n  };\n\n  contextPrototype.arc = function(aX, aY, aRadius,\n                                  aStartAngle, aEndAngle, aClockwise) {\n    aRadius *= Z;\n    var arcType = aClockwise ? 'at' : 'wa';\n\n    var xStart = aX + mc(aStartAngle) * aRadius - Z2;\n    var yStart = aY + ms(aStartAngle) * aRadius - Z2;\n\n    var xEnd = aX + mc(aEndAngle) * aRadius - Z2;\n    var yEnd = aY + ms(aEndAngle) * aRadius - Z2;\n\n    // IE won't render arches drawn counter clockwise if xStart == xEnd.\n    if (xStart == xEnd && !aClockwise) {\n      xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something\n                       // that can be represented in binary\n    }\n\n    var p = this.getCoords_(aX, aY);\n    var pStart = this.getCoords_(xStart, yStart);\n    var pEnd = this.getCoords_(xEnd, yEnd);\n\n    this.currentPath_.push({type: arcType,\n                           x: p.x,\n                           y: p.y,\n                           radius: aRadius,\n                           xStart: pStart.x,\n                           yStart: pStart.y,\n                           xEnd: pEnd.x,\n                           yEnd: pEnd.y});\n\n  };\n\n  contextPrototype.rect = function(aX, aY, aWidth, aHeight) {\n    this.moveTo(aX, aY);\n    this.lineTo(aX + aWidth, aY);\n    this.lineTo(aX + aWidth, aY + aHeight);\n    this.lineTo(aX, aY + aHeight);\n    this.closePath();\n  };\n\n  contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {\n    var oldPath = this.currentPath_;\n    this.beginPath();\n\n    this.moveTo(aX, aY);\n    this.lineTo(aX + aWidth, aY);\n    this.lineTo(aX + aWidth, aY + aHeight);\n    this.lineTo(aX, aY + aHeight);\n    this.closePath();\n    this.stroke();\n\n    this.currentPath_ = oldPath;\n  };\n\n  contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {\n    var oldPath = this.currentPath_;\n    this.beginPath();\n\n    this.moveTo(aX, aY);\n    this.lineTo(aX + aWidth, aY);\n    this.lineTo(aX + aWidth, aY + aHeight);\n    this.lineTo(aX, aY + aHeight);\n    this.closePath();\n    this.fill();\n\n    this.currentPath_ = oldPath;\n  };\n\n  contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {\n    var gradient = new CanvasGradient_('gradient');\n    gradient.x0_ = aX0;\n    gradient.y0_ = aY0;\n    gradient.x1_ = aX1;\n    gradient.y1_ = aY1;\n    return gradient;\n  };\n\n  contextPrototype.createRadialGradient = function(aX0, aY0, aR0,\n                                                   aX1, aY1, aR1) {\n    var gradient = new CanvasGradient_('gradientradial');\n    gradient.x0_ = aX0;\n    gradient.y0_ = aY0;\n    gradient.r0_ = aR0;\n    gradient.x1_ = aX1;\n    gradient.y1_ = aY1;\n    gradient.r1_ = aR1;\n    return gradient;\n  };\n\n  contextPrototype.drawImage = function(image, var_args) {\n    var dx, dy, dw, dh, sx, sy, sw, sh;\n\n    // to find the original width we overide the width and height\n    var oldRuntimeWidth = image.runtimeStyle.width;\n    var oldRuntimeHeight = image.runtimeStyle.height;\n    image.runtimeStyle.width = 'auto';\n    image.runtimeStyle.height = 'auto';\n\n    // get the original size\n    var w = image.width;\n    var h = image.height;\n\n    // and remove overides\n    image.runtimeStyle.width = oldRuntimeWidth;\n    image.runtimeStyle.height = oldRuntimeHeight;\n\n    if (arguments.length == 3) {\n      dx = arguments[1];\n      dy = arguments[2];\n      sx = sy = 0;\n      sw = dw = w;\n      sh = dh = h;\n    } else if (arguments.length == 5) {\n      dx = arguments[1];\n      dy = arguments[2];\n      dw = arguments[3];\n      dh = arguments[4];\n      sx = sy = 0;\n      sw = w;\n      sh = h;\n    } else if (arguments.length == 9) {\n      sx = arguments[1];\n      sy = arguments[2];\n      sw = arguments[3];\n      sh = arguments[4];\n      dx = arguments[5];\n      dy = arguments[6];\n      dw = arguments[7];\n      dh = arguments[8];\n    } else {\n      throw Error('Invalid number of arguments');\n    }\n\n    var d = this.getCoords_(dx, dy);\n\n    var w2 = sw / 2;\n    var h2 = sh / 2;\n\n    var vmlStr = [];\n\n    var W = 10;\n    var H = 10;\n\n    // For some reason that I've now forgotten, using divs didn't work\n    vmlStr.push(' <g_vml_:group',\n                ' coordsize=\"', Z * W, ',', Z * H, '\"',\n                ' coordorigin=\"0,0\"' ,\n                ' style=\"width:', W, 'px;height:', H, 'px;position:absolute;');\n\n    // If filters are necessary (rotation exists), create them\n    // filters are bog-slow, so only create them if abbsolutely necessary\n    // The following check doesn't account for skews (which don't exist\n    // in the canvas spec (yet) anyway.\n\n    if (this.m_[0][0] != 1 || this.m_[0][1]) {\n      var filter = [];\n\n      // Note the 12/21 reversal\n      filter.push('M11=', this.m_[0][0], ',',\n                  'M12=', this.m_[1][0], ',',\n                  'M21=', this.m_[0][1], ',',\n                  'M22=', this.m_[1][1], ',',\n                  'Dx=', mr(d.x / Z), ',',\n                  'Dy=', mr(d.y / Z), '');\n\n      // Bounding box calculation (need to minimize displayed area so that\n      // filters don't waste time on unused pixels.\n      var max = d;\n      var c2 = this.getCoords_(dx + dw, dy);\n      var c3 = this.getCoords_(dx, dy + dh);\n      var c4 = this.getCoords_(dx + dw, dy + dh);\n\n      max.x = m.max(max.x, c2.x, c3.x, c4.x);\n      max.y = m.max(max.y, c2.y, c3.y, c4.y);\n\n      vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),\n                  'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',\n                  filter.join(''), \", sizingmethod='clip');\")\n    } else {\n      vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');\n    }\n\n    vmlStr.push(' \">' ,\n                '<g_vml_:image src=\"', image.src, '\"',\n                ' style=\"width:', Z * dw, 'px;',\n                ' height:', Z * dh, 'px;\"',\n                ' cropleft=\"', sx / w, '\"',\n                ' croptop=\"', sy / h, '\"',\n                ' cropright=\"', (w - sx - sw) / w, '\"',\n                ' cropbottom=\"', (h - sy - sh) / h, '\"',\n                ' />',\n                '</g_vml_:group>');\n\n    this.element_.insertAdjacentHTML('BeforeEnd',\n                                    vmlStr.join(''));\n  };\n\n  contextPrototype.stroke = function(aFill) {\n    var lineStr = [];\n    var lineOpen = false;\n    var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);\n    var color = a.color;\n    var opacity = a.alpha * this.globalAlpha;\n\n    var W = 10;\n    var H = 10;\n\n    lineStr.push('<g_vml_:shape',\n                 ' filled=\"', !!aFill, '\"',\n                 ' style=\"position:absolute;width:', W, 'px;height:', H, 'px;\"',\n                 ' coordorigin=\"0 0\" coordsize=\"', Z * W, ' ', Z * H, '\"',\n                 ' stroked=\"', !aFill, '\"',\n                 ' path=\"');\n\n    var newSeq = false;\n    var min = {x: null, y: null};\n    var max = {x: null, y: null};\n\n    for (var i = 0; i < this.currentPath_.length; i++) {\n      var p = this.currentPath_[i];\n      var c;\n\n      switch (p.type) {\n        case 'moveTo':\n          c = p;\n          lineStr.push(' m ', mr(p.x), ',', mr(p.y));\n          break;\n        case 'lineTo':\n          lineStr.push(' l ', mr(p.x), ',', mr(p.y));\n          break;\n        case 'close':\n          lineStr.push(' x ');\n          p = null;\n          break;\n        case 'bezierCurveTo':\n          lineStr.push(' c ',\n                       mr(p.cp1x), ',', mr(p.cp1y), ',',\n                       mr(p.cp2x), ',', mr(p.cp2y), ',',\n                       mr(p.x), ',', mr(p.y));\n          break;\n        case 'at':\n        case 'wa':\n          lineStr.push(' ', p.type, ' ',\n                       mr(p.x - this.arcScaleX_ * p.radius), ',',\n                       mr(p.y - this.arcScaleY_ * p.radius), ' ',\n                       mr(p.x + this.arcScaleX_ * p.radius), ',',\n                       mr(p.y + this.arcScaleY_ * p.radius), ' ',\n                       mr(p.xStart), ',', mr(p.yStart), ' ',\n                       mr(p.xEnd), ',', mr(p.yEnd));\n          break;\n      }\n\n\n      // TODO: Following is broken for curves due to\n      //       move to proper paths.\n\n      // Figure out dimensions so we can do gradient fills\n      // properly\n      if (p) {\n        if (min.x == null || p.x < min.x) {\n          min.x = p.x;\n        }\n        if (max.x == null || p.x > max.x) {\n          max.x = p.x;\n        }\n        if (min.y == null || p.y < min.y) {\n          min.y = p.y;\n        }\n        if (max.y == null || p.y > max.y) {\n          max.y = p.y;\n        }\n      }\n    }\n    lineStr.push(' \">');\n\n    if (!aFill) {\n      var lineWidth = this.lineScale_ * this.lineWidth;\n\n      // VML cannot correctly render a line if the width is less than 1px.\n      // In that case, we dilute the color to make the line look thinner.\n      if (lineWidth < 1) {\n        opacity *= lineWidth;\n      }\n\n      lineStr.push(\n        '<g_vml_:stroke',\n        ' opacity=\"', opacity, '\"',\n        ' joinstyle=\"', this.lineJoin, '\"',\n        ' miterlimit=\"', this.miterLimit, '\"',\n        ' endcap=\"', processLineCap(this.lineCap), '\"',\n        ' weight=\"', lineWidth, 'px\"',\n        ' color=\"', color, '\" />'\n      );\n    } else if (typeof this.fillStyle == 'object') {\n      var fillStyle = this.fillStyle;\n      var angle = 0;\n      var focus = {x: 0, y: 0};\n\n      // additional offset\n      var shift = 0;\n      // scale factor for offset\n      var expansion = 1;\n\n      if (fillStyle.type_ == 'gradient') {\n        var x0 = fillStyle.x0_ / this.arcScaleX_;\n        var y0 = fillStyle.y0_ / this.arcScaleY_;\n        var x1 = fillStyle.x1_ / this.arcScaleX_;\n        var y1 = fillStyle.y1_ / this.arcScaleY_;\n        var p0 = this.getCoords_(x0, y0);\n        var p1 = this.getCoords_(x1, y1);\n        var dx = p1.x - p0.x;\n        var dy = p1.y - p0.y;\n        angle = Math.atan2(dx, dy) * 180 / Math.PI;\n\n        // The angle should be a non-negative number.\n        if (angle < 0) {\n          angle += 360;\n        }\n\n        // Very small angles produce an unexpected result because they are\n        // converted to a scientific notation string.\n        if (angle < 1e-6) {\n          angle = 0;\n        }\n      } else {\n        var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_);\n        var width  = max.x - min.x;\n        var height = max.y - min.y;\n        focus = {\n          x: (p0.x - min.x) / width,\n          y: (p0.y - min.y) / height\n        };\n\n        width  /= this.arcScaleX_ * Z;\n        height /= this.arcScaleY_ * Z;\n        var dimension = m.max(width, height);\n        shift = 2 * fillStyle.r0_ / dimension;\n        expansion = 2 * fillStyle.r1_ / dimension - shift;\n      }\n\n      // We need to sort the color stops in ascending order by offset,\n      // otherwise IE won't interpret it correctly.\n      var stops = fillStyle.colors_;\n      stops.sort(function(cs1, cs2) {\n        return cs1.offset - cs2.offset;\n      });\n\n      var length = stops.length;\n      var color1 = stops[0].color;\n      var color2 = stops[length - 1].color;\n      var opacity1 = stops[0].alpha * this.globalAlpha;\n      var opacity2 = stops[length - 1].alpha * this.globalAlpha;\n\n      var colors = [];\n      for (var i = 0; i < length; i++) {\n        var stop = stops[i];\n        colors.push(stop.offset * expansion + shift + ' ' + stop.color);\n      }\n\n      // When colors attribute is used, the meanings of opacity and o:opacity2\n      // are reversed.\n      lineStr.push('<g_vml_:fill type=\"', fillStyle.type_, '\"',\n                   ' method=\"none\" focus=\"100%\"',\n                   ' color=\"', color1, '\"',\n                   ' color2=\"', color2, '\"',\n                   ' colors=\"', colors.join(','), '\"',\n                   ' opacity=\"', opacity2, '\"',\n                   ' g_o_:opacity2=\"', opacity1, '\"',\n                   ' angle=\"', angle, '\"',\n                   ' focusposition=\"', focus.x, ',', focus.y, '\" />');\n    } else {\n      lineStr.push('<g_vml_:fill color=\"', color, '\" opacity=\"', opacity,\n                   '\" />');\n    }\n\n    lineStr.push('</g_vml_:shape>');\n\n    this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));\n  };\n\n  contextPrototype.fill = function() {\n    this.stroke(true);\n  }\n\n  contextPrototype.closePath = function() {\n    this.currentPath_.push({type: 'close'});\n  };\n\n  /**\n   * @private\n   */\n  contextPrototype.getCoords_ = function(aX, aY) {\n    var m = this.m_;\n    return {\n      x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,\n      y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2\n    }\n  };\n\n  contextPrototype.save = function() {\n    var o = {};\n    copyState(this, o);\n    this.aStack_.push(o);\n    this.mStack_.push(this.m_);\n    this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);\n  };\n\n  contextPrototype.restore = function() {\n    copyState(this.aStack_.pop(), this);\n    this.m_ = this.mStack_.pop();\n  };\n\n  function matrixIsFinite(m) {\n    for (var j = 0; j < 3; j++) {\n      for (var k = 0; k < 2; k++) {\n        if (!isFinite(m[j][k]) || isNaN(m[j][k])) {\n          return false;\n        }\n      }\n    }\n    return true;\n  }\n\n  function setM(ctx, m, updateLineScale) {\n    if (!matrixIsFinite(m)) {\n      return;\n    }\n    ctx.m_ = m;\n\n    if (updateLineScale) {\n      // Get the line scale.\n      // Determinant of this.m_ means how much the area is enlarged by the\n      // transformation. So its square root can be used as a scale factor\n      // for width.\n      var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];\n      ctx.lineScale_ = sqrt(abs(det));\n    }\n  }\n\n  contextPrototype.translate = function(aX, aY) {\n    var m1 = [\n      [1,  0,  0],\n      [0,  1,  0],\n      [aX, aY, 1]\n    ];\n\n    setM(this, matrixMultiply(m1, this.m_), false);\n  };\n\n  contextPrototype.rotate = function(aRot) {\n    var c = mc(aRot);\n    var s = ms(aRot);\n\n    var m1 = [\n      [c,  s, 0],\n      [-s, c, 0],\n      [0,  0, 1]\n    ];\n\n    setM(this, matrixMultiply(m1, this.m_), false);\n  };\n\n  contextPrototype.scale = function(aX, aY) {\n    this.arcScaleX_ *= aX;\n    this.arcScaleY_ *= aY;\n    var m1 = [\n      [aX, 0,  0],\n      [0,  aY, 0],\n      [0,  0,  1]\n    ];\n\n    setM(this, matrixMultiply(m1, this.m_), true);\n  };\n\n  contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {\n    var m1 = [\n      [m11, m12, 0],\n      [m21, m22, 0],\n      [dx,  dy,  1]\n    ];\n\n    setM(this, matrixMultiply(m1, this.m_), true);\n  };\n\n  contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {\n    var m = [\n      [m11, m12, 0],\n      [m21, m22, 0],\n      [dx,  dy,  1]\n    ];\n\n    setM(this, m, true);\n  };\n\n  /******** STUBS ********/\n  contextPrototype.clip = function() {\n    // TODO: Implement\n  };\n\n  contextPrototype.arcTo = function() {\n    // TODO: Implement\n  };\n\n  contextPrototype.createPattern = function() {\n    return new CanvasPattern_;\n  };\n\n  // Gradient / Pattern Stubs\n  function CanvasGradient_(aType) {\n    this.type_ = aType;\n    this.x0_ = 0;\n    this.y0_ = 0;\n    this.r0_ = 0;\n    this.x1_ = 0;\n    this.y1_ = 0;\n    this.r1_ = 0;\n    this.colors_ = [];\n  }\n\n  CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {\n    aColor = processStyle(aColor);\n    this.colors_.push({offset: aOffset,\n                       color: aColor.color,\n                       alpha: aColor.alpha});\n  };\n\n  function CanvasPattern_() {}\n\n  // set up externs\n  G_vmlCanvasManager = G_vmlCanvasManager_;\n  CanvasRenderingContext2D = CanvasRenderingContext2D_;\n  CanvasGradient = CanvasGradient_;\n  CanvasPattern = CanvasPattern_;\n\n})();\n\n} // if\n"
  },
  {
    "path": "static/assets/plugins/jquery-knob/jquery.knob.js",
    "content": "/*!jQuery Knob*/\n/**\n * Downward compatible, touchable dial\n *\n * Version: 1.2.11\n * Requires: jQuery v1.7+\n *\n * Copyright (c) 2012 Anthony Terrien\n * Under MIT License (http://www.opensource.org/licenses/mit-license.php)\n *\n * Thanks to vor, eskimoblood, spiffistan, FabrizioC\n */\n(function (factory) {\n    if (typeof exports === 'object') {\n        // CommonJS\n        module.exports = factory(require('jquery'));\n    } else if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(['jquery'], factory);\n    } else {\n        // Browser globals\n        factory(jQuery);\n    }\n}(function ($) {\n\n    /**\n     * Kontrol library\n     */\n    \"use strict\";\n\n    /**\n     * Definition of globals and core\n     */\n    var k = {}, // kontrol\n        max = Math.max,\n        min = Math.min;\n\n    k.c = {};\n    k.c.d = $(document);\n    k.c.t = function (e) {\n        return e.originalEvent.touches.length - 1;\n    };\n\n    /**\n     * Kontrol Object\n     *\n     * Definition of an abstract UI control\n     *\n     * Each concrete component must call this one.\n     * <code>\n     * k.o.call(this);\n     * </code>\n     */\n    k.o = function () {\n        var s = this;\n\n        this.o = null; // array of options\n        this.$ = null; // jQuery wrapped element\n        this.i = null; // mixed HTMLInputElement or array of HTMLInputElement\n        this.g = null; // deprecated 2D graphics context for 'pre-rendering'\n        this.v = null; // value ; mixed array or integer\n        this.cv = null; // change value ; not commited value\n        this.x = 0; // canvas x position\n        this.y = 0; // canvas y position\n        this.w = 0; // canvas width\n        this.h = 0; // canvas height\n        this.$c = null; // jQuery canvas element\n        this.c = null; // rendered canvas context\n        this.t = 0; // touches index\n        this.isInit = false;\n        this.fgColor = null; // main color\n        this.pColor = null; // previous color\n        this.dH = null; // draw hook\n        this.cH = null; // change hook\n        this.eH = null; // cancel hook\n        this.rH = null; // release hook\n        this.scale = 1; // scale factor\n        this.relative = false;\n        this.relativeWidth = false;\n        this.relativeHeight = false;\n        this.$div = null; // component div\n\n        this.run = function () {\n            var cf = function (e, conf) {\n                var k;\n                for (k in conf) {\n                    s.o[k] = conf[k];\n                }\n                s._carve().init();\n                s._configure()\n                 ._draw();\n            };\n\n            if (this.$.data('kontroled')) return;\n            this.$.data('kontroled', true);\n\n            this.extend();\n            this.o = $.extend({\n                    // Config\n                    min: this.$.data('min') !== undefined ? this.$.data('min') : 0,\n                    max: this.$.data('max') !== undefined ? this.$.data('max') : 100,\n                    stopper: true,\n                    readOnly: this.$.data('readonly') || (this.$.attr('readonly') === 'readonly'),\n\n                    // UI\n                    cursor: this.$.data('cursor') === true && 30\n                            || this.$.data('cursor') || 0,\n                    thickness: this.$.data('thickness')\n                               && Math.max(Math.min(this.$.data('thickness'), 1), 0.01)\n                               || 0.35,\n                    lineCap: this.$.data('linecap') || 'butt',\n                    width: this.$.data('width') || 200,\n                    height: this.$.data('height') || 200,\n                    displayInput: this.$.data('displayinput') == null || this.$.data('displayinput'),\n                    displayPrevious: this.$.data('displayprevious'),\n                    fgColor: this.$.data('fgcolor') || '#87CEEB',\n                    inputColor: this.$.data('inputcolor'),\n                    font: this.$.data('font') || 'Arial',\n                    fontWeight: this.$.data('font-weight') || 'bold',\n                    inline: false,\n                    step: this.$.data('step') || 1,\n                    rotation: this.$.data('rotation'),\n\n                    // Hooks\n                    draw: null, // function () {}\n                    change: null, // function (value) {}\n                    cancel: null, // function () {}\n                    release: null, // function (value) {}\n\n                    // Output formatting, allows to add unit: %, ms ...\n                    format: function(v) {\n                        return v;\n                    },\n                    parse: function (v) {\n                        return parseFloat(v);\n                    }\n                }, this.o\n            );\n\n            // finalize options\n            this.o.flip = this.o.rotation === 'anticlockwise' || this.o.rotation === 'acw';\n            if (!this.o.inputColor) {\n                this.o.inputColor = this.o.fgColor;\n            }\n\n            // routing value\n            if (this.$.is('fieldset')) {\n\n                // fieldset = array of integer\n                this.v = {};\n                this.i = this.$.find('input');\n                this.i.each(function(k) {\n                    var $this = $(this);\n                    s.i[k] = $this;\n                    s.v[k] = s.o.parse($this.val());\n\n                    $this.bind(\n                        'change blur',\n                        function () {\n                            var val = {};\n                            val[k] = $this.val();\n                            s.val(s._validate(val));\n                        }\n                    );\n                });\n                this.$.find('legend').remove();\n            } else {\n\n                // input = integer\n                this.i = this.$;\n                this.v = this.o.parse(this.$.val());\n                this.v === '' && (this.v = this.o.min);\n                this.$.bind(\n                    'change blur',\n                    function () {\n                        s.val(s._validate(s.o.parse(s.$.val())));\n                    }\n                );\n\n            }\n\n            !this.o.displayInput && this.$.hide();\n\n            // adds needed DOM elements (canvas, div)\n            this.$c = $(document.createElement('canvas')).attr({\n                width: this.o.width,\n                height: this.o.height\n            });\n\n            // wraps all elements in a div\n            // add to DOM before Canvas init is triggered\n            this.$div = $('<div style=\"'\n                + (this.o.inline ? 'display:inline;' : '')\n                + 'width:' + this.o.width + 'px;height:' + this.o.height + 'px;'\n                + '\"></div>');\n\n            this.$.wrap(this.$div).before(this.$c);\n            this.$div = this.$.parent();\n\n            if (typeof G_vmlCanvasManager !== 'undefined') {\n                G_vmlCanvasManager.initElement(this.$c[0]);\n            }\n\n            this.c = this.$c[0].getContext ? this.$c[0].getContext('2d') : null;\n\n            if (!this.c) {\n                throw {\n                    name:        \"CanvasNotSupportedException\",\n                    message:     \"Canvas not supported. Please use excanvas on IE8.0.\",\n                    toString:    function(){return this.name + \": \" + this.message}\n                }\n            }\n\n            // hdpi support\n            this.scale = (window.devicePixelRatio || 1) / (\n                            this.c.webkitBackingStorePixelRatio ||\n                            this.c.mozBackingStorePixelRatio ||\n                            this.c.msBackingStorePixelRatio ||\n                            this.c.oBackingStorePixelRatio ||\n                            this.c.backingStorePixelRatio || 1\n                         );\n\n            // detects relative width / height\n            this.relativeWidth =  this.o.width % 1 !== 0\n                                  && this.o.width.indexOf('%');\n            this.relativeHeight = this.o.height % 1 !== 0\n                                  && this.o.height.indexOf('%');\n            this.relative = this.relativeWidth || this.relativeHeight;\n\n            // computes size and carves the component\n            this._carve();\n\n            // prepares props for transaction\n            if (this.v instanceof Object) {\n                this.cv = {};\n                this.copy(this.v, this.cv);\n            } else {\n                this.cv = this.v;\n            }\n\n            // binds configure event\n            this.$\n                .bind(\"configure\", cf)\n                .parent()\n                .bind(\"configure\", cf);\n\n            // finalize init\n            this._listen()\n                ._configure()\n                ._xy()\n                .init();\n\n            this.isInit = true;\n\n            this.$.val(this.o.format(this.v));\n            this._draw();\n\n            return this;\n        };\n\n        this._carve = function() {\n            if (this.relative) {\n                var w = this.relativeWidth ?\n                        this.$div.parent().width() *\n                        parseInt(this.o.width) / 100\n                        : this.$div.parent().width(),\n                    h = this.relativeHeight ?\n                        this.$div.parent().height() *\n                        parseInt(this.o.height) / 100\n                        : this.$div.parent().height();\n\n                // apply relative\n                this.w = this.h = Math.min(w, h);\n            } else {\n                this.w = this.o.width;\n                this.h = this.o.height;\n            }\n\n            // finalize div\n            this.$div.css({\n                'width': this.w + 'px',\n                'height': this.h + 'px'\n            });\n\n            // finalize canvas with computed width\n            this.$c.attr({\n                width: this.w,\n                height: this.h\n            });\n\n            // scaling\n            if (this.scale !== 1) {\n                this.$c[0].width = this.$c[0].width * this.scale;\n                this.$c[0].height = this.$c[0].height * this.scale;\n                this.$c.width(this.w);\n                this.$c.height(this.h);\n            }\n\n            return this;\n        };\n\n        this._draw = function () {\n\n            // canvas pre-rendering\n            var d = true;\n\n            s.g = s.c;\n\n            s.clear();\n\n            s.dH && (d = s.dH());\n\n            d !== false && s.draw();\n        };\n\n        this._touch = function (e) {\n            var touchMove = function (e) {\n                var v = s.xy2val(\n                            e.originalEvent.touches[s.t].pageX,\n                            e.originalEvent.touches[s.t].pageY\n                        );\n\n                if (v == s.cv) return;\n\n                if (s.cH && s.cH(v) === false) return;\n\n                s.change(s._validate(v));\n                s._draw();\n            };\n\n            // get touches index\n            this.t = k.c.t(e);\n\n            // First touch\n            touchMove(e);\n\n            // Touch events listeners\n            k.c.d\n                .bind(\"touchmove.k\", touchMove)\n                .bind(\n                    \"touchend.k\",\n                    function () {\n                        k.c.d.unbind('touchmove.k touchend.k');\n                        s.val(s.cv);\n                    }\n                );\n\n            return this;\n        };\n\n        this._mouse = function (e) {\n            var mouseMove = function (e) {\n                var v = s.xy2val(e.pageX, e.pageY);\n\n                if (v == s.cv) return;\n\n                if (s.cH && (s.cH(v) === false)) return;\n\n                s.change(s._validate(v));\n                s._draw();\n            };\n\n            // First click\n            mouseMove(e);\n\n            // Mouse events listeners\n            k.c.d\n                .bind(\"mousemove.k\", mouseMove)\n                .bind(\n                    // Escape key cancel current change\n                    \"keyup.k\",\n                    function (e) {\n                        if (e.keyCode === 27) {\n                            k.c.d.unbind(\"mouseup.k mousemove.k keyup.k\");\n\n                            if (s.eH && s.eH() === false)\n                                return;\n\n                            s.cancel();\n                        }\n                    }\n                )\n                .bind(\n                    \"mouseup.k\",\n                    function (e) {\n                        k.c.d.unbind('mousemove.k mouseup.k keyup.k');\n                        s.val(s.cv);\n                    }\n                );\n\n            return this;\n        };\n\n        this._xy = function () {\n            var o = this.$c.offset();\n            this.x = o.left;\n            this.y = o.top;\n\n            return this;\n        };\n\n        this._listen = function () {\n            if (!this.o.readOnly) {\n                this.$c\n                    .bind(\n                        \"mousedown\",\n                        function (e) {\n                            e.preventDefault();\n                            s._xy()._mouse(e);\n                        }\n                    )\n                    .bind(\n                        \"touchstart\",\n                        function (e) {\n                            e.preventDefault();\n                            s._xy()._touch(e);\n                        }\n                    );\n\n                this.listen();\n            } else {\n                this.$.attr('readonly', 'readonly');\n            }\n\n            if (this.relative) {\n                $(window).resize(function() {\n                    s._carve().init();\n                    s._draw();\n                });\n            }\n\n            return this;\n        };\n\n        this._configure = function () {\n\n            // Hooks\n            if (this.o.draw) this.dH = this.o.draw;\n            if (this.o.change) this.cH = this.o.change;\n            if (this.o.cancel) this.eH = this.o.cancel;\n            if (this.o.release) this.rH = this.o.release;\n\n            if (this.o.displayPrevious) {\n                this.pColor = this.h2rgba(this.o.fgColor, \"0.4\");\n                this.fgColor = this.h2rgba(this.o.fgColor, \"0.6\");\n            } else {\n                this.fgColor = this.o.fgColor;\n            }\n\n            return this;\n        };\n\n        this._clear = function () {\n            this.$c[0].width = this.$c[0].width;\n        };\n\n        this._validate = function (v) {\n            var val = (~~ (((v < 0) ? -0.5 : 0.5) + (v/this.o.step))) * this.o.step;\n            return Math.round(val * 100) / 100;\n        };\n\n        // Abstract methods\n        this.listen = function () {}; // on start, one time\n        this.extend = function () {}; // each time configure triggered\n        this.init = function () {}; // each time configure triggered\n        this.change = function (v) {}; // on change\n        this.val = function (v) {}; // on release\n        this.xy2val = function (x, y) {}; //\n        this.draw = function () {}; // on change / on release\n        this.clear = function () { this._clear(); };\n\n        // Utils\n        this.h2rgba = function (h, a) {\n            var rgb;\n            h = h.substring(1,7);\n            rgb = [\n                parseInt(h.substring(0,2), 16),\n                parseInt(h.substring(2,4), 16),\n                parseInt(h.substring(4,6), 16)\n            ];\n\n            return \"rgba(\" + rgb[0] + \",\" + rgb[1] + \",\" + rgb[2] + \",\" + a + \")\";\n        };\n\n        this.copy = function (f, t) {\n            for (var i in f) {\n                t[i] = f[i];\n            }\n        };\n    };\n\n\n    /**\n     * k.Dial\n     */\n    k.Dial = function () {\n        k.o.call(this);\n\n        this.startAngle = null;\n        this.xy = null;\n        this.radius = null;\n        this.lineWidth = null;\n        this.cursorExt = null;\n        this.w2 = null;\n        this.PI2 = 2*Math.PI;\n\n        this.extend = function () {\n            this.o = $.extend({\n                bgColor: this.$.data('bgcolor') || '#EEEEEE',\n                angleOffset: this.$.data('angleoffset') || 0,\n                angleArc: this.$.data('anglearc') || 360,\n                inline: true\n            }, this.o);\n        };\n\n        this.val = function (v, triggerRelease) {\n            if (null != v) {\n\n                // reverse format\n                v = this.o.parse(v);\n\n                if (triggerRelease !== false\n                    && v != this.v\n                    && this.rH\n                    && this.rH(v) === false) { return; }\n\n                this.cv = this.o.stopper ? max(min(v, this.o.max), this.o.min) : v;\n                this.v = this.cv;\n                this.$.val(this.o.format(this.v));\n                this._draw();\n            } else {\n                return this.v;\n            }\n        };\n\n        this.xy2val = function (x, y) {\n            var a, ret;\n\n            a = Math.atan2(\n                        x - (this.x + this.w2),\n                        - (y - this.y - this.w2)\n                    ) - this.angleOffset;\n\n            if (this.o.flip) {\n                a = this.angleArc - a - this.PI2;\n            }\n\n            if (this.angleArc != this.PI2 && (a < 0) && (a > -0.5)) {\n\n                // if isset angleArc option, set to min if .5 under min\n                a = 0;\n            } else if (a < 0) {\n                a += this.PI2;\n            }\n\n            ret = (a * (this.o.max - this.o.min) / this.angleArc) + this.o.min;\n\n            this.o.stopper && (ret = max(min(ret, this.o.max), this.o.min));\n\n            return ret;\n        };\n\n        this.listen = function () {\n\n            // bind MouseWheel\n            var s = this, mwTimerStop,\n                mwTimerRelease,\n                mw = function (e) {\n                    e.preventDefault();\n\n                    var ori = e.originalEvent,\n                        deltaX = ori.detail || ori.wheelDeltaX,\n                        deltaY = ori.detail || ori.wheelDeltaY,\n                        v = s._validate(s.o.parse(s.$.val()))\n                            + (\n                                deltaX > 0 || deltaY > 0\n                                ? s.o.step\n                                : deltaX < 0 || deltaY < 0 ? -s.o.step : 0\n                              );\n\n                    v = max(min(v, s.o.max), s.o.min);\n\n                    s.val(v, false);\n\n                    if (s.rH) {\n                        // Handle mousewheel stop\n                        clearTimeout(mwTimerStop);\n                        mwTimerStop = setTimeout(function () {\n                            s.rH(v);\n                            mwTimerStop = null;\n                        }, 100);\n\n                        // Handle mousewheel releases\n                        if (!mwTimerRelease) {\n                            mwTimerRelease = setTimeout(function () {\n                                if (mwTimerStop)\n                                    s.rH(v);\n                                mwTimerRelease = null;\n                            }, 200);\n                        }\n                    }\n                },\n                kval,\n                to,\n                m = 1,\n                kv = {\n                    37: -s.o.step,\n                    38: s.o.step,\n                    39: s.o.step,\n                    40: -s.o.step\n                };\n\n            this.$\n                .bind(\n                    \"keydown\",\n                    function (e) {\n                        var kc = e.keyCode;\n\n                        // numpad support\n                        if (kc >= 96 && kc <= 105) {\n                            kc = e.keyCode = kc - 48;\n                        }\n\n                        kval = parseInt(String.fromCharCode(kc));\n\n                        if (isNaN(kval)) {\n                            (kc !== 13)                     // enter\n                            && kc !== 8                     // bs\n                            && kc !== 9                     // tab\n                            && kc !== 189                   // -\n                            && (kc !== 190\n                                || s.$.val().match(/\\./))   // . allowed once\n                            && e.preventDefault();\n\n                            // arrows\n                            if ($.inArray(kc,[37,38,39,40]) > -1) {\n                                e.preventDefault();\n\n                                var v = s.o.parse(s.$.val()) + kv[kc] * m;\n                                s.o.stopper && (v = max(min(v, s.o.max), s.o.min));\n\n                                s.change(s._validate(v));\n                                s._draw();\n\n                                // long time keydown speed-up\n                                to = window.setTimeout(function () {\n                                    m *= 2;\n                                }, 30);\n                            }\n                        }\n                    }\n                )\n                .bind(\n                    \"keyup\",\n                    function (e) {\n                        if (isNaN(kval)) {\n                            if (to) {\n                                window.clearTimeout(to);\n                                to = null;\n                                m = 1;\n                                s.val(s.$.val());\n                            }\n                        } else {\n                            // kval postcond\n                            (s.$.val() > s.o.max && s.$.val(s.o.max))\n                            || (s.$.val() < s.o.min && s.$.val(s.o.min));\n                        }\n                    }\n                );\n\n            this.$c.bind(\"mousewheel DOMMouseScroll\", mw);\n            this.$.bind(\"mousewheel DOMMouseScroll\", mw);\n        };\n\n        this.init = function () {\n            if (this.v < this.o.min\n                || this.v > this.o.max) { this.v = this.o.min; }\n\n            this.$.val(this.v);\n            this.w2 = this.w / 2;\n            this.cursorExt = this.o.cursor / 100;\n            this.xy = this.w2 * this.scale;\n            this.lineWidth = this.xy * this.o.thickness;\n            this.lineCap = this.o.lineCap;\n            this.radius = this.xy - this.lineWidth / 2;\n\n            this.o.angleOffset\n            && (this.o.angleOffset = isNaN(this.o.angleOffset) ? 0 : this.o.angleOffset);\n\n            this.o.angleArc\n            && (this.o.angleArc = isNaN(this.o.angleArc) ? this.PI2 : this.o.angleArc);\n\n            // deg to rad\n            this.angleOffset = this.o.angleOffset * Math.PI / 180;\n            this.angleArc = this.o.angleArc * Math.PI / 180;\n\n            // compute start and end angles\n            this.startAngle = 1.5 * Math.PI + this.angleOffset;\n            this.endAngle = 1.5 * Math.PI + this.angleOffset + this.angleArc;\n\n            var s = max(\n                String(Math.abs(this.o.max)).length,\n                String(Math.abs(this.o.min)).length,\n                2\n            ) + 2;\n\n            this.o.displayInput\n                && this.i.css({\n                        'width' : ((this.w / 2 + 4) >> 0) + 'px',\n                        'height' : ((this.w / 3) >> 0) + 'px',\n                        'position' : 'absolute',\n                        'vertical-align' : 'middle',\n                        'margin-top' : ((this.w / 3) >> 0) + 'px',\n                        'margin-left' : '-' + ((this.w * 3 / 4 + 2) >> 0) + 'px',\n                        'border' : 0,\n                        'background' : 'none',\n                        'font' : this.o.fontWeight + ' ' + ((this.w / s) >> 0) + 'px ' + this.o.font,\n                        'text-align' : 'center',\n                        'color' : this.o.inputColor || this.o.fgColor,\n                        'padding' : '0px',\n                        '-webkit-appearance': 'none'\n                        }) || this.i.css({\n                            'width': '0px',\n                            'visibility': 'hidden'\n                        });\n        };\n\n        this.change = function (v) {\n            this.cv = v;\n            this.$.val(this.o.format(v));\n        };\n\n        this.angle = function (v) {\n            return (v - this.o.min) * this.angleArc / (this.o.max - this.o.min);\n        };\n\n        this.arc = function (v) {\n          var sa, ea;\n          v = this.angle(v);\n          if (this.o.flip) {\n              sa = this.endAngle + 0.00001;\n              ea = sa - v - 0.00001;\n          } else {\n              sa = this.startAngle - 0.00001;\n              ea = sa + v + 0.00001;\n          }\n          this.o.cursor\n              && (sa = ea - this.cursorExt)\n              && (ea = ea + this.cursorExt);\n\n          return {\n              s: sa,\n              e: ea,\n              d: this.o.flip && !this.o.cursor\n          };\n        };\n\n        this.draw = function () {\n            var c = this.g,                 // context\n                a = this.arc(this.cv),      // Arc\n                pa,                         // Previous arc\n                r = 1;\n\n            c.lineWidth = this.lineWidth;\n            c.lineCap = this.lineCap;\n\n            if (this.o.bgColor !== \"none\") {\n                c.beginPath();\n                    c.strokeStyle = this.o.bgColor;\n                    c.arc(this.xy, this.xy, this.radius, this.endAngle - 0.00001, this.startAngle + 0.00001, true);\n                c.stroke();\n            }\n\n            if (this.o.displayPrevious) {\n                pa = this.arc(this.v);\n                c.beginPath();\n                c.strokeStyle = this.pColor;\n                c.arc(this.xy, this.xy, this.radius, pa.s, pa.e, pa.d);\n                c.stroke();\n                r = this.cv == this.v;\n            }\n\n            c.beginPath();\n            c.strokeStyle = r ? this.o.fgColor : this.fgColor ;\n            c.arc(this.xy, this.xy, this.radius, a.s, a.e, a.d);\n            c.stroke();\n        };\n\n        this.cancel = function () {\n            this.val(this.v);\n        };\n    };\n\n    $.fn.dial = $.fn.knob = function (o) {\n        return this.each(\n            function () {\n                var d = new k.Dial();\n                d.o = o;\n                d.$ = $(this);\n                d.run();\n            }\n        ).parent();\n    };\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/jquery.easy-pie-chart/dist/angular.easypiechart.js",
    "content": "/**!\n * easyPieChart\n * Lightweight plugin to render simple, animated and retina optimized pie charts\n *\n * @license \n * @author Robert Fleischmann <rendro87@gmail.com> (http://robert-fleischmann.de)\n * @version 2.1.6\n **/\n\n(function(root, factory) {\n    if(typeof exports === 'object') {\n        module.exports = factory(require('angular'));\n    }\n    else if(typeof define === 'function' && define.amd) {\n        define(['angular'], factory);\n    }\n    else {\n        factory(root.angular);\n    }\n}(this, function(angular) {\n\n(function (angular) {\n\n\t'use strict';\n\n\treturn angular.module('easypiechart', [])\n\n\t\t.directive('easypiechart', [function() {\n\t\t\treturn {\n\t\t\t\trestrict: 'A',\n\t\t\t\trequire: '?ngModel',\n\t\t\t\tscope: {\n\t\t\t\t\tpercent: '=',\n\t\t\t\t\toptions: '='\n\t\t\t\t},\n\t\t\t\tlink: function (scope, element, attrs) {\n\n\t\t\t\t\tscope.percent = scope.percent || 0;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * default easy pie chart options\n\t\t\t\t\t * @type {Object}\n\t\t\t\t\t */\n\t\t\t\t\tvar options = {\n\t\t\t\t\t\tbarColor: '#ef1e25',\n\t\t\t\t\t\ttrackColor: '#f9f9f9',\n\t\t\t\t\t\tscaleColor: '#dfe0e0',\n\t\t\t\t\t\tscaleLength: 5,\n\t\t\t\t\t\tlineCap: 'round',\n\t\t\t\t\t\tlineWidth: 3,\n\t\t\t\t\t\tsize: 110,\n\t\t\t\t\t\trotate: 0,\n\t\t\t\t\t\tanimate: {\n\t\t\t\t\t\t\tduration: 1000,\n\t\t\t\t\t\t\tenabled: true\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\tscope.options = angular.extend(options, scope.options);\n\n\t\t\t\t\tvar pieChart = new EasyPieChart(element[0], options);\n\n\t\t\t\t\tscope.$watch('percent', function(newVal, oldVal) {\n\t\t\t\t\t\tpieChart.update(newVal);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t};\n\t\t}]);\n\n})(angular);\n/**\n * Renderer to render the chart on a canvas object\n * @param {DOMElement} el      DOM element to host the canvas (root of the plugin)\n * @param {object}     options options object of the plugin\n */\nvar CanvasRenderer = function(el, options) {\n\tvar cachedBackground;\n\tvar canvas = document.createElement('canvas');\n\n\tel.appendChild(canvas);\n\n\tif (typeof(G_vmlCanvasManager) !== 'undefined') {\n\t\tG_vmlCanvasManager.initElement(canvas);\n\t}\n\n\tvar ctx = canvas.getContext('2d');\n\n\tcanvas.width = canvas.height = options.size;\n\n\t// canvas on retina devices\n\tvar scaleBy = 1;\n\tif (window.devicePixelRatio > 1) {\n\t\tscaleBy = window.devicePixelRatio;\n\t\tcanvas.style.width = canvas.style.height = [options.size, 'px'].join('');\n\t\tcanvas.width = canvas.height = options.size * scaleBy;\n\t\tctx.scale(scaleBy, scaleBy);\n\t}\n\n\t// move 0,0 coordinates to the center\n\tctx.translate(options.size / 2, options.size / 2);\n\n\t// rotate canvas -90deg\n\tctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);\n\n\tvar radius = (options.size - options.lineWidth) / 2;\n\tif (options.scaleColor && options.scaleLength) {\n\t\tradius -= options.scaleLength + 2; // 2 is the distance between scale and bar\n\t}\n\n\t// IE polyfill for Date\n\tDate.now = Date.now || function() {\n\t\treturn +(new Date());\n\t};\n\n\t/**\n\t * Draw a circle around the center of the canvas\n\t * @param {strong} color     Valid CSS color string\n\t * @param {number} lineWidth Width of the line in px\n\t * @param {number} percent   Percentage to draw (float between -1 and 1)\n\t */\n\tvar drawCircle = function(color, lineWidth, percent) {\n\t\tpercent = Math.min(Math.max(-1, percent || 0), 1);\n\t\tvar isNegative = percent <= 0 ? true : false;\n\n\t\tctx.beginPath();\n\t\tctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, isNegative);\n\n\t\tctx.strokeStyle = color;\n\t\tctx.lineWidth = lineWidth;\n\n\t\tctx.stroke();\n\t};\n\n\t/**\n\t * Draw the scale of the chart\n\t */\n\tvar drawScale = function() {\n\t\tvar offset;\n\t\tvar length;\n\n\t\tctx.lineWidth = 1;\n\t\tctx.fillStyle = options.scaleColor;\n\n\t\tctx.save();\n\t\tfor (var i = 24; i > 0; --i) {\n\t\t\tif (i % 6 === 0) {\n\t\t\t\tlength = options.scaleLength;\n\t\t\t\toffset = 0;\n\t\t\t} else {\n\t\t\t\tlength = options.scaleLength * 0.6;\n\t\t\t\toffset = options.scaleLength - length;\n\t\t\t}\n\t\t\tctx.fillRect(-options.size/2 + offset, 0, length, 1);\n\t\t\tctx.rotate(Math.PI / 12);\n\t\t}\n\t\tctx.restore();\n\t};\n\n\t/**\n\t * Request animation frame wrapper with polyfill\n\t * @return {function} Request animation frame method or timeout fallback\n\t */\n\tvar reqAnimationFrame = (function() {\n\t\treturn  window.requestAnimationFrame ||\n\t\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\t\tfunction(callback) {\n\t\t\t\t\twindow.setTimeout(callback, 1000 / 60);\n\t\t\t\t};\n\t}());\n\n\t/**\n\t * Draw the background of the plugin including the scale and the track\n\t */\n\tvar drawBackground = function() {\n\t\tif(options.scaleColor) drawScale();\n\t\tif(options.trackColor) drawCircle(options.trackColor, options.trackWidth || options.lineWidth, 1);\n\t};\n\n  /**\n    * Canvas accessor\n   */\n  this.getCanvas = function() {\n    return canvas;\n  };\n\n  /**\n    * Canvas 2D context 'ctx' accessor\n   */\n  this.getCtx = function() {\n    return ctx;\n  };\n\n\t/**\n\t * Clear the complete canvas\n\t */\n\tthis.clear = function() {\n\t\tctx.clearRect(options.size / -2, options.size / -2, options.size, options.size);\n\t};\n\n\t/**\n\t * Draw the complete chart\n\t * @param {number} percent Percent shown by the chart between -100 and 100\n\t */\n\tthis.draw = function(percent) {\n\t\t// do we need to render a background\n\t\tif (!!options.scaleColor || !!options.trackColor) {\n\t\t\t// getImageData and putImageData are supported\n\t\t\tif (ctx.getImageData && ctx.putImageData) {\n\t\t\t\tif (!cachedBackground) {\n\t\t\t\t\tdrawBackground();\n\t\t\t\t\tcachedBackground = ctx.getImageData(0, 0, options.size * scaleBy, options.size * scaleBy);\n\t\t\t\t} else {\n\t\t\t\t\tctx.putImageData(cachedBackground, 0, 0);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.clear();\n\t\t\t\tdrawBackground();\n\t\t\t}\n\t\t} else {\n\t\t\tthis.clear();\n\t\t}\n\n\t\tctx.lineCap = options.lineCap;\n\n\t\t// if barcolor is a function execute it and pass the percent as a value\n\t\tvar color;\n\t\tif (typeof(options.barColor) === 'function') {\n\t\t\tcolor = options.barColor(percent);\n\t\t} else {\n\t\t\tcolor = options.barColor;\n\t\t}\n\n\t\t// draw bar\n\t\tdrawCircle(color, options.lineWidth, percent / 100);\n\t}.bind(this);\n\n\t/**\n\t * Animate from some percent to some other percentage\n\t * @param {number} from Starting percentage\n\t * @param {number} to   Final percentage\n\t */\n\tthis.animate = function(from, to) {\n\t\tvar startTime = Date.now();\n\t\toptions.onStart(from, to);\n\t\tvar animation = function() {\n\t\t\tvar process = Math.min(Date.now() - startTime, options.animate.duration);\n\t\t\tvar currentValue = options.easing(this, process, from, to - from, options.animate.duration);\n\t\t\tthis.draw(currentValue);\n\t\t\toptions.onStep(from, to, currentValue);\n\t\t\tif (process >= options.animate.duration) {\n\t\t\t\toptions.onStop(from, to);\n\t\t\t} else {\n\t\t\t\treqAnimationFrame(animation);\n\t\t\t}\n\t\t}.bind(this);\n\n\t\treqAnimationFrame(animation);\n\t}.bind(this);\n};\n\nvar EasyPieChart = function(el, opts) {\n\tvar defaultOptions = {\n\t\tbarColor: '#ef1e25',\n\t\ttrackColor: '#f9f9f9',\n\t\tscaleColor: '#dfe0e0',\n\t\tscaleLength: 5,\n\t\tlineCap: 'round',\n\t\tlineWidth: 3,\n\t\ttrackWidth: undefined,\n\t\tsize: 110,\n\t\trotate: 0,\n\t\tanimate: {\n\t\t\tduration: 1000,\n\t\t\tenabled: true\n\t\t},\n\t\teasing: function (x, t, b, c, d) { // more can be found here: http://gsgd.co.uk/sandbox/jquery/easing/\n\t\t\tt = t / (d/2);\n\t\t\tif (t < 1) {\n\t\t\t\treturn c / 2 * t * t + b;\n\t\t\t}\n\t\t\treturn -c/2 * ((--t)*(t-2) - 1) + b;\n\t\t},\n\t\tonStart: function(from, to) {\n\t\t\treturn;\n\t\t},\n\t\tonStep: function(from, to, currentValue) {\n\t\t\treturn;\n\t\t},\n\t\tonStop: function(from, to) {\n\t\t\treturn;\n\t\t}\n\t};\n\n\t// detect present renderer\n\tif (typeof(CanvasRenderer) !== 'undefined') {\n\t\tdefaultOptions.renderer = CanvasRenderer;\n\t} else if (typeof(SVGRenderer) !== 'undefined') {\n\t\tdefaultOptions.renderer = SVGRenderer;\n\t} else {\n\t\tthrow new Error('Please load either the SVG- or the CanvasRenderer');\n\t}\n\n\tvar options = {};\n\tvar currentValue = 0;\n\n\t/**\n\t * Initialize the plugin by creating the options object and initialize rendering\n\t */\n\tvar init = function() {\n\t\tthis.el = el;\n\t\tthis.options = options;\n\n\t\t// merge user options into default options\n\t\tfor (var i in defaultOptions) {\n\t\t\tif (defaultOptions.hasOwnProperty(i)) {\n\t\t\t\toptions[i] = opts && typeof(opts[i]) !== 'undefined' ? opts[i] : defaultOptions[i];\n\t\t\t\tif (typeof(options[i]) === 'function') {\n\t\t\t\t\toptions[i] = options[i].bind(this);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// check for jQuery easing\n\t\tif (typeof(options.easing) === 'string' && typeof(jQuery) !== 'undefined' && jQuery.isFunction(jQuery.easing[options.easing])) {\n\t\t\toptions.easing = jQuery.easing[options.easing];\n\t\t} else {\n\t\t\toptions.easing = defaultOptions.easing;\n\t\t}\n\n\t\t// process earlier animate option to avoid bc breaks\n\t\tif (typeof(options.animate) === 'number') {\n\t\t\toptions.animate = {\n\t\t\t\tduration: options.animate,\n\t\t\t\tenabled: true\n\t\t\t};\n\t\t}\n\n\t\tif (typeof(options.animate) === 'boolean' && !options.animate) {\n\t\t\toptions.animate = {\n\t\t\t\tduration: 1000,\n\t\t\t\tenabled: options.animate\n\t\t\t};\n\t\t}\n\n\t\t// create renderer\n\t\tthis.renderer = new options.renderer(el, options);\n\n\t\t// initial draw\n\t\tthis.renderer.draw(currentValue);\n\n\t\t// initial update\n\t\tif (el.dataset && el.dataset.percent) {\n\t\t\tthis.update(parseFloat(el.dataset.percent));\n\t\t} else if (el.getAttribute && el.getAttribute('data-percent')) {\n\t\t\tthis.update(parseFloat(el.getAttribute('data-percent')));\n\t\t}\n\t}.bind(this);\n\n\t/**\n\t * Update the value of the chart\n\t * @param  {number} newValue Number between 0 and 100\n\t * @return {object}          Instance of the plugin for method chaining\n\t */\n\tthis.update = function(newValue) {\n\t\tnewValue = parseFloat(newValue);\n\t\tif (options.animate.enabled) {\n\t\t\tthis.renderer.animate(currentValue, newValue);\n\t\t} else {\n\t\t\tthis.renderer.draw(newValue);\n\t\t}\n\t\tcurrentValue = newValue;\n\t\treturn this;\n\t}.bind(this);\n\n\t/**\n\t * Disable animation\n\t * @return {object} Instance of the plugin for method chaining\n\t */\n\tthis.disableAnimation = function() {\n\t\toptions.animate.enabled = false;\n\t\treturn this;\n\t};\n\n\t/**\n\t * Enable animation\n\t * @return {object} Instance of the plugin for method chaining\n\t */\n\tthis.enableAnimation = function() {\n\t\toptions.animate.enabled = true;\n\t\treturn this;\n\t};\n\n\tinit();\n};\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/jquery.easy-pie-chart/dist/easypiechart.js",
    "content": "/**!\n * easyPieChart\n * Lightweight plugin to render simple, animated and retina optimized pie charts\n *\n * @license \n * @author Robert Fleischmann <rendro87@gmail.com> (http://robert-fleischmann.de)\n * @version 2.1.6\n **/\n\n(function(root, factory) {\n    if(typeof exports === 'object') {\n        module.exports = factory();\n    }\n    else if(typeof define === 'function' && define.amd) {\n        define([], factory);\n    }\n    else {\n        root['EasyPieChart'] = factory();\n    }\n}(this, function() {\n\n/**\n * Renderer to render the chart on a canvas object\n * @param {DOMElement} el      DOM element to host the canvas (root of the plugin)\n * @param {object}     options options object of the plugin\n */\nvar CanvasRenderer = function(el, options) {\n\tvar cachedBackground;\n\tvar canvas = document.createElement('canvas');\n\n\tel.appendChild(canvas);\n\n\tif (typeof(G_vmlCanvasManager) !== 'undefined') {\n\t\tG_vmlCanvasManager.initElement(canvas);\n\t}\n\n\tvar ctx = canvas.getContext('2d');\n\n\tcanvas.width = canvas.height = options.size;\n\n\t// canvas on retina devices\n\tvar scaleBy = 1;\n\tif (window.devicePixelRatio > 1) {\n\t\tscaleBy = window.devicePixelRatio;\n\t\tcanvas.style.width = canvas.style.height = [options.size, 'px'].join('');\n\t\tcanvas.width = canvas.height = options.size * scaleBy;\n\t\tctx.scale(scaleBy, scaleBy);\n\t}\n\n\t// move 0,0 coordinates to the center\n\tctx.translate(options.size / 2, options.size / 2);\n\n\t// rotate canvas -90deg\n\tctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);\n\n\tvar radius = (options.size - options.lineWidth) / 2;\n\tif (options.scaleColor && options.scaleLength) {\n\t\tradius -= options.scaleLength + 2; // 2 is the distance between scale and bar\n\t}\n\n\t// IE polyfill for Date\n\tDate.now = Date.now || function() {\n\t\treturn +(new Date());\n\t};\n\n\t/**\n\t * Draw a circle around the center of the canvas\n\t * @param {strong} color     Valid CSS color string\n\t * @param {number} lineWidth Width of the line in px\n\t * @param {number} percent   Percentage to draw (float between -1 and 1)\n\t */\n\tvar drawCircle = function(color, lineWidth, percent) {\n\t\tpercent = Math.min(Math.max(-1, percent || 0), 1);\n\t\tvar isNegative = percent <= 0 ? true : false;\n\n\t\tctx.beginPath();\n\t\tctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, isNegative);\n\n\t\tctx.strokeStyle = color;\n\t\tctx.lineWidth = lineWidth;\n\n\t\tctx.stroke();\n\t};\n\n\t/**\n\t * Draw the scale of the chart\n\t */\n\tvar drawScale = function() {\n\t\tvar offset;\n\t\tvar length;\n\n\t\tctx.lineWidth = 1;\n\t\tctx.fillStyle = options.scaleColor;\n\n\t\tctx.save();\n\t\tfor (var i = 24; i > 0; --i) {\n\t\t\tif (i % 6 === 0) {\n\t\t\t\tlength = options.scaleLength;\n\t\t\t\toffset = 0;\n\t\t\t} else {\n\t\t\t\tlength = options.scaleLength * 0.6;\n\t\t\t\toffset = options.scaleLength - length;\n\t\t\t}\n\t\t\tctx.fillRect(-options.size/2 + offset, 0, length, 1);\n\t\t\tctx.rotate(Math.PI / 12);\n\t\t}\n\t\tctx.restore();\n\t};\n\n\t/**\n\t * Request animation frame wrapper with polyfill\n\t * @return {function} Request animation frame method or timeout fallback\n\t */\n\tvar reqAnimationFrame = (function() {\n\t\treturn  window.requestAnimationFrame ||\n\t\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\t\tfunction(callback) {\n\t\t\t\t\twindow.setTimeout(callback, 1000 / 60);\n\t\t\t\t};\n\t}());\n\n\t/**\n\t * Draw the background of the plugin including the scale and the track\n\t */\n\tvar drawBackground = function() {\n\t\tif(options.scaleColor) drawScale();\n\t\tif(options.trackColor) drawCircle(options.trackColor, options.trackWidth || options.lineWidth, 1);\n\t};\n\n  /**\n    * Canvas accessor\n   */\n  this.getCanvas = function() {\n    return canvas;\n  };\n\n  /**\n    * Canvas 2D context 'ctx' accessor\n   */\n  this.getCtx = function() {\n    return ctx;\n  };\n\n\t/**\n\t * Clear the complete canvas\n\t */\n\tthis.clear = function() {\n\t\tctx.clearRect(options.size / -2, options.size / -2, options.size, options.size);\n\t};\n\n\t/**\n\t * Draw the complete chart\n\t * @param {number} percent Percent shown by the chart between -100 and 100\n\t */\n\tthis.draw = function(percent) {\n\t\t// do we need to render a background\n\t\tif (!!options.scaleColor || !!options.trackColor) {\n\t\t\t// getImageData and putImageData are supported\n\t\t\tif (ctx.getImageData && ctx.putImageData) {\n\t\t\t\tif (!cachedBackground) {\n\t\t\t\t\tdrawBackground();\n\t\t\t\t\tcachedBackground = ctx.getImageData(0, 0, options.size * scaleBy, options.size * scaleBy);\n\t\t\t\t} else {\n\t\t\t\t\tctx.putImageData(cachedBackground, 0, 0);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.clear();\n\t\t\t\tdrawBackground();\n\t\t\t}\n\t\t} else {\n\t\t\tthis.clear();\n\t\t}\n\n\t\tctx.lineCap = options.lineCap;\n\n\t\t// if barcolor is a function execute it and pass the percent as a value\n\t\tvar color;\n\t\tif (typeof(options.barColor) === 'function') {\n\t\t\tcolor = options.barColor(percent);\n\t\t} else {\n\t\t\tcolor = options.barColor;\n\t\t}\n\n\t\t// draw bar\n\t\tdrawCircle(color, options.lineWidth, percent / 100);\n\t}.bind(this);\n\n\t/**\n\t * Animate from some percent to some other percentage\n\t * @param {number} from Starting percentage\n\t * @param {number} to   Final percentage\n\t */\n\tthis.animate = function(from, to) {\n\t\tvar startTime = Date.now();\n\t\toptions.onStart(from, to);\n\t\tvar animation = function() {\n\t\t\tvar process = Math.min(Date.now() - startTime, options.animate.duration);\n\t\t\tvar currentValue = options.easing(this, process, from, to - from, options.animate.duration);\n\t\t\tthis.draw(currentValue);\n\t\t\toptions.onStep(from, to, currentValue);\n\t\t\tif (process >= options.animate.duration) {\n\t\t\t\toptions.onStop(from, to);\n\t\t\t} else {\n\t\t\t\treqAnimationFrame(animation);\n\t\t\t}\n\t\t}.bind(this);\n\n\t\treqAnimationFrame(animation);\n\t}.bind(this);\n};\n\nvar EasyPieChart = function(el, opts) {\n\tvar defaultOptions = {\n\t\tbarColor: '#ef1e25',\n\t\ttrackColor: '#f9f9f9',\n\t\tscaleColor: '#dfe0e0',\n\t\tscaleLength: 5,\n\t\tlineCap: 'round',\n\t\tlineWidth: 3,\n\t\ttrackWidth: undefined,\n\t\tsize: 110,\n\t\trotate: 0,\n\t\tanimate: {\n\t\t\tduration: 1000,\n\t\t\tenabled: true\n\t\t},\n\t\teasing: function (x, t, b, c, d) { // more can be found here: http://gsgd.co.uk/sandbox/jquery/easing/\n\t\t\tt = t / (d/2);\n\t\t\tif (t < 1) {\n\t\t\t\treturn c / 2 * t * t + b;\n\t\t\t}\n\t\t\treturn -c/2 * ((--t)*(t-2) - 1) + b;\n\t\t},\n\t\tonStart: function(from, to) {\n\t\t\treturn;\n\t\t},\n\t\tonStep: function(from, to, currentValue) {\n\t\t\treturn;\n\t\t},\n\t\tonStop: function(from, to) {\n\t\t\treturn;\n\t\t}\n\t};\n\n\t// detect present renderer\n\tif (typeof(CanvasRenderer) !== 'undefined') {\n\t\tdefaultOptions.renderer = CanvasRenderer;\n\t} else if (typeof(SVGRenderer) !== 'undefined') {\n\t\tdefaultOptions.renderer = SVGRenderer;\n\t} else {\n\t\tthrow new Error('Please load either the SVG- or the CanvasRenderer');\n\t}\n\n\tvar options = {};\n\tvar currentValue = 0;\n\n\t/**\n\t * Initialize the plugin by creating the options object and initialize rendering\n\t */\n\tvar init = function() {\n\t\tthis.el = el;\n\t\tthis.options = options;\n\n\t\t// merge user options into default options\n\t\tfor (var i in defaultOptions) {\n\t\t\tif (defaultOptions.hasOwnProperty(i)) {\n\t\t\t\toptions[i] = opts && typeof(opts[i]) !== 'undefined' ? opts[i] : defaultOptions[i];\n\t\t\t\tif (typeof(options[i]) === 'function') {\n\t\t\t\t\toptions[i] = options[i].bind(this);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// check for jQuery easing\n\t\tif (typeof(options.easing) === 'string' && typeof(jQuery) !== 'undefined' && jQuery.isFunction(jQuery.easing[options.easing])) {\n\t\t\toptions.easing = jQuery.easing[options.easing];\n\t\t} else {\n\t\t\toptions.easing = defaultOptions.easing;\n\t\t}\n\n\t\t// process earlier animate option to avoid bc breaks\n\t\tif (typeof(options.animate) === 'number') {\n\t\t\toptions.animate = {\n\t\t\t\tduration: options.animate,\n\t\t\t\tenabled: true\n\t\t\t};\n\t\t}\n\n\t\tif (typeof(options.animate) === 'boolean' && !options.animate) {\n\t\t\toptions.animate = {\n\t\t\t\tduration: 1000,\n\t\t\t\tenabled: options.animate\n\t\t\t};\n\t\t}\n\n\t\t// create renderer\n\t\tthis.renderer = new options.renderer(el, options);\n\n\t\t// initial draw\n\t\tthis.renderer.draw(currentValue);\n\n\t\t// initial update\n\t\tif (el.dataset && el.dataset.percent) {\n\t\t\tthis.update(parseFloat(el.dataset.percent));\n\t\t} else if (el.getAttribute && el.getAttribute('data-percent')) {\n\t\t\tthis.update(parseFloat(el.getAttribute('data-percent')));\n\t\t}\n\t}.bind(this);\n\n\t/**\n\t * Update the value of the chart\n\t * @param  {number} newValue Number between 0 and 100\n\t * @return {object}          Instance of the plugin for method chaining\n\t */\n\tthis.update = function(newValue) {\n\t\tnewValue = parseFloat(newValue);\n\t\tif (options.animate.enabled) {\n\t\t\tthis.renderer.animate(currentValue, newValue);\n\t\t} else {\n\t\t\tthis.renderer.draw(newValue);\n\t\t}\n\t\tcurrentValue = newValue;\n\t\treturn this;\n\t}.bind(this);\n\n\t/**\n\t * Disable animation\n\t * @return {object} Instance of the plugin for method chaining\n\t */\n\tthis.disableAnimation = function() {\n\t\toptions.animate.enabled = false;\n\t\treturn this;\n\t};\n\n\t/**\n\t * Enable animation\n\t * @return {object} Instance of the plugin for method chaining\n\t */\n\tthis.enableAnimation = function() {\n\t\toptions.animate.enabled = true;\n\t\treturn this;\n\t};\n\n\tinit();\n};\n\n\nreturn EasyPieChart;\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/jquery.easy-pie-chart/dist/jquery.easypiechart.js",
    "content": "/**!\n * easyPieChart\n * Lightweight plugin to render simple, animated and retina optimized pie charts\n *\n * @license \n * @author Robert Fleischmann <rendro87@gmail.com> (http://robert-fleischmann.de)\n * @version 2.1.6\n **/\n\n(function(root, factory) {\n    if(typeof exports === 'object') {\n        module.exports = factory(require('jquery'));\n    }\n    else if(typeof define === 'function' && define.amd) {\n        define(['jquery'], factory);\n    }\n    else {\n        factory(root.jQuery);\n    }\n}(this, function($) {\n\n/**\n * Renderer to render the chart on a canvas object\n * @param {DOMElement} el      DOM element to host the canvas (root of the plugin)\n * @param {object}     options options object of the plugin\n */\nvar CanvasRenderer = function(el, options) {\n\tvar cachedBackground;\n\tvar canvas = document.createElement('canvas');\n\n\tel.appendChild(canvas);\n\n\tif (typeof(G_vmlCanvasManager) !== 'undefined') {\n\t\tG_vmlCanvasManager.initElement(canvas);\n\t}\n\n\tvar ctx = canvas.getContext('2d');\n\n\tcanvas.width = canvas.height = options.size;\n\n\t// canvas on retina devices\n\tvar scaleBy = 1;\n\tif (window.devicePixelRatio > 1) {\n\t\tscaleBy = window.devicePixelRatio;\n\t\tcanvas.style.width = canvas.style.height = [options.size, 'px'].join('');\n\t\tcanvas.width = canvas.height = options.size * scaleBy;\n\t\tctx.scale(scaleBy, scaleBy);\n\t}\n\n\t// move 0,0 coordinates to the center\n\tctx.translate(options.size / 2, options.size / 2);\n\n\t// rotate canvas -90deg\n\tctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);\n\n\tvar radius = (options.size - options.lineWidth) / 2;\n\tif (options.scaleColor && options.scaleLength) {\n\t\tradius -= options.scaleLength + 2; // 2 is the distance between scale and bar\n\t}\n\n\t// IE polyfill for Date\n\tDate.now = Date.now || function() {\n\t\treturn +(new Date());\n\t};\n\n\t/**\n\t * Draw a circle around the center of the canvas\n\t * @param {strong} color     Valid CSS color string\n\t * @param {number} lineWidth Width of the line in px\n\t * @param {number} percent   Percentage to draw (float between -1 and 1)\n\t */\n\tvar drawCircle = function(color, lineWidth, percent) {\n\t\tpercent = Math.min(Math.max(-1, percent || 0), 1);\n\t\tvar isNegative = percent <= 0 ? true : false;\n\n\t\tctx.beginPath();\n\t\tctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, isNegative);\n\n\t\tctx.strokeStyle = color;\n\t\tctx.lineWidth = lineWidth;\n\n\t\tctx.stroke();\n\t};\n\n\t/**\n\t * Draw the scale of the chart\n\t */\n\tvar drawScale = function() {\n\t\tvar offset;\n\t\tvar length;\n\n\t\tctx.lineWidth = 1;\n\t\tctx.fillStyle = options.scaleColor;\n\n\t\tctx.save();\n\t\tfor (var i = 24; i > 0; --i) {\n\t\t\tif (i % 6 === 0) {\n\t\t\t\tlength = options.scaleLength;\n\t\t\t\toffset = 0;\n\t\t\t} else {\n\t\t\t\tlength = options.scaleLength * 0.6;\n\t\t\t\toffset = options.scaleLength - length;\n\t\t\t}\n\t\t\tctx.fillRect(-options.size/2 + offset, 0, length, 1);\n\t\t\tctx.rotate(Math.PI / 12);\n\t\t}\n\t\tctx.restore();\n\t};\n\n\t/**\n\t * Request animation frame wrapper with polyfill\n\t * @return {function} Request animation frame method or timeout fallback\n\t */\n\tvar reqAnimationFrame = (function() {\n\t\treturn  window.requestAnimationFrame ||\n\t\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\t\tfunction(callback) {\n\t\t\t\t\twindow.setTimeout(callback, 1000 / 60);\n\t\t\t\t};\n\t}());\n\n\t/**\n\t * Draw the background of the plugin including the scale and the track\n\t */\n\tvar drawBackground = function() {\n\t\tif(options.scaleColor) drawScale();\n\t\tif(options.trackColor) drawCircle(options.trackColor, options.trackWidth || options.lineWidth, 1);\n\t};\n\n  /**\n    * Canvas accessor\n   */\n  this.getCanvas = function() {\n    return canvas;\n  };\n\n  /**\n    * Canvas 2D context 'ctx' accessor\n   */\n  this.getCtx = function() {\n    return ctx;\n  };\n\n\t/**\n\t * Clear the complete canvas\n\t */\n\tthis.clear = function() {\n\t\tctx.clearRect(options.size / -2, options.size / -2, options.size, options.size);\n\t};\n\n\t/**\n\t * Draw the complete chart\n\t * @param {number} percent Percent shown by the chart between -100 and 100\n\t */\n\tthis.draw = function(percent) {\n\t\t// do we need to render a background\n\t\tif (!!options.scaleColor || !!options.trackColor) {\n\t\t\t// getImageData and putImageData are supported\n\t\t\tif (ctx.getImageData && ctx.putImageData) {\n\t\t\t\tif (!cachedBackground) {\n\t\t\t\t\tdrawBackground();\n\t\t\t\t\tcachedBackground = ctx.getImageData(0, 0, options.size * scaleBy, options.size * scaleBy);\n\t\t\t\t} else {\n\t\t\t\t\tctx.putImageData(cachedBackground, 0, 0);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.clear();\n\t\t\t\tdrawBackground();\n\t\t\t}\n\t\t} else {\n\t\t\tthis.clear();\n\t\t}\n\n\t\tctx.lineCap = options.lineCap;\n\n\t\t// if barcolor is a function execute it and pass the percent as a value\n\t\tvar color;\n\t\tif (typeof(options.barColor) === 'function') {\n\t\t\tcolor = options.barColor(percent);\n\t\t} else {\n\t\t\tcolor = options.barColor;\n\t\t}\n\n\t\t// draw bar\n\t\tdrawCircle(color, options.lineWidth, percent / 100);\n\t}.bind(this);\n\n\t/**\n\t * Animate from some percent to some other percentage\n\t * @param {number} from Starting percentage\n\t * @param {number} to   Final percentage\n\t */\n\tthis.animate = function(from, to) {\n\t\tvar startTime = Date.now();\n\t\toptions.onStart(from, to);\n\t\tvar animation = function() {\n\t\t\tvar process = Math.min(Date.now() - startTime, options.animate.duration);\n\t\t\tvar currentValue = options.easing(this, process, from, to - from, options.animate.duration);\n\t\t\tthis.draw(currentValue);\n\t\t\toptions.onStep(from, to, currentValue);\n\t\t\tif (process >= options.animate.duration) {\n\t\t\t\toptions.onStop(from, to);\n\t\t\t} else {\n\t\t\t\treqAnimationFrame(animation);\n\t\t\t}\n\t\t}.bind(this);\n\n\t\treqAnimationFrame(animation);\n\t}.bind(this);\n};\n\nvar EasyPieChart = function(el, opts) {\n\tvar defaultOptions = {\n\t\tbarColor: '#ef1e25',\n\t\ttrackColor: '#f9f9f9',\n\t\tscaleColor: '#dfe0e0',\n\t\tscaleLength: 5,\n\t\tlineCap: 'round',\n\t\tlineWidth: 3,\n\t\ttrackWidth: undefined,\n\t\tsize: 110,\n\t\trotate: 0,\n\t\tanimate: {\n\t\t\tduration: 1000,\n\t\t\tenabled: true\n\t\t},\n\t\teasing: function (x, t, b, c, d) { // more can be found here: http://gsgd.co.uk/sandbox/jquery/easing/\n\t\t\tt = t / (d/2);\n\t\t\tif (t < 1) {\n\t\t\t\treturn c / 2 * t * t + b;\n\t\t\t}\n\t\t\treturn -c/2 * ((--t)*(t-2) - 1) + b;\n\t\t},\n\t\tonStart: function(from, to) {\n\t\t\treturn;\n\t\t},\n\t\tonStep: function(from, to, currentValue) {\n\t\t\treturn;\n\t\t},\n\t\tonStop: function(from, to) {\n\t\t\treturn;\n\t\t}\n\t};\n\n\t// detect present renderer\n\tif (typeof(CanvasRenderer) !== 'undefined') {\n\t\tdefaultOptions.renderer = CanvasRenderer;\n\t} else if (typeof(SVGRenderer) !== 'undefined') {\n\t\tdefaultOptions.renderer = SVGRenderer;\n\t} else {\n\t\tthrow new Error('Please load either the SVG- or the CanvasRenderer');\n\t}\n\n\tvar options = {};\n\tvar currentValue = 0;\n\n\t/**\n\t * Initialize the plugin by creating the options object and initialize rendering\n\t */\n\tvar init = function() {\n\t\tthis.el = el;\n\t\tthis.options = options;\n\n\t\t// merge user options into default options\n\t\tfor (var i in defaultOptions) {\n\t\t\tif (defaultOptions.hasOwnProperty(i)) {\n\t\t\t\toptions[i] = opts && typeof(opts[i]) !== 'undefined' ? opts[i] : defaultOptions[i];\n\t\t\t\tif (typeof(options[i]) === 'function') {\n\t\t\t\t\toptions[i] = options[i].bind(this);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// check for jQuery easing\n\t\tif (typeof(options.easing) === 'string' && typeof(jQuery) !== 'undefined' && jQuery.isFunction(jQuery.easing[options.easing])) {\n\t\t\toptions.easing = jQuery.easing[options.easing];\n\t\t} else {\n\t\t\toptions.easing = defaultOptions.easing;\n\t\t}\n\n\t\t// process earlier animate option to avoid bc breaks\n\t\tif (typeof(options.animate) === 'number') {\n\t\t\toptions.animate = {\n\t\t\t\tduration: options.animate,\n\t\t\t\tenabled: true\n\t\t\t};\n\t\t}\n\n\t\tif (typeof(options.animate) === 'boolean' && !options.animate) {\n\t\t\toptions.animate = {\n\t\t\t\tduration: 1000,\n\t\t\t\tenabled: options.animate\n\t\t\t};\n\t\t}\n\n\t\t// create renderer\n\t\tthis.renderer = new options.renderer(el, options);\n\n\t\t// initial draw\n\t\tthis.renderer.draw(currentValue);\n\n\t\t// initial update\n\t\tif (el.dataset && el.dataset.percent) {\n\t\t\tthis.update(parseFloat(el.dataset.percent));\n\t\t} else if (el.getAttribute && el.getAttribute('data-percent')) {\n\t\t\tthis.update(parseFloat(el.getAttribute('data-percent')));\n\t\t}\n\t}.bind(this);\n\n\t/**\n\t * Update the value of the chart\n\t * @param  {number} newValue Number between 0 and 100\n\t * @return {object}          Instance of the plugin for method chaining\n\t */\n\tthis.update = function(newValue) {\n\t\tnewValue = parseFloat(newValue);\n\t\tif (options.animate.enabled) {\n\t\t\tthis.renderer.animate(currentValue, newValue);\n\t\t} else {\n\t\t\tthis.renderer.draw(newValue);\n\t\t}\n\t\tcurrentValue = newValue;\n\t\treturn this;\n\t}.bind(this);\n\n\t/**\n\t * Disable animation\n\t * @return {object} Instance of the plugin for method chaining\n\t */\n\tthis.disableAnimation = function() {\n\t\toptions.animate.enabled = false;\n\t\treturn this;\n\t};\n\n\t/**\n\t * Enable animation\n\t * @return {object} Instance of the plugin for method chaining\n\t */\n\tthis.enableAnimation = function() {\n\t\toptions.animate.enabled = true;\n\t\treturn this;\n\t};\n\n\tinit();\n};\n\n$.fn.easyPieChart = function(options) {\n\treturn this.each(function() {\n\t\tvar instanceOptions;\n\n\t\tif (!$.data(this, 'easyPieChart')) {\n\t\t\tinstanceOptions = $.extend({}, options, $(this).data());\n\t\t\t$.data(this, 'easyPieChart', new EasyPieChart(this, instanceOptions));\n\t\t}\n\t});\n};\n\n\n}));\n"
  },
  {
    "path": "static/assets/plugins/jquery.easy-pie-chart/src/angular.directive.js",
    "content": "(function (angular) {\n\n\t'use strict';\n\n\treturn angular.module('easypiechart', [])\n\n\t\t.directive('easypiechart', [function() {\n\t\t\treturn {\n\t\t\t\trestrict: 'A',\n\t\t\t\trequire: '?ngModel',\n\t\t\t\tscope: {\n\t\t\t\t\tpercent: '=',\n\t\t\t\t\toptions: '='\n\t\t\t\t},\n\t\t\t\tlink: function (scope, element, attrs) {\n\n\t\t\t\t\tscope.percent = scope.percent || 0;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * default easy pie chart options\n\t\t\t\t\t * @type {Object}\n\t\t\t\t\t */\n\t\t\t\t\tvar options = {\n\t\t\t\t\t\tbarColor: '#ef1e25',\n\t\t\t\t\t\ttrackColor: '#f9f9f9',\n\t\t\t\t\t\tscaleColor: '#dfe0e0',\n\t\t\t\t\t\tscaleLength: 5,\n\t\t\t\t\t\tlineCap: 'round',\n\t\t\t\t\t\tlineWidth: 3,\n\t\t\t\t\t\tsize: 110,\n\t\t\t\t\t\trotate: 0,\n\t\t\t\t\t\tanimate: {\n\t\t\t\t\t\t\tduration: 1000,\n\t\t\t\t\t\t\tenabled: true\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\tscope.options = angular.extend(options, scope.options);\n\n\t\t\t\t\tvar pieChart = new EasyPieChart(element[0], options);\n\n\t\t\t\t\tscope.$watch('percent', function(newVal, oldVal) {\n\t\t\t\t\t\tpieChart.update(newVal);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t};\n\t\t}]);\n\n})(angular);"
  },
  {
    "path": "static/assets/plugins/jquery.easy-pie-chart/src/easypiechart.js",
    "content": "var EasyPieChart = function(el, opts) {\n\tvar defaultOptions = {\n\t\tbarColor: '#ef1e25',\n\t\ttrackColor: '#f9f9f9',\n\t\tscaleColor: '#dfe0e0',\n\t\tscaleLength: 5,\n\t\tlineCap: 'round',\n\t\tlineWidth: 3,\n\t\ttrackWidth: undefined,\n\t\tsize: 110,\n\t\trotate: 0,\n\t\tanimate: {\n\t\t\tduration: 1000,\n\t\t\tenabled: true\n\t\t},\n\t\teasing: function (x, t, b, c, d) { // more can be found here: http://gsgd.co.uk/sandbox/jquery/easing/\n\t\t\tt = t / (d/2);\n\t\t\tif (t < 1) {\n\t\t\t\treturn c / 2 * t * t + b;\n\t\t\t}\n\t\t\treturn -c/2 * ((--t)*(t-2) - 1) + b;\n\t\t},\n\t\tonStart: function(from, to) {\n\t\t\treturn;\n\t\t},\n\t\tonStep: function(from, to, currentValue) {\n\t\t\treturn;\n\t\t},\n\t\tonStop: function(from, to) {\n\t\t\treturn;\n\t\t}\n\t};\n\n\t// detect present renderer\n\tif (typeof(CanvasRenderer) !== 'undefined') {\n\t\tdefaultOptions.renderer = CanvasRenderer;\n\t} else if (typeof(SVGRenderer) !== 'undefined') {\n\t\tdefaultOptions.renderer = SVGRenderer;\n\t} else {\n\t\tthrow new Error('Please load either the SVG- or the CanvasRenderer');\n\t}\n\n\tvar options = {};\n\tvar currentValue = 0;\n\n\t/**\n\t * Initialize the plugin by creating the options object and initialize rendering\n\t */\n\tvar init = function() {\n\t\tthis.el = el;\n\t\tthis.options = options;\n\n\t\t// merge user options into default options\n\t\tfor (var i in defaultOptions) {\n\t\t\tif (defaultOptions.hasOwnProperty(i)) {\n\t\t\t\toptions[i] = opts && typeof(opts[i]) !== 'undefined' ? opts[i] : defaultOptions[i];\n\t\t\t\tif (typeof(options[i]) === 'function') {\n\t\t\t\t\toptions[i] = options[i].bind(this);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// check for jQuery easing\n\t\tif (typeof(options.easing) === 'string' && typeof(jQuery) !== 'undefined' && jQuery.isFunction(jQuery.easing[options.easing])) {\n\t\t\toptions.easing = jQuery.easing[options.easing];\n\t\t} else {\n\t\t\toptions.easing = defaultOptions.easing;\n\t\t}\n\n\t\t// process earlier animate option to avoid bc breaks\n\t\tif (typeof(options.animate) === 'number') {\n\t\t\toptions.animate = {\n\t\t\t\tduration: options.animate,\n\t\t\t\tenabled: true\n\t\t\t};\n\t\t}\n\n\t\tif (typeof(options.animate) === 'boolean' && !options.animate) {\n\t\t\toptions.animate = {\n\t\t\t\tduration: 1000,\n\t\t\t\tenabled: options.animate\n\t\t\t};\n\t\t}\n\n\t\t// create renderer\n\t\tthis.renderer = new options.renderer(el, options);\n\n\t\t// initial draw\n\t\tthis.renderer.draw(currentValue);\n\n\t\t// initial update\n\t\tif (el.dataset && el.dataset.percent) {\n\t\t\tthis.update(parseFloat(el.dataset.percent));\n\t\t} else if (el.getAttribute && el.getAttribute('data-percent')) {\n\t\t\tthis.update(parseFloat(el.getAttribute('data-percent')));\n\t\t}\n\t}.bind(this);\n\n\t/**\n\t * Update the value of the chart\n\t * @param  {number} newValue Number between 0 and 100\n\t * @return {object}          Instance of the plugin for method chaining\n\t */\n\tthis.update = function(newValue) {\n\t\tnewValue = parseFloat(newValue);\n\t\tif (options.animate.enabled) {\n\t\t\tthis.renderer.animate(currentValue, newValue);\n\t\t} else {\n\t\t\tthis.renderer.draw(newValue);\n\t\t}\n\t\tcurrentValue = newValue;\n\t\treturn this;\n\t}.bind(this);\n\n\t/**\n\t * Disable animation\n\t * @return {object} Instance of the plugin for method chaining\n\t */\n\tthis.disableAnimation = function() {\n\t\toptions.animate.enabled = false;\n\t\treturn this;\n\t};\n\n\t/**\n\t * Enable animation\n\t * @return {object} Instance of the plugin for method chaining\n\t */\n\tthis.enableAnimation = function() {\n\t\toptions.animate.enabled = true;\n\t\treturn this;\n\t};\n\n\tinit();\n};\n"
  },
  {
    "path": "static/assets/plugins/jquery.easy-pie-chart/src/jquery.plugin.js",
    "content": "$.fn.easyPieChart = function(options) {\n\treturn this.each(function() {\n\t\tvar instanceOptions;\n\n\t\tif (!$.data(this, 'easyPieChart')) {\n\t\t\tinstanceOptions = $.extend({}, options, $(this).data());\n\t\t\t$.data(this, 'easyPieChart', new EasyPieChart(this, instanceOptions));\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "static/assets/plugins/jquery.easy-pie-chart/src/renderer/canvas.js",
    "content": "/**\n * Renderer to render the chart on a canvas object\n * @param {DOMElement} el      DOM element to host the canvas (root of the plugin)\n * @param {object}     options options object of the plugin\n */\nvar CanvasRenderer = function(el, options) {\n\tvar cachedBackground;\n\tvar canvas = document.createElement('canvas');\n\n\tel.appendChild(canvas);\n\n\tif (typeof(G_vmlCanvasManager) !== 'undefined') {\n\t\tG_vmlCanvasManager.initElement(canvas);\n\t}\n\n\tvar ctx = canvas.getContext('2d');\n\n\tcanvas.width = canvas.height = options.size;\n\n\t// canvas on retina devices\n\tvar scaleBy = 1;\n\tif (window.devicePixelRatio > 1) {\n\t\tscaleBy = window.devicePixelRatio;\n\t\tcanvas.style.width = canvas.style.height = [options.size, 'px'].join('');\n\t\tcanvas.width = canvas.height = options.size * scaleBy;\n\t\tctx.scale(scaleBy, scaleBy);\n\t}\n\n\t// move 0,0 coordinates to the center\n\tctx.translate(options.size / 2, options.size / 2);\n\n\t// rotate canvas -90deg\n\tctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);\n\n\tvar radius = (options.size - options.lineWidth) / 2;\n\tif (options.scaleColor && options.scaleLength) {\n\t\tradius -= options.scaleLength + 2; // 2 is the distance between scale and bar\n\t}\n\n\t// IE polyfill for Date\n\tDate.now = Date.now || function() {\n\t\treturn +(new Date());\n\t};\n\n\t/**\n\t * Draw a circle around the center of the canvas\n\t * @param {strong} color     Valid CSS color string\n\t * @param {number} lineWidth Width of the line in px\n\t * @param {number} percent   Percentage to draw (float between -1 and 1)\n\t */\n\tvar drawCircle = function(color, lineWidth, percent) {\n\t\tpercent = Math.min(Math.max(-1, percent || 0), 1);\n\t\tvar isNegative = percent <= 0 ? true : false;\n\n\t\tctx.beginPath();\n\t\tctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, isNegative);\n\n\t\tctx.strokeStyle = color;\n\t\tctx.lineWidth = lineWidth;\n\n\t\tctx.stroke();\n\t};\n\n\t/**\n\t * Draw the scale of the chart\n\t */\n\tvar drawScale = function() {\n\t\tvar offset;\n\t\tvar length;\n\n\t\tctx.lineWidth = 1;\n\t\tctx.fillStyle = options.scaleColor;\n\n\t\tctx.save();\n\t\tfor (var i = 24; i > 0; --i) {\n\t\t\tif (i % 6 === 0) {\n\t\t\t\tlength = options.scaleLength;\n\t\t\t\toffset = 0;\n\t\t\t} else {\n\t\t\t\tlength = options.scaleLength * 0.6;\n\t\t\t\toffset = options.scaleLength - length;\n\t\t\t}\n\t\t\tctx.fillRect(-options.size/2 + offset, 0, length, 1);\n\t\t\tctx.rotate(Math.PI / 12);\n\t\t}\n\t\tctx.restore();\n\t};\n\n\t/**\n\t * Request animation frame wrapper with polyfill\n\t * @return {function} Request animation frame method or timeout fallback\n\t */\n\tvar reqAnimationFrame = (function() {\n\t\treturn  window.requestAnimationFrame ||\n\t\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\t\tfunction(callback) {\n\t\t\t\t\twindow.setTimeout(callback, 1000 / 60);\n\t\t\t\t};\n\t}());\n\n\t/**\n\t * Draw the background of the plugin including the scale and the track\n\t */\n\tvar drawBackground = function() {\n\t\tif(options.scaleColor) drawScale();\n\t\tif(options.trackColor) drawCircle(options.trackColor, options.trackWidth || options.lineWidth, 1);\n\t};\n\n  /**\n    * Canvas accessor\n   */\n  this.getCanvas = function() {\n    return canvas;\n  };\n\n  /**\n    * Canvas 2D context 'ctx' accessor\n   */\n  this.getCtx = function() {\n    return ctx;\n  };\n\n\t/**\n\t * Clear the complete canvas\n\t */\n\tthis.clear = function() {\n\t\tctx.clearRect(options.size / -2, options.size / -2, options.size, options.size);\n\t};\n\n\t/**\n\t * Draw the complete chart\n\t * @param {number} percent Percent shown by the chart between -100 and 100\n\t */\n\tthis.draw = function(percent) {\n\t\t// do we need to render a background\n\t\tif (!!options.scaleColor || !!options.trackColor) {\n\t\t\t// getImageData and putImageData are supported\n\t\t\tif (ctx.getImageData && ctx.putImageData) {\n\t\t\t\tif (!cachedBackground) {\n\t\t\t\t\tdrawBackground();\n\t\t\t\t\tcachedBackground = ctx.getImageData(0, 0, options.size * scaleBy, options.size * scaleBy);\n\t\t\t\t} else {\n\t\t\t\t\tctx.putImageData(cachedBackground, 0, 0);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.clear();\n\t\t\t\tdrawBackground();\n\t\t\t}\n\t\t} else {\n\t\t\tthis.clear();\n\t\t}\n\n\t\tctx.lineCap = options.lineCap;\n\n\t\t// if barcolor is a function execute it and pass the percent as a value\n\t\tvar color;\n\t\tif (typeof(options.barColor) === 'function') {\n\t\t\tcolor = options.barColor(percent);\n\t\t} else {\n\t\t\tcolor = options.barColor;\n\t\t}\n\n\t\t// draw bar\n\t\tdrawCircle(color, options.lineWidth, percent / 100);\n\t}.bind(this);\n\n\t/**\n\t * Animate from some percent to some other percentage\n\t * @param {number} from Starting percentage\n\t * @param {number} to   Final percentage\n\t */\n\tthis.animate = function(from, to) {\n\t\tvar startTime = Date.now();\n\t\toptions.onStart(from, to);\n\t\tvar animation = function() {\n\t\t\tvar process = Math.min(Date.now() - startTime, options.animate.duration);\n\t\t\tvar currentValue = options.easing(this, process, from, to - from, options.animate.duration);\n\t\t\tthis.draw(currentValue);\n\t\t\toptions.onStep(from, to, currentValue);\n\t\t\tif (process >= options.animate.duration) {\n\t\t\t\toptions.onStop(from, to);\n\t\t\t} else {\n\t\t\t\treqAnimationFrame(animation);\n\t\t\t}\n\t\t}.bind(this);\n\n\t\treqAnimationFrame(animation);\n\t}.bind(this);\n};\n"
  },
  {
    "path": "static/assets/plugins/magnific-popup/dist/jquery.magnific-popup.js",
    "content": "/*! Magnific Popup - v1.0.0 - 2014-12-12\n* http://dimsemenov.com/plugins/magnific-popup/\n* Copyright (c) 2014 Dmitry Semenov; */\n;(function (factory) { \nif (typeof define === 'function' && define.amd) { \n // AMD. Register as an anonymous module. \n define(['jquery'], factory); \n } else if (typeof exports === 'object') { \n // Node/CommonJS \n factory(require('jquery')); \n } else { \n // Browser globals \n factory(window.jQuery || window.Zepto); \n } \n }(function($) { \n\n/*>>core*/\n/**\n * \n * Magnific Popup Core JS file\n * \n */\n\n\n/**\n * Private static constants\n */\nvar CLOSE_EVENT = 'Close',\n\tBEFORE_CLOSE_EVENT = 'BeforeClose',\n\tAFTER_CLOSE_EVENT = 'AfterClose',\n\tBEFORE_APPEND_EVENT = 'BeforeAppend',\n\tMARKUP_PARSE_EVENT = 'MarkupParse',\n\tOPEN_EVENT = 'Open',\n\tCHANGE_EVENT = 'Change',\n\tNS = 'mfp',\n\tEVENT_NS = '.' + NS,\n\tREADY_CLASS = 'mfp-ready',\n\tREMOVING_CLASS = 'mfp-removing',\n\tPREVENT_CLOSE_CLASS = 'mfp-prevent-close';\n\n\n/**\n * Private vars \n */\nvar mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this'\n\tMagnificPopup = function(){},\n\t_isJQ = !!(window.jQuery),\n\t_prevStatus,\n\t_window = $(window),\n\t_body,\n\t_document,\n\t_prevContentType,\n\t_wrapClasses,\n\t_currPopupType;\n\n\n/**\n * Private functions\n */\nvar _mfpOn = function(name, f) {\n\t\tmfp.ev.on(NS + name + EVENT_NS, f);\n\t},\n\t_getEl = function(className, appendTo, html, raw) {\n\t\tvar el = document.createElement('div');\n\t\tel.className = 'mfp-'+className;\n\t\tif(html) {\n\t\t\tel.innerHTML = html;\n\t\t}\n\t\tif(!raw) {\n\t\t\tel = $(el);\n\t\t\tif(appendTo) {\n\t\t\t\tel.appendTo(appendTo);\n\t\t\t}\n\t\t} else if(appendTo) {\n\t\t\tappendTo.appendChild(el);\n\t\t}\n\t\treturn el;\n\t},\n\t_mfpTrigger = function(e, data) {\n\t\tmfp.ev.triggerHandler(NS + e, data);\n\n\t\tif(mfp.st.callbacks) {\n\t\t\t// converts \"mfpEventName\" to \"eventName\" callback and triggers it if it's present\n\t\t\te = e.charAt(0).toLowerCase() + e.slice(1);\n\t\t\tif(mfp.st.callbacks[e]) {\n\t\t\t\tmfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]);\n\t\t\t}\n\t\t}\n\t},\n\t_getCloseBtn = function(type) {\n\t\tif(type !== _currPopupType || !mfp.currTemplate.closeBtn) {\n\t\t\tmfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) );\n\t\t\t_currPopupType = type;\n\t\t}\n\t\treturn mfp.currTemplate.closeBtn;\n\t},\n\t// Initialize Magnific Popup only when called at least once\n\t_checkInstance = function() {\n\t\tif(!$.magnificPopup.instance) {\n\t\t\tmfp = new MagnificPopup();\n\t\t\tmfp.init();\n\t\t\t$.magnificPopup.instance = mfp;\n\t\t}\n\t},\n\t// CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr\n\tsupportsTransitions = function() {\n\t\tvar s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist\n\t\t\tv = ['ms','O','Moz','Webkit']; // 'v' for vendor\n\n\t\tif( s['transition'] !== undefined ) {\n\t\t\treturn true; \n\t\t}\n\t\t\t\n\t\twhile( v.length ) {\n\t\t\tif( v.pop() + 'Transition' in s ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\t\t\t\n\t\treturn false;\n\t};\n\n\n\n/**\n * Public functions\n */\nMagnificPopup.prototype = {\n\n\tconstructor: MagnificPopup,\n\n\t/**\n\t * Initializes Magnific Popup plugin. \n\t * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed\n\t */\n\tinit: function() {\n\t\tvar appVersion = navigator.appVersion;\n\t\tmfp.isIE7 = appVersion.indexOf(\"MSIE 7.\") !== -1; \n\t\tmfp.isIE8 = appVersion.indexOf(\"MSIE 8.\") !== -1;\n\t\tmfp.isLowIE = mfp.isIE7 || mfp.isIE8;\n\t\tmfp.isAndroid = (/android/gi).test(appVersion);\n\t\tmfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion);\n\t\tmfp.supportsTransition = supportsTransitions();\n\n\t\t// We disable fixed positioned lightbox on devices that don't handle it nicely.\n\t\t// If you know a better way of detecting this - let me know.\n\t\tmfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) );\n\t\t_document = $(document);\n\n\t\tmfp.popupsCache = {};\n\t},\n\n\t/**\n\t * Opens popup\n\t * @param  data [description]\n\t */\n\topen: function(data) {\n\n\t\tif(!_body) {\n\t\t\t_body = $(document.body);\n\t\t}\n\n\t\tvar i;\n\n\t\tif(data.isObj === false) { \n\t\t\t// convert jQuery collection to array to avoid conflicts later\n\t\t\tmfp.items = data.items.toArray();\n\n\t\t\tmfp.index = 0;\n\t\t\tvar items = data.items,\n\t\t\t\titem;\n\t\t\tfor(i = 0; i < items.length; i++) {\n\t\t\t\titem = items[i];\n\t\t\t\tif(item.parsed) {\n\t\t\t\t\titem = item.el[0];\n\t\t\t\t}\n\t\t\t\tif(item === data.el[0]) {\n\t\t\t\t\tmfp.index = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tmfp.items = $.isArray(data.items) ? data.items : [data.items];\n\t\t\tmfp.index = data.index || 0;\n\t\t}\n\n\t\t// if popup is already opened - we just update the content\n\t\tif(mfp.isOpen) {\n\t\t\tmfp.updateItemHTML();\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tmfp.types = []; \n\t\t_wrapClasses = '';\n\t\tif(data.mainEl && data.mainEl.length) {\n\t\t\tmfp.ev = data.mainEl.eq(0);\n\t\t} else {\n\t\t\tmfp.ev = _document;\n\t\t}\n\n\t\tif(data.key) {\n\t\t\tif(!mfp.popupsCache[data.key]) {\n\t\t\t\tmfp.popupsCache[data.key] = {};\n\t\t\t}\n\t\t\tmfp.currTemplate = mfp.popupsCache[data.key];\n\t\t} else {\n\t\t\tmfp.currTemplate = {};\n\t\t}\n\n\n\n\t\tmfp.st = $.extend(true, {}, $.magnificPopup.defaults, data ); \n\t\tmfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos;\n\n\t\tif(mfp.st.modal) {\n\t\t\tmfp.st.closeOnContentClick = false;\n\t\t\tmfp.st.closeOnBgClick = false;\n\t\t\tmfp.st.showCloseBtn = false;\n\t\t\tmfp.st.enableEscapeKey = false;\n\t\t}\n\t\t\n\n\t\t// Building markup\n\t\t// main containers are created only once\n\t\tif(!mfp.bgOverlay) {\n\n\t\t\t// Dark overlay\n\t\t\tmfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() {\n\t\t\t\tmfp.close();\n\t\t\t});\n\n\t\t\tmfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) {\n\t\t\t\tif(mfp._checkIfClose(e.target)) {\n\t\t\t\t\tmfp.close();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tmfp.container = _getEl('container', mfp.wrap);\n\t\t}\n\n\t\tmfp.contentContainer = _getEl('content');\n\t\tif(mfp.st.preloader) {\n\t\t\tmfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading);\n\t\t}\n\n\n\t\t// Initializing modules\n\t\tvar modules = $.magnificPopup.modules;\n\t\tfor(i = 0; i < modules.length; i++) {\n\t\t\tvar n = modules[i];\n\t\t\tn = n.charAt(0).toUpperCase() + n.slice(1);\n\t\t\tmfp['init'+n].call(mfp);\n\t\t}\n\t\t_mfpTrigger('BeforeOpen');\n\n\n\t\tif(mfp.st.showCloseBtn) {\n\t\t\t// Close button\n\t\t\tif(!mfp.st.closeBtnInside) {\n\t\t\t\tmfp.wrap.append( _getCloseBtn() );\n\t\t\t} else {\n\t\t\t\t_mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) {\n\t\t\t\t\tvalues.close_replaceWith = _getCloseBtn(item.type);\n\t\t\t\t});\n\t\t\t\t_wrapClasses += ' mfp-close-btn-in';\n\t\t\t}\n\t\t}\n\n\t\tif(mfp.st.alignTop) {\n\t\t\t_wrapClasses += ' mfp-align-top';\n\t\t}\n\n\t\n\n\t\tif(mfp.fixedContentPos) {\n\t\t\tmfp.wrap.css({\n\t\t\t\toverflow: mfp.st.overflowY,\n\t\t\t\toverflowX: 'hidden',\n\t\t\t\toverflowY: mfp.st.overflowY\n\t\t\t});\n\t\t} else {\n\t\t\tmfp.wrap.css({ \n\t\t\t\ttop: _window.scrollTop(),\n\t\t\t\tposition: 'absolute'\n\t\t\t});\n\t\t}\n\t\tif( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) {\n\t\t\tmfp.bgOverlay.css({\n\t\t\t\theight: _document.height(),\n\t\t\t\tposition: 'absolute'\n\t\t\t});\n\t\t}\n\n\t\t\n\n\t\tif(mfp.st.enableEscapeKey) {\n\t\t\t// Close on ESC key\n\t\t\t_document.on('keyup' + EVENT_NS, function(e) {\n\t\t\t\tif(e.keyCode === 27) {\n\t\t\t\t\tmfp.close();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t_window.on('resize' + EVENT_NS, function() {\n\t\t\tmfp.updateSize();\n\t\t});\n\n\n\t\tif(!mfp.st.closeOnContentClick) {\n\t\t\t_wrapClasses += ' mfp-auto-cursor';\n\t\t}\n\t\t\n\t\tif(_wrapClasses)\n\t\t\tmfp.wrap.addClass(_wrapClasses);\n\n\n\t\t// this triggers recalculation of layout, so we get it once to not to trigger twice\n\t\tvar windowHeight = mfp.wH = _window.height();\n\n\t\t\n\t\tvar windowStyles = {};\n\n\t\tif( mfp.fixedContentPos ) {\n            if(mfp._hasScrollBar(windowHeight)){\n                var s = mfp._getScrollbarSize();\n                if(s) {\n                    windowStyles.marginRight = s;\n                }\n            }\n        }\n\n\t\tif(mfp.fixedContentPos) {\n\t\t\tif(!mfp.isIE7) {\n\t\t\t\twindowStyles.overflow = 'hidden';\n\t\t\t} else {\n\t\t\t\t// ie7 double-scroll bug\n\t\t\t\t$('body, html').css('overflow', 'hidden');\n\t\t\t}\n\t\t}\n\n\t\t\n\t\t\n\t\tvar classesToadd = mfp.st.mainClass;\n\t\tif(mfp.isIE7) {\n\t\t\tclassesToadd += ' mfp-ie7';\n\t\t}\n\t\tif(classesToadd) {\n\t\t\tmfp._addClassToMFP( classesToadd );\n\t\t}\n\n\t\t// add content\n\t\tmfp.updateItemHTML();\n\n\t\t_mfpTrigger('BuildControls');\n\n\t\t// remove scrollbar, add margin e.t.c\n\t\t$('html').css(windowStyles);\n\t\t\n\t\t// add everything to DOM\n\t\tmfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || _body );\n\n\t\t// Save last focused element\n\t\tmfp._lastFocusedEl = document.activeElement;\n\t\t\n\t\t// Wait for next cycle to allow CSS transition\n\t\tsetTimeout(function() {\n\t\t\t\n\t\t\tif(mfp.content) {\n\t\t\t\tmfp._addClassToMFP(READY_CLASS);\n\t\t\t\tmfp._setFocus();\n\t\t\t} else {\n\t\t\t\t// if content is not defined (not loaded e.t.c) we add class only for BG\n\t\t\t\tmfp.bgOverlay.addClass(READY_CLASS);\n\t\t\t}\n\t\t\t\n\t\t\t// Trap the focus in popup\n\t\t\t_document.on('focusin' + EVENT_NS, mfp._onFocusIn);\n\n\t\t}, 16);\n\n\t\tmfp.isOpen = true;\n\t\tmfp.updateSize(windowHeight);\n\t\t_mfpTrigger(OPEN_EVENT);\n\n\t\treturn data;\n\t},\n\n\t/**\n\t * Closes the popup\n\t */\n\tclose: function() {\n\t\tif(!mfp.isOpen) return;\n\t\t_mfpTrigger(BEFORE_CLOSE_EVENT);\n\n\t\tmfp.isOpen = false;\n\t\t// for CSS3 animation\n\t\tif(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition )  {\n\t\t\tmfp._addClassToMFP(REMOVING_CLASS);\n\t\t\tsetTimeout(function() {\n\t\t\t\tmfp._close();\n\t\t\t}, mfp.st.removalDelay);\n\t\t} else {\n\t\t\tmfp._close();\n\t\t}\n\t},\n\n\t/**\n\t * Helper for close() function\n\t */\n\t_close: function() {\n\t\t_mfpTrigger(CLOSE_EVENT);\n\n\t\tvar classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' ';\n\n\t\tmfp.bgOverlay.detach();\n\t\tmfp.wrap.detach();\n\t\tmfp.container.empty();\n\n\t\tif(mfp.st.mainClass) {\n\t\t\tclassesToRemove += mfp.st.mainClass + ' ';\n\t\t}\n\n\t\tmfp._removeClassFromMFP(classesToRemove);\n\n\t\tif(mfp.fixedContentPos) {\n\t\t\tvar windowStyles = {marginRight: ''};\n\t\t\tif(mfp.isIE7) {\n\t\t\t\t$('body, html').css('overflow', '');\n\t\t\t} else {\n\t\t\t\twindowStyles.overflow = '';\n\t\t\t}\n\t\t\t$('html').css(windowStyles);\n\t\t}\n\t\t\n\t\t_document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS);\n\t\tmfp.ev.off(EVENT_NS);\n\n\t\t// clean up DOM elements that aren't removed\n\t\tmfp.wrap.attr('class', 'mfp-wrap').removeAttr('style');\n\t\tmfp.bgOverlay.attr('class', 'mfp-bg');\n\t\tmfp.container.attr('class', 'mfp-container');\n\n\t\t// remove close button from target element\n\t\tif(mfp.st.showCloseBtn &&\n\t\t(!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) {\n\t\t\tif(mfp.currTemplate.closeBtn)\n\t\t\t\tmfp.currTemplate.closeBtn.detach();\n\t\t}\n\n\n\t\tif(mfp._lastFocusedEl) {\n\t\t\t$(mfp._lastFocusedEl).focus(); // put tab focus back\n\t\t}\n\t\tmfp.currItem = null;\t\n\t\tmfp.content = null;\n\t\tmfp.currTemplate = null;\n\t\tmfp.prevHeight = 0;\n\n\t\t_mfpTrigger(AFTER_CLOSE_EVENT);\n\t},\n\t\n\tupdateSize: function(winHeight) {\n\n\t\tif(mfp.isIOS) {\n\t\t\t// fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2\n\t\t\tvar zoomLevel = document.documentElement.clientWidth / window.innerWidth;\n\t\t\tvar height = window.innerHeight * zoomLevel;\n\t\t\tmfp.wrap.css('height', height);\n\t\t\tmfp.wH = height;\n\t\t} else {\n\t\t\tmfp.wH = winHeight || _window.height();\n\t\t}\n\t\t// Fixes #84: popup incorrectly positioned with position:relative on body\n\t\tif(!mfp.fixedContentPos) {\n\t\t\tmfp.wrap.css('height', mfp.wH);\n\t\t}\n\n\t\t_mfpTrigger('Resize');\n\n\t},\n\n\t/**\n\t * Set content of popup based on current index\n\t */\n\tupdateItemHTML: function() {\n\t\tvar item = mfp.items[mfp.index];\n\n\t\t// Detach and perform modifications\n\t\tmfp.contentContainer.detach();\n\n\t\tif(mfp.content)\n\t\t\tmfp.content.detach();\n\n\t\tif(!item.parsed) {\n\t\t\titem = mfp.parseEl( mfp.index );\n\t\t}\n\n\t\tvar type = item.type;\t\n\n\t\t_mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]);\n\t\t// BeforeChange event works like so:\n\t\t// _mfpOn('BeforeChange', function(e, prevType, newType) { });\n\t\t\n\t\tmfp.currItem = item;\n\n\t\t\n\n\t\t\n\n\t\tif(!mfp.currTemplate[type]) {\n\t\t\tvar markup = mfp.st[type] ? mfp.st[type].markup : false;\n\n\t\t\t// allows to modify markup\n\t\t\t_mfpTrigger('FirstMarkupParse', markup);\n\n\t\t\tif(markup) {\n\t\t\t\tmfp.currTemplate[type] = $(markup);\n\t\t\t} else {\n\t\t\t\t// if there is no markup found we just define that template is parsed\n\t\t\t\tmfp.currTemplate[type] = true;\n\t\t\t}\n\t\t}\n\n\t\tif(_prevContentType && _prevContentType !== item.type) {\n\t\t\tmfp.container.removeClass('mfp-'+_prevContentType+'-holder');\n\t\t}\n\t\t\n\t\tvar newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]);\n\t\tmfp.appendContent(newContent, type);\n\n\t\titem.preloaded = true;\n\n\t\t_mfpTrigger(CHANGE_EVENT, item);\n\t\t_prevContentType = item.type;\n\t\t\n\t\t// Append container back after its content changed\n\t\tmfp.container.prepend(mfp.contentContainer);\n\n\t\t_mfpTrigger('AfterChange');\n\t},\n\n\n\t/**\n\t * Set HTML content of popup\n\t */\n\tappendContent: function(newContent, type) {\n\t\tmfp.content = newContent;\n\t\t\n\t\tif(newContent) {\n\t\t\tif(mfp.st.showCloseBtn && mfp.st.closeBtnInside &&\n\t\t\t\tmfp.currTemplate[type] === true) {\n\t\t\t\t// if there is no markup, we just append close button element inside\n\t\t\t\tif(!mfp.content.find('.mfp-close').length) {\n\t\t\t\t\tmfp.content.append(_getCloseBtn());\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tmfp.content = newContent;\n\t\t\t}\n\t\t} else {\n\t\t\tmfp.content = '';\n\t\t}\n\n\t\t_mfpTrigger(BEFORE_APPEND_EVENT);\n\t\tmfp.container.addClass('mfp-'+type+'-holder');\n\n\t\tmfp.contentContainer.append(mfp.content);\n\t},\n\n\n\n\t\n\t/**\n\t * Creates Magnific Popup data object based on given data\n\t * @param  {int} index Index of item to parse\n\t */\n\tparseEl: function(index) {\n\t\tvar item = mfp.items[index],\n\t\t\ttype;\n\n\t\tif(item.tagName) {\n\t\t\titem = { el: $(item) };\n\t\t} else {\n\t\t\ttype = item.type;\n\t\t\titem = { data: item, src: item.src };\n\t\t}\n\n\t\tif(item.el) {\n\t\t\tvar types = mfp.types;\n\n\t\t\t// check for 'mfp-TYPE' class\n\t\t\tfor(var i = 0; i < types.length; i++) {\n\t\t\t\tif( item.el.hasClass('mfp-'+types[i]) ) {\n\t\t\t\t\ttype = types[i];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\titem.src = item.el.attr('data-mfp-src');\n\t\t\tif(!item.src) {\n\t\t\t\titem.src = item.el.attr('href');\n\t\t\t}\n\t\t}\n\n\t\titem.type = type || mfp.st.type || 'inline';\n\t\titem.index = index;\n\t\titem.parsed = true;\n\t\tmfp.items[index] = item;\n\t\t_mfpTrigger('ElementParse', item);\n\n\t\treturn mfp.items[index];\n\t},\n\n\n\t/**\n\t * Initializes single popup or a group of popups\n\t */\n\taddGroup: function(el, options) {\n\t\tvar eHandler = function(e) {\n\t\t\te.mfpEl = this;\n\t\t\tmfp._openClick(e, el, options);\n\t\t};\n\n\t\tif(!options) {\n\t\t\toptions = {};\n\t\t} \n\n\t\tvar eName = 'click.magnificPopup';\n\t\toptions.mainEl = el;\n\t\t\n\t\tif(options.items) {\n\t\t\toptions.isObj = true;\n\t\t\tel.off(eName).on(eName, eHandler);\n\t\t} else {\n\t\t\toptions.isObj = false;\n\t\t\tif(options.delegate) {\n\t\t\t\tel.off(eName).on(eName, options.delegate , eHandler);\n\t\t\t} else {\n\t\t\t\toptions.items = el;\n\t\t\t\tel.off(eName).on(eName, eHandler);\n\t\t\t}\n\t\t}\n\t},\n\t_openClick: function(e, el, options) {\n\t\tvar midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick;\n\n\n\t\tif(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn;\n\n\t\tif(disableOn) {\n\t\t\tif($.isFunction(disableOn)) {\n\t\t\t\tif( !disableOn.call(mfp) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} else { // else it's number\n\t\t\t\tif( _window.width() < disableOn ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\tif(e.type) {\n\t\t\te.preventDefault();\n\n\t\t\t// This will prevent popup from closing if element is inside and popup is already opened\n\t\t\tif(mfp.isOpen) {\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t}\n\t\t\t\n\n\t\toptions.el = $(e.mfpEl);\n\t\tif(options.delegate) {\n\t\t\toptions.items = el.find(options.delegate);\n\t\t}\n\t\tmfp.open(options);\n\t},\n\n\n\t/**\n\t * Updates text on preloader\n\t */\n\tupdateStatus: function(status, text) {\n\n\t\tif(mfp.preloader) {\n\t\t\tif(_prevStatus !== status) {\n\t\t\t\tmfp.container.removeClass('mfp-s-'+_prevStatus);\n\t\t\t}\n\n\t\t\tif(!text && status === 'loading') {\n\t\t\t\ttext = mfp.st.tLoading;\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tstatus: status,\n\t\t\t\ttext: text\n\t\t\t};\n\t\t\t// allows to modify status\n\t\t\t_mfpTrigger('UpdateStatus', data);\n\n\t\t\tstatus = data.status;\n\t\t\ttext = data.text;\n\n\t\t\tmfp.preloader.html(text);\n\n\t\t\tmfp.preloader.find('a').on('click', function(e) {\n\t\t\t\te.stopImmediatePropagation();\n\t\t\t});\n\n\t\t\tmfp.container.addClass('mfp-s-'+status);\n\t\t\t_prevStatus = status;\n\t\t}\n\t},\n\n\n\t/*\n\t\t\"Private\" helpers that aren't private at all\n\t */\n\t// Check to close popup or not\n\t// \"target\" is an element that was clicked\n\t_checkIfClose: function(target) {\n\n\t\tif($(target).hasClass(PREVENT_CLOSE_CLASS)) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar closeOnContent = mfp.st.closeOnContentClick;\n\t\tvar closeOnBg = mfp.st.closeOnBgClick;\n\n\t\tif(closeOnContent && closeOnBg) {\n\t\t\treturn true;\n\t\t} else {\n\n\t\t\t// We close the popup if click is on close button or on preloader. Or if there is no content.\n\t\t\tif(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// if click is outside the content\n\t\t\tif(  (target !== mfp.content[0] && !$.contains(mfp.content[0], target))  ) {\n\t\t\t\tif(closeOnBg) {\n\t\t\t\t\t// last check, if the clicked element is in DOM, (in case it's removed onclick)\n\t\t\t\t\tif( $.contains(document, target) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if(closeOnContent) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t}\n\t\treturn false;\n\t},\n\t_addClassToMFP: function(cName) {\n\t\tmfp.bgOverlay.addClass(cName);\n\t\tmfp.wrap.addClass(cName);\n\t},\n\t_removeClassFromMFP: function(cName) {\n\t\tthis.bgOverlay.removeClass(cName);\n\t\tmfp.wrap.removeClass(cName);\n\t},\n\t_hasScrollBar: function(winHeight) {\n\t\treturn (  (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) );\n\t},\n\t_setFocus: function() {\n\t\t(mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus();\n\t},\n\t_onFocusIn: function(e) {\n\t\tif( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) {\n\t\t\tmfp._setFocus();\n\t\t\treturn false;\n\t\t}\n\t},\n\t_parseMarkup: function(template, values, item) {\n\t\tvar arr;\n\t\tif(item.data) {\n\t\t\tvalues = $.extend(item.data, values);\n\t\t}\n\t\t_mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] );\n\n\t\t$.each(values, function(key, value) {\n\t\t\tif(value === undefined || value === false) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tarr = key.split('_');\n\t\t\tif(arr.length > 1) {\n\t\t\t\tvar el = template.find(EVENT_NS + '-'+arr[0]);\n\n\t\t\t\tif(el.length > 0) {\n\t\t\t\t\tvar attr = arr[1];\n\t\t\t\t\tif(attr === 'replaceWith') {\n\t\t\t\t\t\tif(el[0] !== value[0]) {\n\t\t\t\t\t\t\tel.replaceWith(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if(attr === 'img') {\n\t\t\t\t\t\tif(el.is('img')) {\n\t\t\t\t\t\t\tel.attr('src', value);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tel.replaceWith( '<img src=\"'+value+'\" class=\"' + el.attr('class') + '\" />' );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tel.attr(arr[1], value);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\ttemplate.find(EVENT_NS + '-'+key).html(value);\n\t\t\t}\n\t\t});\n\t},\n\n\t_getScrollbarSize: function() {\n\t\t// thx David\n\t\tif(mfp.scrollbarSize === undefined) {\n\t\t\tvar scrollDiv = document.createElement(\"div\");\n\t\t\tscrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';\n\t\t\tdocument.body.appendChild(scrollDiv);\n\t\t\tmfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;\n\t\t\tdocument.body.removeChild(scrollDiv);\n\t\t}\n\t\treturn mfp.scrollbarSize;\n\t}\n\n}; /* MagnificPopup core prototype end */\n\n\n\n\n/**\n * Public static functions\n */\n$.magnificPopup = {\n\tinstance: null,\n\tproto: MagnificPopup.prototype,\n\tmodules: [],\n\n\topen: function(options, index) {\n\t\t_checkInstance();\t\n\n\t\tif(!options) {\n\t\t\toptions = {};\n\t\t} else {\n\t\t\toptions = $.extend(true, {}, options);\n\t\t}\n\t\t\t\n\n\t\toptions.isObj = true;\n\t\toptions.index = index || 0;\n\t\treturn this.instance.open(options);\n\t},\n\n\tclose: function() {\n\t\treturn $.magnificPopup.instance && $.magnificPopup.instance.close();\n\t},\n\n\tregisterModule: function(name, module) {\n\t\tif(module.options) {\n\t\t\t$.magnificPopup.defaults[name] = module.options;\n\t\t}\n\t\t$.extend(this.proto, module.proto);\t\t\t\n\t\tthis.modules.push(name);\n\t},\n\n\tdefaults: {   \n\n\t\t// Info about options is in docs:\n\t\t// http://dimsemenov.com/plugins/magnific-popup/documentation.html#options\n\t\t\n\t\tdisableOn: 0,\t\n\n\t\tkey: null,\n\n\t\tmidClick: false,\n\n\t\tmainClass: '',\n\n\t\tpreloader: true,\n\n\t\tfocus: '', // CSS selector of input to focus after popup is opened\n\t\t\n\t\tcloseOnContentClick: false,\n\n\t\tcloseOnBgClick: true,\n\n\t\tcloseBtnInside: true, \n\n\t\tshowCloseBtn: true,\n\n\t\tenableEscapeKey: true,\n\n\t\tmodal: false,\n\n\t\talignTop: false,\n\t\n\t\tremovalDelay: 0,\n\n\t\tprependTo: null,\n\t\t\n\t\tfixedContentPos: 'auto', \n\t\n\t\tfixedBgPos: 'auto',\n\n\t\toverflowY: 'auto',\n\n\t\tcloseMarkup: '<button title=\"%title%\" type=\"button\" class=\"mfp-close\">&times;</button>',\n\n\t\ttClose: 'Close (Esc)',\n\n\t\ttLoading: 'Loading...'\n\n\t}\n};\n\n\n\n$.fn.magnificPopup = function(options) {\n\t_checkInstance();\n\n\tvar jqEl = $(this);\n\n\t// We call some API method of first param is a string\n\tif (typeof options === \"string\" ) {\n\n\t\tif(options === 'open') {\n\t\t\tvar items,\n\t\t\t\titemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup,\n\t\t\t\tindex = parseInt(arguments[1], 10) || 0;\n\n\t\t\tif(itemOpts.items) {\n\t\t\t\titems = itemOpts.items[index];\n\t\t\t} else {\n\t\t\t\titems = jqEl;\n\t\t\t\tif(itemOpts.delegate) {\n\t\t\t\t\titems = items.find(itemOpts.delegate);\n\t\t\t\t}\n\t\t\t\titems = items.eq( index );\n\t\t\t}\n\t\t\tmfp._openClick({mfpEl:items}, jqEl, itemOpts);\n\t\t} else {\n\t\t\tif(mfp.isOpen)\n\t\t\t\tmfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1));\n\t\t}\n\n\t} else {\n\t\t// clone options obj\n\t\toptions = $.extend(true, {}, options);\n\t\t\n\t\t/*\n\t\t * As Zepto doesn't support .data() method for objects \n\t\t * and it works only in normal browsers\n\t\t * we assign \"options\" object directly to the DOM element. FTW!\n\t\t */\n\t\tif(_isJQ) {\n\t\t\tjqEl.data('magnificPopup', options);\n\t\t} else {\n\t\t\tjqEl[0].magnificPopup = options;\n\t\t}\n\n\t\tmfp.addGroup(jqEl, options);\n\n\t}\n\treturn jqEl;\n};\n\n\n//Quick benchmark\n/*\nvar start = performance.now(),\n\ti,\n\trounds = 1000;\n\nfor(i = 0; i < rounds; i++) {\n\n}\nconsole.log('Test #1:', performance.now() - start);\n\nstart = performance.now();\nfor(i = 0; i < rounds; i++) {\n\n}\nconsole.log('Test #2:', performance.now() - start);\n*/\n\n\n/*>>core*/\n\n/*>>inline*/\n\nvar INLINE_NS = 'inline',\n\t_hiddenClass,\n\t_inlinePlaceholder, \n\t_lastInlineElement,\n\t_putInlineElementsBack = function() {\n\t\tif(_lastInlineElement) {\n\t\t\t_inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach();\n\t\t\t_lastInlineElement = null;\n\t\t}\n\t};\n\n$.magnificPopup.registerModule(INLINE_NS, {\n\toptions: {\n\t\thiddenClass: 'hide', // will be appended with `mfp-` prefix\n\t\tmarkup: '',\n\t\ttNotFound: 'Content not found'\n\t},\n\tproto: {\n\n\t\tinitInline: function() {\n\t\t\tmfp.types.push(INLINE_NS);\n\n\t\t\t_mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() {\n\t\t\t\t_putInlineElementsBack();\n\t\t\t});\n\t\t},\n\n\t\tgetInline: function(item, template) {\n\n\t\t\t_putInlineElementsBack();\n\n\t\t\tif(item.src) {\n\t\t\t\tvar inlineSt = mfp.st.inline,\n\t\t\t\t\tel = $(item.src);\n\n\t\t\t\tif(el.length) {\n\n\t\t\t\t\t// If target element has parent - we replace it with placeholder and put it back after popup is closed\n\t\t\t\t\tvar parent = el[0].parentNode;\n\t\t\t\t\tif(parent && parent.tagName) {\n\t\t\t\t\t\tif(!_inlinePlaceholder) {\n\t\t\t\t\t\t\t_hiddenClass = inlineSt.hiddenClass;\n\t\t\t\t\t\t\t_inlinePlaceholder = _getEl(_hiddenClass);\n\t\t\t\t\t\t\t_hiddenClass = 'mfp-'+_hiddenClass;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// replace target inline element with placeholder\n\t\t\t\t\t\t_lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass);\n\t\t\t\t\t}\n\n\t\t\t\t\tmfp.updateStatus('ready');\n\t\t\t\t} else {\n\t\t\t\t\tmfp.updateStatus('error', inlineSt.tNotFound);\n\t\t\t\t\tel = $('<div>');\n\t\t\t\t}\n\n\t\t\t\titem.inlineElement = el;\n\t\t\t\treturn el;\n\t\t\t}\n\n\t\t\tmfp.updateStatus('ready');\n\t\t\tmfp._parseMarkup(template, {}, item);\n\t\t\treturn template;\n\t\t}\n\t}\n});\n\n/*>>inline*/\n\n/*>>ajax*/\nvar AJAX_NS = 'ajax',\n\t_ajaxCur,\n\t_removeAjaxCursor = function() {\n\t\tif(_ajaxCur) {\n\t\t\t_body.removeClass(_ajaxCur);\n\t\t}\n\t},\n\t_destroyAjaxRequest = function() {\n\t\t_removeAjaxCursor();\n\t\tif(mfp.req) {\n\t\t\tmfp.req.abort();\n\t\t}\n\t};\n\n$.magnificPopup.registerModule(AJAX_NS, {\n\n\toptions: {\n\t\tsettings: null,\n\t\tcursor: 'mfp-ajax-cur',\n\t\ttError: '<a href=\"%url%\">The content</a> could not be loaded.'\n\t},\n\n\tproto: {\n\t\tinitAjax: function() {\n\t\t\tmfp.types.push(AJAX_NS);\n\t\t\t_ajaxCur = mfp.st.ajax.cursor;\n\n\t\t\t_mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest);\n\t\t\t_mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest);\n\t\t},\n\t\tgetAjax: function(item) {\n\n\t\t\tif(_ajaxCur)\n\t\t\t\t_body.addClass(_ajaxCur);\n\n\t\t\tmfp.updateStatus('loading');\n\n\t\t\tvar opts = $.extend({\n\t\t\t\turl: item.src,\n\t\t\t\tsuccess: function(data, textStatus, jqXHR) {\n\t\t\t\t\tvar temp = {\n\t\t\t\t\t\tdata:data,\n\t\t\t\t\t\txhr:jqXHR\n\t\t\t\t\t};\n\n\t\t\t\t\t_mfpTrigger('ParseAjax', temp);\n\n\t\t\t\t\tmfp.appendContent( $(temp.data), AJAX_NS );\n\n\t\t\t\t\titem.finished = true;\n\n\t\t\t\t\t_removeAjaxCursor();\n\n\t\t\t\t\tmfp._setFocus();\n\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tmfp.wrap.addClass(READY_CLASS);\n\t\t\t\t\t}, 16);\n\n\t\t\t\t\tmfp.updateStatus('ready');\n\n\t\t\t\t\t_mfpTrigger('AjaxContentAdded');\n\t\t\t\t},\n\t\t\t\terror: function() {\n\t\t\t\t\t_removeAjaxCursor();\n\t\t\t\t\titem.finished = item.loadError = true;\n\t\t\t\t\tmfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src));\n\t\t\t\t}\n\t\t\t}, mfp.st.ajax.settings);\n\n\t\t\tmfp.req = $.ajax(opts);\n\n\t\t\treturn '';\n\t\t}\n\t}\n});\n\n\n\n\n\n\t\n\n/*>>ajax*/\n\n/*>>image*/\nvar _imgInterval,\n\t_getTitle = function(item) {\n\t\tif(item.data && item.data.title !== undefined) \n\t\t\treturn item.data.title;\n\n\t\tvar src = mfp.st.image.titleSrc;\n\n\t\tif(src) {\n\t\t\tif($.isFunction(src)) {\n\t\t\t\treturn src.call(mfp, item);\n\t\t\t} else if(item.el) {\n\t\t\t\treturn item.el.attr(src) || '';\n\t\t\t}\n\t\t}\n\t\treturn '';\n\t};\n\n$.magnificPopup.registerModule('image', {\n\n\toptions: {\n\t\tmarkup: '<div class=\"mfp-figure\">'+\n\t\t\t\t\t'<div class=\"mfp-close\"></div>'+\n\t\t\t\t\t'<figure>'+\n\t\t\t\t\t\t'<div class=\"mfp-img\"></div>'+\n\t\t\t\t\t\t'<figcaption>'+\n\t\t\t\t\t\t\t'<div class=\"mfp-bottom-bar\">'+\n\t\t\t\t\t\t\t\t'<div class=\"mfp-title\"></div>'+\n\t\t\t\t\t\t\t\t'<div class=\"mfp-counter\"></div>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t'</figcaption>'+\n\t\t\t\t\t'</figure>'+\n\t\t\t\t'</div>',\n\t\tcursor: 'mfp-zoom-out-cur',\n\t\ttitleSrc: 'title', \n\t\tverticalFit: true,\n\t\ttError: '<a href=\"%url%\">The image</a> could not be loaded.'\n\t},\n\n\tproto: {\n\t\tinitImage: function() {\n\t\t\tvar imgSt = mfp.st.image,\n\t\t\t\tns = '.image';\n\n\t\t\tmfp.types.push('image');\n\n\t\t\t_mfpOn(OPEN_EVENT+ns, function() {\n\t\t\t\tif(mfp.currItem.type === 'image' && imgSt.cursor) {\n\t\t\t\t\t_body.addClass(imgSt.cursor);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t_mfpOn(CLOSE_EVENT+ns, function() {\n\t\t\t\tif(imgSt.cursor) {\n\t\t\t\t\t_body.removeClass(imgSt.cursor);\n\t\t\t\t}\n\t\t\t\t_window.off('resize' + EVENT_NS);\n\t\t\t});\n\n\t\t\t_mfpOn('Resize'+ns, mfp.resizeImage);\n\t\t\tif(mfp.isLowIE) {\n\t\t\t\t_mfpOn('AfterChange', mfp.resizeImage);\n\t\t\t}\n\t\t},\n\t\tresizeImage: function() {\n\t\t\tvar item = mfp.currItem;\n\t\t\tif(!item || !item.img) return;\n\n\t\t\tif(mfp.st.image.verticalFit) {\n\t\t\t\tvar decr = 0;\n\t\t\t\t// fix box-sizing in ie7/8\n\t\t\t\tif(mfp.isLowIE) {\n\t\t\t\t\tdecr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10);\n\t\t\t\t}\n\t\t\t\titem.img.css('max-height', mfp.wH-decr);\n\t\t\t}\n\t\t},\n\t\t_onImageHasSize: function(item) {\n\t\t\tif(item.img) {\n\t\t\t\t\n\t\t\t\titem.hasSize = true;\n\n\t\t\t\tif(_imgInterval) {\n\t\t\t\t\tclearInterval(_imgInterval);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\titem.isCheckingImgSize = false;\n\n\t\t\t\t_mfpTrigger('ImageHasSize', item);\n\n\t\t\t\tif(item.imgHidden) {\n\t\t\t\t\tif(mfp.content)\n\t\t\t\t\t\tmfp.content.removeClass('mfp-loading');\n\t\t\t\t\t\n\t\t\t\t\titem.imgHidden = false;\n\t\t\t\t}\n\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Function that loops until the image has size to display elements that rely on it asap\n\t\t */\n\t\tfindImageSize: function(item) {\n\n\t\t\tvar counter = 0,\n\t\t\t\timg = item.img[0],\n\t\t\t\tmfpSetInterval = function(delay) {\n\n\t\t\t\t\tif(_imgInterval) {\n\t\t\t\t\t\tclearInterval(_imgInterval);\n\t\t\t\t\t}\n\t\t\t\t\t// decelerating interval that checks for size of an image\n\t\t\t\t\t_imgInterval = setInterval(function() {\n\t\t\t\t\t\tif(img.naturalWidth > 0) {\n\t\t\t\t\t\t\tmfp._onImageHasSize(item);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(counter > 200) {\n\t\t\t\t\t\t\tclearInterval(_imgInterval);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcounter++;\n\t\t\t\t\t\tif(counter === 3) {\n\t\t\t\t\t\t\tmfpSetInterval(10);\n\t\t\t\t\t\t} else if(counter === 40) {\n\t\t\t\t\t\t\tmfpSetInterval(50);\n\t\t\t\t\t\t} else if(counter === 100) {\n\t\t\t\t\t\t\tmfpSetInterval(500);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, delay);\n\t\t\t\t};\n\n\t\t\tmfpSetInterval(1);\n\t\t},\n\n\t\tgetImage: function(item, template) {\n\n\t\t\tvar guard = 0,\n\n\t\t\t\t// image load complete handler\n\t\t\t\tonLoadComplete = function() {\n\t\t\t\t\tif(item) {\n\t\t\t\t\t\tif (item.img[0].complete) {\n\t\t\t\t\t\t\titem.img.off('.mfploader');\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tif(item === mfp.currItem){\n\t\t\t\t\t\t\t\tmfp._onImageHasSize(item);\n\n\t\t\t\t\t\t\t\tmfp.updateStatus('ready');\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\titem.hasSize = true;\n\t\t\t\t\t\t\titem.loaded = true;\n\n\t\t\t\t\t\t\t_mfpTrigger('ImageLoadComplete');\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// if image complete check fails 200 times (20 sec), we assume that there was an error.\n\t\t\t\t\t\t\tguard++;\n\t\t\t\t\t\t\tif(guard < 200) {\n\t\t\t\t\t\t\t\tsetTimeout(onLoadComplete,100);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tonLoadError();\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\n\t\t\t\t// image error handler\n\t\t\t\tonLoadError = function() {\n\t\t\t\t\tif(item) {\n\t\t\t\t\t\titem.img.off('.mfploader');\n\t\t\t\t\t\tif(item === mfp.currItem){\n\t\t\t\t\t\t\tmfp._onImageHasSize(item);\n\t\t\t\t\t\t\tmfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\titem.hasSize = true;\n\t\t\t\t\t\titem.loaded = true;\n\t\t\t\t\t\titem.loadError = true;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\timgSt = mfp.st.image;\n\n\n\t\t\tvar el = template.find('.mfp-img');\n\t\t\tif(el.length) {\n\t\t\t\tvar img = document.createElement('img');\n\t\t\t\timg.className = 'mfp-img';\n\t\t\t\tif(item.el && item.el.find('img').length) {\n\t\t\t\t\timg.alt = item.el.find('img').attr('alt');\n\t\t\t\t}\n\t\t\t\titem.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError);\n\t\t\t\timg.src = item.src;\n\n\t\t\t\t// without clone() \"error\" event is not firing when IMG is replaced by new IMG\n\t\t\t\t// TODO: find a way to avoid such cloning\n\t\t\t\tif(el.is('img')) {\n\t\t\t\t\titem.img = item.img.clone();\n\t\t\t\t}\n\n\t\t\t\timg = item.img[0];\n\t\t\t\tif(img.naturalWidth > 0) {\n\t\t\t\t\titem.hasSize = true;\n\t\t\t\t} else if(!img.width) {\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\titem.hasSize = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmfp._parseMarkup(template, {\n\t\t\t\ttitle: _getTitle(item),\n\t\t\t\timg_replaceWith: item.img\n\t\t\t}, item);\n\n\t\t\tmfp.resizeImage();\n\n\t\t\tif(item.hasSize) {\n\t\t\t\tif(_imgInterval) clearInterval(_imgInterval);\n\n\t\t\t\tif(item.loadError) {\n\t\t\t\t\ttemplate.addClass('mfp-loading');\n\t\t\t\t\tmfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );\n\t\t\t\t} else {\n\t\t\t\t\ttemplate.removeClass('mfp-loading');\n\t\t\t\t\tmfp.updateStatus('ready');\n\t\t\t\t}\n\t\t\t\treturn template;\n\t\t\t}\n\n\t\t\tmfp.updateStatus('loading');\n\t\t\titem.loading = true;\n\n\t\t\tif(!item.hasSize) {\n\t\t\t\titem.imgHidden = true;\n\t\t\t\ttemplate.addClass('mfp-loading');\n\t\t\t\tmfp.findImageSize(item);\n\t\t\t} \n\n\t\t\treturn template;\n\t\t}\n\t}\n});\n\n\n\n/*>>image*/\n\n/*>>zoom*/\nvar hasMozTransform,\n\tgetHasMozTransform = function() {\n\t\tif(hasMozTransform === undefined) {\n\t\t\thasMozTransform = document.createElement('p').style.MozTransform !== undefined;\n\t\t}\n\t\treturn hasMozTransform;\t\t\n\t};\n\n$.magnificPopup.registerModule('zoom', {\n\n\toptions: {\n\t\tenabled: false,\n\t\teasing: 'ease-in-out',\n\t\tduration: 300,\n\t\topener: function(element) {\n\t\t\treturn element.is('img') ? element : element.find('img');\n\t\t}\n\t},\n\n\tproto: {\n\n\t\tinitZoom: function() {\n\t\t\tvar zoomSt = mfp.st.zoom,\n\t\t\t\tns = '.zoom',\n\t\t\t\timage;\n\t\t\t\t\n\t\t\tif(!zoomSt.enabled || !mfp.supportsTransition) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar duration = zoomSt.duration,\n\t\t\t\tgetElToAnimate = function(image) {\n\t\t\t\t\tvar newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'),\n\t\t\t\t\t\ttransition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing,\n\t\t\t\t\t\tcssObj = {\n\t\t\t\t\t\t\tposition: 'fixed',\n\t\t\t\t\t\t\tzIndex: 9999,\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\t'-webkit-backface-visibility': 'hidden'\n\t\t\t\t\t\t},\n\t\t\t\t\t\tt = 'transition';\n\n\t\t\t\t\tcssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition;\n\n\t\t\t\t\tnewImg.css(cssObj);\n\t\t\t\t\treturn newImg;\n\t\t\t\t},\n\t\t\t\tshowMainContent = function() {\n\t\t\t\t\tmfp.content.css('visibility', 'visible');\n\t\t\t\t},\n\t\t\t\topenTimeout,\n\t\t\t\tanimatedImg;\n\n\t\t\t_mfpOn('BuildControls'+ns, function() {\n\t\t\t\tif(mfp._allowZoom()) {\n\n\t\t\t\t\tclearTimeout(openTimeout);\n\t\t\t\t\tmfp.content.css('visibility', 'hidden');\n\n\t\t\t\t\t// Basically, all code below does is clones existing image, puts in on top of the current one and animated it\n\t\t\t\t\t\n\t\t\t\t\timage = mfp._getItemToZoom();\n\n\t\t\t\t\tif(!image) {\n\t\t\t\t\t\tshowMainContent();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tanimatedImg = getElToAnimate(image); \n\t\t\t\t\t\n\t\t\t\t\tanimatedImg.css( mfp._getOffset() );\n\n\t\t\t\t\tmfp.wrap.append(animatedImg);\n\n\t\t\t\t\topenTimeout = setTimeout(function() {\n\t\t\t\t\t\tanimatedImg.css( mfp._getOffset( true ) );\n\t\t\t\t\t\topenTimeout = setTimeout(function() {\n\n\t\t\t\t\t\t\tshowMainContent();\n\n\t\t\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\t\t\tanimatedImg.remove();\n\t\t\t\t\t\t\t\timage = animatedImg = null;\n\t\t\t\t\t\t\t\t_mfpTrigger('ZoomAnimationEnded');\n\t\t\t\t\t\t\t}, 16); // avoid blink when switching images \n\n\t\t\t\t\t\t}, duration); // this timeout equals animation duration\n\n\t\t\t\t\t}, 16); // by adding this timeout we avoid short glitch at the beginning of animation\n\n\n\t\t\t\t\t// Lots of timeouts...\n\t\t\t\t}\n\t\t\t});\n\t\t\t_mfpOn(BEFORE_CLOSE_EVENT+ns, function() {\n\t\t\t\tif(mfp._allowZoom()) {\n\n\t\t\t\t\tclearTimeout(openTimeout);\n\n\t\t\t\t\tmfp.st.removalDelay = duration;\n\n\t\t\t\t\tif(!image) {\n\t\t\t\t\t\timage = mfp._getItemToZoom();\n\t\t\t\t\t\tif(!image) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tanimatedImg = getElToAnimate(image);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\tanimatedImg.css( mfp._getOffset(true) );\n\t\t\t\t\tmfp.wrap.append(animatedImg);\n\t\t\t\t\tmfp.content.css('visibility', 'hidden');\n\t\t\t\t\t\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tanimatedImg.css( mfp._getOffset() );\n\t\t\t\t\t}, 16);\n\t\t\t\t}\n\n\t\t\t});\n\n\t\t\t_mfpOn(CLOSE_EVENT+ns, function() {\n\t\t\t\tif(mfp._allowZoom()) {\n\t\t\t\t\tshowMainContent();\n\t\t\t\t\tif(animatedImg) {\n\t\t\t\t\t\tanimatedImg.remove();\n\t\t\t\t\t}\n\t\t\t\t\timage = null;\n\t\t\t\t}\t\n\t\t\t});\n\t\t},\n\n\t\t_allowZoom: function() {\n\t\t\treturn mfp.currItem.type === 'image';\n\t\t},\n\n\t\t_getItemToZoom: function() {\n\t\t\tif(mfp.currItem.hasSize) {\n\t\t\t\treturn mfp.currItem.img;\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\n\t\t// Get element postion relative to viewport\n\t\t_getOffset: function(isLarge) {\n\t\t\tvar el;\n\t\t\tif(isLarge) {\n\t\t\t\tel = mfp.currItem.img;\n\t\t\t} else {\n\t\t\t\tel = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem);\n\t\t\t}\n\n\t\t\tvar offset = el.offset();\n\t\t\tvar paddingTop = parseInt(el.css('padding-top'),10);\n\t\t\tvar paddingBottom = parseInt(el.css('padding-bottom'),10);\n\t\t\toffset.top -= ( $(window).scrollTop() - paddingTop );\n\n\n\t\t\t/*\n\t\t\t\n\t\t\tAnimating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa.\n\n\t\t\t */\n\t\t\tvar obj = {\n\t\t\t\twidth: el.width(),\n\t\t\t\t// fix Zepto height+padding issue\n\t\t\t\theight: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop\n\t\t\t};\n\n\t\t\t// I hate to do this, but there is no another option\n\t\t\tif( getHasMozTransform() ) {\n\t\t\t\tobj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)';\n\t\t\t} else {\n\t\t\t\tobj.left = offset.left;\n\t\t\t\tobj.top = offset.top;\n\t\t\t}\n\t\t\treturn obj;\n\t\t}\n\n\t}\n});\n\n\n\n/*>>zoom*/\n\n/*>>iframe*/\n\nvar IFRAME_NS = 'iframe',\n\t_emptyPage = '//about:blank',\n\t\n\t_fixIframeBugs = function(isShowing) {\n\t\tif(mfp.currTemplate[IFRAME_NS]) {\n\t\t\tvar el = mfp.currTemplate[IFRAME_NS].find('iframe');\n\t\t\tif(el.length) { \n\t\t\t\t// reset src after the popup is closed to avoid \"video keeps playing after popup is closed\" bug\n\t\t\t\tif(!isShowing) {\n\t\t\t\t\tel[0].src = _emptyPage;\n\t\t\t\t}\n\n\t\t\t\t// IE8 black screen bug fix\n\t\t\t\tif(mfp.isIE8) {\n\t\t\t\t\tel.css('display', isShowing ? 'block' : 'none');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n$.magnificPopup.registerModule(IFRAME_NS, {\n\n\toptions: {\n\t\tmarkup: '<div class=\"mfp-iframe-scaler\">'+\n\t\t\t\t\t'<div class=\"mfp-close\"></div>'+\n\t\t\t\t\t'<iframe class=\"mfp-iframe\" src=\"//about:blank\" frameborder=\"0\" allowfullscreen></iframe>'+\n\t\t\t\t'</div>',\n\n\t\tsrcAction: 'iframe_src',\n\n\t\t// we don't care and support only one default type of URL by default\n\t\tpatterns: {\n\t\t\tyoutube: {\n\t\t\t\tindex: 'youtube.com', \n\t\t\t\tid: 'v=', \n\t\t\t\tsrc: '//www.youtube.com/embed/%id%?autoplay=1'\n\t\t\t},\n\t\t\tvimeo: {\n\t\t\t\tindex: 'vimeo.com/',\n\t\t\t\tid: '/',\n\t\t\t\tsrc: '//player.vimeo.com/video/%id%?autoplay=1'\n\t\t\t},\n\t\t\tgmaps: {\n\t\t\t\tindex: '//maps.google.',\n\t\t\t\tsrc: '%id%&output=embed'\n\t\t\t}\n\t\t}\n\t},\n\n\tproto: {\n\t\tinitIframe: function() {\n\t\t\tmfp.types.push(IFRAME_NS);\n\n\t\t\t_mfpOn('BeforeChange', function(e, prevType, newType) {\n\t\t\t\tif(prevType !== newType) {\n\t\t\t\t\tif(prevType === IFRAME_NS) {\n\t\t\t\t\t\t_fixIframeBugs(); // iframe if removed\n\t\t\t\t\t} else if(newType === IFRAME_NS) {\n\t\t\t\t\t\t_fixIframeBugs(true); // iframe is showing\n\t\t\t\t\t} \n\t\t\t\t}// else {\n\t\t\t\t\t// iframe source is switched, don't do anything\n\t\t\t\t//}\n\t\t\t});\n\n\t\t\t_mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() {\n\t\t\t\t_fixIframeBugs();\n\t\t\t});\n\t\t},\n\n\t\tgetIframe: function(item, template) {\n\t\t\tvar embedSrc = item.src;\n\t\t\tvar iframeSt = mfp.st.iframe;\n\t\t\t\t\n\t\t\t$.each(iframeSt.patterns, function() {\n\t\t\t\tif(embedSrc.indexOf( this.index ) > -1) {\n\t\t\t\t\tif(this.id) {\n\t\t\t\t\t\tif(typeof this.id === 'string') {\n\t\t\t\t\t\t\tembedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tembedSrc = this.id.call( this, embedSrc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tembedSrc = this.src.replace('%id%', embedSrc );\n\t\t\t\t\treturn false; // break;\n\t\t\t\t}\n\t\t\t});\n\t\t\t\n\t\t\tvar dataObj = {};\n\t\t\tif(iframeSt.srcAction) {\n\t\t\t\tdataObj[iframeSt.srcAction] = embedSrc;\n\t\t\t}\n\t\t\tmfp._parseMarkup(template, dataObj, item);\n\n\t\t\tmfp.updateStatus('ready');\n\n\t\t\treturn template;\n\t\t}\n\t}\n});\n\n\n\n/*>>iframe*/\n\n/*>>gallery*/\n/**\n * Get looped index depending on number of slides\n */\nvar _getLoopedId = function(index) {\n\t\tvar numSlides = mfp.items.length;\n\t\tif(index > numSlides - 1) {\n\t\t\treturn index - numSlides;\n\t\t} else  if(index < 0) {\n\t\t\treturn numSlides + index;\n\t\t}\n\t\treturn index;\n\t},\n\t_replaceCurrTotal = function(text, curr, total) {\n\t\treturn text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total);\n\t};\n\n$.magnificPopup.registerModule('gallery', {\n\n\toptions: {\n\t\tenabled: false,\n\t\tarrowMarkup: '<button title=\"%title%\" type=\"button\" class=\"mfp-arrow mfp-arrow-%dir%\"></button>',\n\t\tpreload: [0,2],\n\t\tnavigateByImgClick: true,\n\t\tarrows: true,\n\n\t\ttPrev: 'Previous (Left arrow key)',\n\t\ttNext: 'Next (Right arrow key)',\n\t\ttCounter: '%curr% of %total%'\n\t},\n\n\tproto: {\n\t\tinitGallery: function() {\n\n\t\t\tvar gSt = mfp.st.gallery,\n\t\t\t\tns = '.mfp-gallery',\n\t\t\t\tsupportsFastClick = Boolean($.fn.mfpFastClick);\n\n\t\t\tmfp.direction = true; // true - next, false - prev\n\t\t\t\n\t\t\tif(!gSt || !gSt.enabled ) return false;\n\n\t\t\t_wrapClasses += ' mfp-gallery';\n\n\t\t\t_mfpOn(OPEN_EVENT+ns, function() {\n\n\t\t\t\tif(gSt.navigateByImgClick) {\n\t\t\t\t\tmfp.wrap.on('click'+ns, '.mfp-img', function() {\n\t\t\t\t\t\tif(mfp.items.length > 1) {\n\t\t\t\t\t\t\tmfp.next();\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t_document.on('keydown'+ns, function(e) {\n\t\t\t\t\tif (e.keyCode === 37) {\n\t\t\t\t\t\tmfp.prev();\n\t\t\t\t\t} else if (e.keyCode === 39) {\n\t\t\t\t\t\tmfp.next();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t_mfpOn('UpdateStatus'+ns, function(e, data) {\n\t\t\t\tif(data.text) {\n\t\t\t\t\tdata.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t_mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) {\n\t\t\t\tvar l = mfp.items.length;\n\t\t\t\tvalues.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : '';\n\t\t\t});\n\n\t\t\t_mfpOn('BuildControls' + ns, function() {\n\t\t\t\tif(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) {\n\t\t\t\t\tvar markup = gSt.arrowMarkup,\n\t\t\t\t\t\tarrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS),\t\t\t\n\t\t\t\t\t\tarrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS);\n\n\t\t\t\t\tvar eName = supportsFastClick ? 'mfpFastClick' : 'click';\n\t\t\t\t\tarrowLeft[eName](function() {\n\t\t\t\t\t\tmfp.prev();\n\t\t\t\t\t});\t\t\t\n\t\t\t\t\tarrowRight[eName](function() {\n\t\t\t\t\t\tmfp.next();\n\t\t\t\t\t});\t\n\n\t\t\t\t\t// Polyfill for :before and :after (adds elements with classes mfp-a and mfp-b)\n\t\t\t\t\tif(mfp.isIE7) {\n\t\t\t\t\t\t_getEl('b', arrowLeft[0], false, true);\n\t\t\t\t\t\t_getEl('a', arrowLeft[0], false, true);\n\t\t\t\t\t\t_getEl('b', arrowRight[0], false, true);\n\t\t\t\t\t\t_getEl('a', arrowRight[0], false, true);\n\t\t\t\t\t}\n\n\t\t\t\t\tmfp.container.append(arrowLeft.add(arrowRight));\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t_mfpOn(CHANGE_EVENT+ns, function() {\n\t\t\t\tif(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout);\n\n\t\t\t\tmfp._preloadTimeout = setTimeout(function() {\n\t\t\t\t\tmfp.preloadNearbyImages();\n\t\t\t\t\tmfp._preloadTimeout = null;\n\t\t\t\t}, 16);\t\t\n\t\t\t});\n\n\n\t\t\t_mfpOn(CLOSE_EVENT+ns, function() {\n\t\t\t\t_document.off(ns);\n\t\t\t\tmfp.wrap.off('click'+ns);\n\t\t\t\n\t\t\t\tif(mfp.arrowLeft && supportsFastClick) {\n\t\t\t\t\tmfp.arrowLeft.add(mfp.arrowRight).destroyMfpFastClick();\n\t\t\t\t}\n\t\t\t\tmfp.arrowRight = mfp.arrowLeft = null;\n\t\t\t});\n\n\t\t}, \n\t\tnext: function() {\n\t\t\tmfp.direction = true;\n\t\t\tmfp.index = _getLoopedId(mfp.index + 1);\n\t\t\tmfp.updateItemHTML();\n\t\t},\n\t\tprev: function() {\n\t\t\tmfp.direction = false;\n\t\t\tmfp.index = _getLoopedId(mfp.index - 1);\n\t\t\tmfp.updateItemHTML();\n\t\t},\n\t\tgoTo: function(newIndex) {\n\t\t\tmfp.direction = (newIndex >= mfp.index);\n\t\t\tmfp.index = newIndex;\n\t\t\tmfp.updateItemHTML();\n\t\t},\n\t\tpreloadNearbyImages: function() {\n\t\t\tvar p = mfp.st.gallery.preload,\n\t\t\t\tpreloadBefore = Math.min(p[0], mfp.items.length),\n\t\t\t\tpreloadAfter = Math.min(p[1], mfp.items.length),\n\t\t\t\ti;\n\n\t\t\tfor(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) {\n\t\t\t\tmfp._preloadItem(mfp.index+i);\n\t\t\t}\n\t\t\tfor(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) {\n\t\t\t\tmfp._preloadItem(mfp.index-i);\n\t\t\t}\n\t\t},\n\t\t_preloadItem: function(index) {\n\t\t\tindex = _getLoopedId(index);\n\n\t\t\tif(mfp.items[index].preloaded) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar item = mfp.items[index];\n\t\t\tif(!item.parsed) {\n\t\t\t\titem = mfp.parseEl( index );\n\t\t\t}\n\n\t\t\t_mfpTrigger('LazyLoad', item);\n\n\t\t\tif(item.type === 'image') {\n\t\t\t\titem.img = $('<img class=\"mfp-img\" />').on('load.mfploader', function() {\n\t\t\t\t\titem.hasSize = true;\n\t\t\t\t}).on('error.mfploader', function() {\n\t\t\t\t\titem.hasSize = true;\n\t\t\t\t\titem.loadError = true;\n\t\t\t\t\t_mfpTrigger('LazyLoadError', item);\n\t\t\t\t}).attr('src', item.src);\n\t\t\t}\n\n\n\t\t\titem.preloaded = true;\n\t\t}\n\t}\n});\n\n/*\nTouch Support that might be implemented some day\n\naddSwipeGesture: function() {\n\tvar startX,\n\t\tmoved,\n\t\tmultipleTouches;\n\n\t\treturn;\n\n\tvar namespace = '.mfp',\n\t\taddEventNames = function(pref, down, move, up, cancel) {\n\t\t\tmfp._tStart = pref + down + namespace;\n\t\t\tmfp._tMove = pref + move + namespace;\n\t\t\tmfp._tEnd = pref + up + namespace;\n\t\t\tmfp._tCancel = pref + cancel + namespace;\n\t\t};\n\n\tif(window.navigator.msPointerEnabled) {\n\t\taddEventNames('MSPointer', 'Down', 'Move', 'Up', 'Cancel');\n\t} else if('ontouchstart' in window) {\n\t\taddEventNames('touch', 'start', 'move', 'end', 'cancel');\n\t} else {\n\t\treturn;\n\t}\n\t_window.on(mfp._tStart, function(e) {\n\t\tvar oE = e.originalEvent;\n\t\tmultipleTouches = moved = false;\n\t\tstartX = oE.pageX || oE.changedTouches[0].pageX;\n\t}).on(mfp._tMove, function(e) {\n\t\tif(e.originalEvent.touches.length > 1) {\n\t\t\tmultipleTouches = e.originalEvent.touches.length;\n\t\t} else {\n\t\t\t//e.preventDefault();\n\t\t\tmoved = true;\n\t\t}\n\t}).on(mfp._tEnd + ' ' + mfp._tCancel, function(e) {\n\t\tif(moved && !multipleTouches) {\n\t\t\tvar oE = e.originalEvent,\n\t\t\t\tdiff = startX - (oE.pageX || oE.changedTouches[0].pageX);\n\n\t\t\tif(diff > 20) {\n\t\t\t\tmfp.next();\n\t\t\t} else if(diff < -20) {\n\t\t\t\tmfp.prev();\n\t\t\t}\n\t\t}\n\t});\n},\n*/\n\n\n/*>>gallery*/\n\n/*>>retina*/\n\nvar RETINA_NS = 'retina';\n\n$.magnificPopup.registerModule(RETINA_NS, {\n\toptions: {\n\t\treplaceSrc: function(item) {\n\t\t\treturn item.src.replace(/\\.\\w+$/, function(m) { return '@2x' + m; });\n\t\t},\n\t\tratio: 1 // Function or number.  Set to 1 to disable.\n\t},\n\tproto: {\n\t\tinitRetina: function() {\n\t\t\tif(window.devicePixelRatio > 1) {\n\n\t\t\t\tvar st = mfp.st.retina,\n\t\t\t\t\tratio = st.ratio;\n\n\t\t\t\tratio = !isNaN(ratio) ? ratio : ratio();\n\n\t\t\t\tif(ratio > 1) {\n\t\t\t\t\t_mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) {\n\t\t\t\t\t\titem.img.css({\n\t\t\t\t\t\t\t'max-width': item.img[0].naturalWidth / ratio,\n\t\t\t\t\t\t\t'width': '100%'\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t\t_mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) {\n\t\t\t\t\t\titem.src = st.replaceSrc(item, ratio);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n});\n\n/*>>retina*/\n\n/*>>fastclick*/\n/**\n * FastClick event implementation. (removes 300ms delay on touch devices)\n * Based on https://developers.google.com/mobile/articles/fast_buttons\n *\n * You may use it outside the Magnific Popup by calling just:\n *\n * $('.your-el').mfpFastClick(function() {\n *     console.log('Clicked!');\n * });\n *\n * To unbind:\n * $('.your-el').destroyMfpFastClick();\n * \n * \n * Note that it's a very basic and simple implementation, it blocks ghost click on the same element where it was bound.\n * If you need something more advanced, use plugin by FT Labs https://github.com/ftlabs/fastclick\n * \n */\n\n(function() {\n\tvar ghostClickDelay = 1000,\n\t\tsupportsTouch = 'ontouchstart' in window,\n\t\tunbindTouchMove = function() {\n\t\t\t_window.off('touchmove'+ns+' touchend'+ns);\n\t\t},\n\t\teName = 'mfpFastClick',\n\t\tns = '.'+eName;\n\n\n\t// As Zepto.js doesn't have an easy way to add custom events (like jQuery), so we implement it in this way\n\t$.fn.mfpFastClick = function(callback) {\n\n\t\treturn $(this).each(function() {\n\n\t\t\tvar elem = $(this),\n\t\t\t\tlock;\n\n\t\t\tif( supportsTouch ) {\n\n\t\t\t\tvar timeout,\n\t\t\t\t\tstartX,\n\t\t\t\t\tstartY,\n\t\t\t\t\tpointerMoved,\n\t\t\t\t\tpoint,\n\t\t\t\t\tnumPointers;\n\n\t\t\t\telem.on('touchstart' + ns, function(e) {\n\t\t\t\t\tpointerMoved = false;\n\t\t\t\t\tnumPointers = 1;\n\n\t\t\t\t\tpoint = e.originalEvent ? e.originalEvent.touches[0] : e.touches[0];\n\t\t\t\t\tstartX = point.clientX;\n\t\t\t\t\tstartY = point.clientY;\n\n\t\t\t\t\t_window.on('touchmove'+ns, function(e) {\n\t\t\t\t\t\tpoint = e.originalEvent ? e.originalEvent.touches : e.touches;\n\t\t\t\t\t\tnumPointers = point.length;\n\t\t\t\t\t\tpoint = point[0];\n\t\t\t\t\t\tif (Math.abs(point.clientX - startX) > 10 ||\n\t\t\t\t\t\t\tMath.abs(point.clientY - startY) > 10) {\n\t\t\t\t\t\t\tpointerMoved = true;\n\t\t\t\t\t\t\tunbindTouchMove();\n\t\t\t\t\t\t}\n\t\t\t\t\t}).on('touchend'+ns, function(e) {\n\t\t\t\t\t\tunbindTouchMove();\n\t\t\t\t\t\tif(pointerMoved || numPointers > 1) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlock = true;\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\t\ttimeout = setTimeout(function() {\n\t\t\t\t\t\t\tlock = false;\n\t\t\t\t\t\t}, ghostClickDelay);\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t}\n\n\t\t\telem.on('click' + ns, function() {\n\t\t\t\tif(!lock) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t};\n\n\t$.fn.destroyMfpFastClick = function() {\n\t\t$(this).off('touchstart' + ns + ' click' + ns);\n\t\tif(supportsTouch) _window.off('touchmove'+ns+' touchend'+ns);\n\t};\n})();\n\n/*>>fastclick*/\n _checkInstance(); }));"
  },
  {
    "path": "static/assets/plugins/magnific-popup/dist/magnific-popup.css",
    "content": "/* Magnific Popup CSS */\n.mfp-bg {\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  z-index: 1042;\n  overflow: hidden;\n  position: fixed;\n  background: #0b0b0b;\n  opacity: 0.8;\n  filter: alpha(opacity=80); }\n\n.mfp-wrap {\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  z-index: 1043;\n  position: fixed;\n  outline: none !important;\n  -webkit-backface-visibility: hidden; }\n\n.mfp-container {\n  text-align: center;\n  position: absolute;\n  width: 100%;\n  height: 100%;\n  left: 0;\n  top: 0;\n  padding: 0 8px;\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box; }\n\n.mfp-container:before {\n  content: '';\n  display: inline-block;\n  height: 100%;\n  vertical-align: middle; }\n\n.mfp-align-top .mfp-container:before {\n  display: none; }\n\n.mfp-content {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n  margin: 0 auto;\n  text-align: left;\n  z-index: 1045; }\n\n.mfp-inline-holder .mfp-content, .mfp-ajax-holder .mfp-content {\n  width: 100%;\n  cursor: auto; }\n\n.mfp-ajax-cur {\n  cursor: progress; }\n\n.mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close {\n  cursor: -moz-zoom-out;\n  cursor: -webkit-zoom-out;\n  cursor: zoom-out; }\n\n.mfp-zoom {\n  cursor: pointer;\n  cursor: -webkit-zoom-in;\n  cursor: -moz-zoom-in;\n  cursor: zoom-in; }\n\n.mfp-auto-cursor .mfp-content {\n  cursor: auto; }\n\n.mfp-close, .mfp-arrow, .mfp-preloader, .mfp-counter {\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  user-select: none; }\n\n.mfp-loading.mfp-figure {\n  display: none; }\n\n.mfp-hide {\n  display: none !important; }\n\n.mfp-preloader {\n  color: #cccccc;\n  position: absolute;\n  top: 50%;\n  width: auto;\n  text-align: center;\n  margin-top: -0.8em;\n  left: 8px;\n  right: 8px;\n  z-index: 1044; }\n  .mfp-preloader a {\n    color: #cccccc; }\n    .mfp-preloader a:hover {\n      color: white; }\n\n.mfp-s-ready .mfp-preloader {\n  display: none; }\n\n.mfp-s-error .mfp-content {\n  display: none; }\n\nbutton.mfp-close, button.mfp-arrow {\n  overflow: visible;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n  -webkit-appearance: none;\n  display: block;\n  outline: none;\n  padding: 0;\n  z-index: 1046;\n  -webkit-box-shadow: none;\n  box-shadow: none; }\nbutton::-moz-focus-inner {\n  padding: 0;\n  border: 0; }\n\n.mfp-close {\n  width: 44px;\n  height: 44px;\n  line-height: 44px;\n  position: absolute;\n  right: 0;\n  top: 0;\n  text-decoration: none;\n  text-align: center;\n  opacity: 0.65;\n  filter: alpha(opacity=65);\n  padding: 0 0 18px 10px;\n  color: white;\n  font-style: normal;\n  font-size: 28px;\n  font-family: Arial, Baskerville, monospace; }\n  .mfp-close:hover, .mfp-close:focus {\n    opacity: 1;\n    filter: alpha(opacity=100); }\n  .mfp-close:active {\n    top: 1px; }\n\n.mfp-close-btn-in .mfp-close {\n  color: #333333; }\n\n.mfp-image-holder .mfp-close, .mfp-iframe-holder .mfp-close {\n  color: white;\n  right: -6px;\n  text-align: right;\n  padding-right: 6px;\n  width: 100%; }\n\n.mfp-counter {\n  position: absolute;\n  top: 0;\n  right: 0;\n  color: #cccccc;\n  font-size: 12px;\n  line-height: 18px;\n  white-space: nowrap; }\n\n.mfp-arrow {\n  position: absolute;\n  opacity: 0.65;\n  filter: alpha(opacity=65);\n  margin: 0;\n  top: 50%;\n  margin-top: -55px;\n  padding: 0;\n  width: 90px;\n  height: 110px;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0); }\n  .mfp-arrow:active {\n    margin-top: -54px; }\n  .mfp-arrow:hover, .mfp-arrow:focus {\n    opacity: 1;\n    filter: alpha(opacity=100); }\n  .mfp-arrow:before, .mfp-arrow:after, .mfp-arrow .mfp-b, .mfp-arrow .mfp-a {\n    content: '';\n    display: block;\n    width: 0;\n    height: 0;\n    position: absolute;\n    left: 0;\n    top: 0;\n    margin-top: 35px;\n    margin-left: 35px;\n    border: medium inset transparent; }\n  .mfp-arrow:after, .mfp-arrow .mfp-a {\n    border-top-width: 13px;\n    border-bottom-width: 13px;\n    top: 8px; }\n  .mfp-arrow:before, .mfp-arrow .mfp-b {\n    border-top-width: 21px;\n    border-bottom-width: 21px;\n    opacity: 0.7; }\n\n.mfp-arrow-left {\n  left: 0; }\n  .mfp-arrow-left:after, .mfp-arrow-left .mfp-a {\n    border-right: 17px solid white;\n    margin-left: 31px; }\n  .mfp-arrow-left:before, .mfp-arrow-left .mfp-b {\n    margin-left: 25px;\n    border-right: 27px solid #3f3f3f; }\n\n.mfp-arrow-right {\n  right: 0; }\n  .mfp-arrow-right:after, .mfp-arrow-right .mfp-a {\n    border-left: 17px solid white;\n    margin-left: 39px; }\n  .mfp-arrow-right:before, .mfp-arrow-right .mfp-b {\n    border-left: 27px solid #3f3f3f; }\n\n.mfp-iframe-holder {\n  padding-top: 40px;\n  padding-bottom: 40px; }\n  .mfp-iframe-holder .mfp-content {\n    line-height: 0;\n    width: 100%;\n    max-width: 900px; }\n  .mfp-iframe-holder .mfp-close {\n    top: -40px; }\n\n.mfp-iframe-scaler {\n  width: 100%;\n  height: 0;\n  overflow: hidden;\n  padding-top: 56.25%; }\n  .mfp-iframe-scaler iframe {\n    position: absolute;\n    display: block;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);\n    background: black; }\n\n/* Main image in popup */\nimg.mfp-img {\n  width: auto;\n  max-width: 100%;\n  height: auto;\n  display: block;\n  line-height: 0;\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  padding: 40px 0 40px;\n  margin: 0 auto; }\n\n/* The shadow behind the image */\n.mfp-figure {\n  line-height: 0; }\n  .mfp-figure:after {\n    content: '';\n    position: absolute;\n    left: 0;\n    top: 40px;\n    bottom: 40px;\n    display: block;\n    right: 0;\n    width: auto;\n    height: auto;\n    z-index: -1;\n    box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);\n    background: #444444; }\n  .mfp-figure small {\n    color: #bdbdbd;\n    display: block;\n    font-size: 12px;\n    line-height: 14px; }\n  .mfp-figure figure {\n    margin: 0; }\n\n.mfp-bottom-bar {\n  margin-top: -36px;\n  position: absolute;\n  top: 100%;\n  left: 0;\n  width: 100%;\n  cursor: auto; }\n\n.mfp-title {\n  text-align: left;\n  line-height: 18px;\n  color: #f3f3f3;\n  word-wrap: break-word;\n  padding-right: 36px; }\n\n.mfp-image-holder .mfp-content {\n  max-width: 100%; }\n\n.mfp-gallery .mfp-image-holder .mfp-figure {\n  cursor: pointer; }\n\n@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) {\n  /**\n       * Remove all paddings around the image on small screen\n       */\n  .mfp-img-mobile .mfp-image-holder {\n    padding-left: 0;\n    padding-right: 0; }\n  .mfp-img-mobile img.mfp-img {\n    padding: 0; }\n  .mfp-img-mobile .mfp-figure:after {\n    top: 0;\n    bottom: 0; }\n  .mfp-img-mobile .mfp-figure small {\n    display: inline;\n    margin-left: 5px; }\n  .mfp-img-mobile .mfp-bottom-bar {\n    background: rgba(0, 0, 0, 0.6);\n    bottom: 0;\n    margin: 0;\n    top: auto;\n    padding: 3px 5px;\n    position: fixed;\n    -webkit-box-sizing: border-box;\n    -moz-box-sizing: border-box;\n    box-sizing: border-box; }\n    .mfp-img-mobile .mfp-bottom-bar:empty {\n      padding: 0; }\n  .mfp-img-mobile .mfp-counter {\n    right: 5px;\n    top: 3px; }\n  .mfp-img-mobile .mfp-close {\n    top: 0;\n    right: 0;\n    width: 35px;\n    height: 35px;\n    line-height: 35px;\n    background: rgba(0, 0, 0, 0.6);\n    position: fixed;\n    text-align: center;\n    padding: 0; } }\n\n@media all and (max-width: 900px) {\n  .mfp-arrow {\n    -webkit-transform: scale(0.75);\n    transform: scale(0.75); }\n  .mfp-arrow-left {\n    -webkit-transform-origin: 0;\n    transform-origin: 0; }\n  .mfp-arrow-right {\n    -webkit-transform-origin: 100%;\n    transform-origin: 100%; }\n  .mfp-container {\n    padding-left: 6px;\n    padding-right: 6px; } }\n\n.mfp-ie7 .mfp-img {\n  padding: 0; }\n.mfp-ie7 .mfp-bottom-bar {\n  width: 600px;\n  left: 50%;\n  margin-left: -300px;\n  margin-top: 5px;\n  padding-bottom: 5px; }\n.mfp-ie7 .mfp-container {\n  padding: 0; }\n.mfp-ie7 .mfp-content {\n  padding-top: 44px; }\n.mfp-ie7 .mfp-close {\n  top: 0;\n  right: 0;\n  padding-top: 0; }\n"
  },
  {
    "path": "static/assets/plugins/magnific-popup/src/css/_settings.scss",
    "content": "////////////////////////\n//      Settings      //\n////////////////////////\n\n// overlay\n$mfp-overlay-color:                   #0b0b0b;                    // Color of overlay screen\n$mfp-overlay-opacity:                 0.8;                        // Opacity of overlay screen\n$mfp-shadow:                          0 0 8px rgba(0, 0, 0, 0.6); // Shadow on image or iframe\n\n// spacing\n$mfp-popup-padding-left:              8px;                        // Padding from left and from right side\n$mfp-popup-padding-left-mobile:       6px;                        // Same as above, but is applied when width of window is less than 800px\n\n$mfp-z-index-base:                    1040;                        // Base z-index of popup\n\n// controls\n$mfp-include-arrows:                  true;                       // Include styles for nav arrows\n$mfp-controls-opacity:                0.65;                       // Opacity of controls\n$mfp-controls-color:                  #FFF;                       // Color of controls\n$mfp-controls-border-color:           #3F3F3F; \t                  // Border color of controls\n$mfp-inner-close-icon-color:          #333;                       // Color of close button when inside\n$mfp-controls-text-color:             #CCC;                       // Color of preloader and \"1 of X\" indicator\n$mfp-controls-text-color-hover:       #FFF;                       // Hover color of preloader and \"1 of X\" indicator\n$mfp-IE7support:                      true;                       // Very basic IE7 support\n\n// Iframe-type options\n$mfp-include-iframe-type:             true;                       // Enable Iframe-type popups\n$mfp-iframe-padding-top:              40px;                       // Iframe padding top\n$mfp-iframe-background:               #000;                       // Background color of iframes\n$mfp-iframe-max-width:                900px;                      // Maximum width of iframes\n$mfp-iframe-ratio:                    9/16;                       // Ratio of iframe (9/16 = widescreen, 3/4 = standard, etc.)\n\n// Image-type options\n$mfp-include-image-type:              true;                       // Enable Image-type popups\n$mfp-image-background:                #444 !default;\n$mfp-image-padding-top:               40px;                       // Image padding top\n$mfp-image-padding-bottom:            40px;                       // Image padding bottom\n$mfp-include-mobile-layout-for-image: true;                       // Removes paddings from top and bottom\n\n// Image caption options\n$mfp-caption-title-color:             #F3F3F3;                    // Caption title color\n$mfp-caption-subtitle-color:          #BDBDBD;                    // Caption subtitle color\n\n// A11y\n$mfp-use-visuallyhidden:              false; "
  },
  {
    "path": "static/assets/plugins/magnific-popup/src/css/main.scss",
    "content": "/* Magnific Popup CSS */\n\n@import \"settings\";\n\n////////////////////////\n//\n// Contents:\n//\n// 1. Default Settings\n// 2. General styles\n//    - Transluscent overlay\n//    - Containers, wrappers\n//    - Cursors\n//    - Helper classes\n// 3. Appearance\n//    - Preloader & text that displays error messages\n//    - CSS reset for buttons\n//    - Close icon\n//    - \"1 of X\" counter\n//    - Navigation (left/right) arrows\n//    - Iframe content type styles\n//    - Image content type styles\n//    - Media query where size of arrows is reduced\n//    - IE7 support\n//\n////////////////////////\n\n\n\n////////////////////////\n// 1. Default Settings\n////////////////////////\n\n$mfp-overlay-color:                   #0b0b0b !default;\n$mfp-overlay-opacity:                 0.8 !default;\n$mfp-shadow:                          0 0 8px rgba(0, 0, 0, 0.6) !default; // shadow on image or iframe\n$mfp-popup-padding-left:              8px !default; // Padding from left and from right side\n$mfp-popup-padding-left-mobile:       6px !default; // Same as above, but is applied when width of window is less than 800px\n\n$mfp-z-index-base:                    1040 !default; // Base z-index of popup\n$mfp-include-arrows:                  true !default; // include styles for nav arrows\n$mfp-controls-opacity:                0.65 !default;\n$mfp-controls-color:                  #FFF !default;\n$mfp-controls-border-color:           #3F3F3F !default;\n$mfp-inner-close-icon-color:          #333 !default;\n$mfp-controls-text-color:             #CCC !default; // Color of preloader and \"1 of X\" indicator\n$mfp-controls-text-color-hover:       #FFF !default;\n$mfp-IE7support:                      true !default; // Very basic IE7 support\n\n// Iframe-type options\n$mfp-include-iframe-type:             true !default;\n$mfp-iframe-padding-top:              40px !default;\n$mfp-iframe-background:               #000 !default;\n$mfp-iframe-max-width:                900px !default;\n$mfp-iframe-ratio:                    9/16 !default;\n\n// Image-type options\n$mfp-include-image-type:              true !default;\n$mfp-image-background:                #444 !default;\n$mfp-image-padding-top:               40px !default;\n$mfp-image-padding-bottom:            40px !default;\n$mfp-include-mobile-layout-for-image: true !default; // Removes paddings from top and bottom\n\n// Image caption options\n$mfp-caption-title-color:             #F3F3F3 !default;\n$mfp-caption-subtitle-color:          #BDBDBD !default;\n\n// A11y\n$mfp-use-visuallyhidden:              false !default; // Hide content from browsers, but make it available for screen readers \n\n\n\n////////////////////////\n// 2. General styles\n////////////////////////\n\n// Transluscent overlay\n.mfp-bg {\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  z-index: $mfp-z-index-base + 2;\n  overflow: hidden;\n  position: fixed;\n\n  background: $mfp-overlay-color;\n  opacity: $mfp-overlay-opacity;\n  @if $mfp-IE7support {\n    filter: unquote(\"alpha(opacity=#{$mfp-overlay-opacity*100})\");\n  }\n}\n\n// Wrapper for popup\n.mfp-wrap {\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  z-index: $mfp-z-index-base + 3;\n  position: fixed;\n  outline: none !important;\n  -webkit-backface-visibility: hidden; // fixes webkit bug that can cause \"false\" scrollbar\n}\n\n// Root container\n.mfp-container {\n  text-align: center;\n  position: absolute;\n  width: 100%;\n  height: 100%;\n  left: 0;\n  top: 0;\n  padding: 0 $mfp-popup-padding-left;\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n\n// Vertical centerer helper\n.mfp-container {\n  &:before {\n    content: '';\n    display: inline-block;\n    height: 100%;\n    vertical-align: middle;\n  }\n}\n\n// Remove vertical centering when popup has class `mfp-align-top`\n.mfp-align-top {\n  .mfp-container { \n    &:before {\n      display: none;\n    }\n  }\n}\n\n// Popup content holder\n.mfp-content {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n  margin: 0 auto;\n  text-align: left;\n  z-index: $mfp-z-index-base + 5;\n}\n.mfp-inline-holder,\n.mfp-ajax-holder {\n  .mfp-content {\n    width: 100%;\n    cursor: auto;\n  }\n}\n\n// Cursors\n.mfp-ajax-cur {\n  cursor: progress;\n}\n.mfp-zoom-out-cur {\n  &, .mfp-image-holder .mfp-close {\n    cursor: -moz-zoom-out;\n    cursor: -webkit-zoom-out;\n    cursor: zoom-out;\n  }\n}\n.mfp-zoom {\n  cursor: pointer;\n  cursor: -webkit-zoom-in;\n  cursor: -moz-zoom-in;\n  cursor: zoom-in;\n}\n.mfp-auto-cursor {\n  .mfp-content {\n    cursor: auto;\n  }\n}\n\n.mfp-close,\n.mfp-arrow,\n.mfp-preloader,\n.mfp-counter {\n  -webkit-user-select:none;\n  -moz-user-select: none;\n  user-select: none;\n}\n\n// Hide the image during the loading\n.mfp-loading {\n  &.mfp-figure {\n    display: none;\n  }\n}\n\n// Helper class that hides stuff\n@if $mfp-use-visuallyhidden {\n  // From HTML5 Boilerplate https://github.com/h5bp/html5-boilerplate/blob/v4.2.0/doc/css.md#visuallyhidden\n  .mfp-hide {\n    border: 0 !important;\n    clip: rect(0 0 0 0) !important;\n    height: 1px !important;\n    margin: -1px !important;\n    overflow: hidden !important;\n    padding: 0 !important;\n    position: absolute !important;\n    width: 1px !important;\n  }\n} @else {\n  .mfp-hide {\n    display: none !important;\n  }\n}\n\n\n////////////////////////\n// 3. Appearance\n////////////////////////\n\n// Preloader and text that displays error messages\n.mfp-preloader {\n  color: $mfp-controls-text-color;\n  position: absolute;\n  top: 50%;\n  width: auto;\n  text-align: center;\n  margin-top: -0.8em;\n  left: 8px;\n  right: 8px;\n  z-index: $mfp-z-index-base + 4;\n  a {\n    color: $mfp-controls-text-color;\n    &:hover {\n      color: $mfp-controls-text-color-hover;\n    }\n  }\n}\n\n// Hide preloader when content successfully loaded\n.mfp-s-ready {\n  .mfp-preloader {\n    display: none;\n  }\n}\n\n// Hide content when it was not loaded\n.mfp-s-error {\n  .mfp-content {\n    display: none;\n  }\n}\n\n// CSS-reset for buttons\nbutton {\n  &.mfp-close,\n  &.mfp-arrow {\n    overflow: visible;\n    cursor: pointer;\n    background: transparent;\n    border: 0;\n    -webkit-appearance: none;\n    display: block;\n    outline: none;\n    padding: 0;\n    z-index: $mfp-z-index-base + 6;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n  }\n  &::-moz-focus-inner {\n      padding: 0;\n      border: 0\n  }\n}\n\n\n// Close icon\n.mfp-close {\n  width: 44px;\n  height: 44px;\n  line-height: 44px;\n\n  position: absolute;\n  right: 0;\n  top: 0;\n  text-decoration: none;\n  text-align: center;\n  opacity: $mfp-controls-opacity;\n  @if $mfp-IE7support {\n    filter: unquote(\"alpha(opacity=#{$mfp-controls-opacity*100})\");\n  }\n  padding: 0 0 18px 10px;\n  color: $mfp-controls-color;\n\n  font-style: normal;\n  font-size: 28px;\n  font-family: Arial, Baskerville, monospace;\n\n  &:hover,\n  &:focus {\n    opacity: 1;\n    @if $mfp-IE7support {\n      filter: unquote(\"alpha(opacity=#{1*100})\");\n    }\n  }\n\n  &:active {\n    top: 1px;\n  }\n}\n.mfp-close-btn-in {\n  .mfp-close {\n    color: $mfp-inner-close-icon-color;\n  }\n}\n.mfp-image-holder,\n.mfp-iframe-holder {\n  .mfp-close {\n    color: $mfp-controls-color;\n    right: -6px;\n    text-align: right;\n    padding-right: 6px;\n    width: 100%;\n  }\n}\n\n// \"1 of X\" counter\n.mfp-counter {\n  position: absolute;\n  top: 0;\n  right: 0;\n  color: $mfp-controls-text-color;\n  font-size: 12px;\n  line-height: 18px;\n  white-space: nowrap;\n}\n\n// Navigation arrows\n@if $mfp-include-arrows {\n  .mfp-arrow {\n    position: absolute;\n    opacity: $mfp-controls-opacity;\n    @if $mfp-IE7support {\n      filter: unquote(\"alpha(opacity=#{$mfp-controls-opacity*100})\");\n    }\n    margin: 0;\n    top: 50%;\n    margin-top: -55px;\n    padding: 0;\n    width: 90px;\n    height: 110px;\n    -webkit-tap-highlight-color: rgba(0,0,0,0);\n    &:active {\n      margin-top: -54px;\n    }\n    &:hover,\n    &:focus {\n      opacity: 1;\n      @if $mfp-IE7support {\n        filter: unquote(\"alpha(opacity=#{1*100})\");\n      }\n    }\n    &:before,\n    &:after,\n    .mfp-b,\n    .mfp-a {\n      content: '';\n      display: block;\n      width: 0;\n      height: 0;\n      position: absolute;\n      left: 0;\n      top: 0;\n      margin-top: 35px;\n      margin-left: 35px;\n      border: medium inset transparent;\n    }\n\n    &:after,\n    .mfp-a {\n\n      border-top-width: 13px;\n      border-bottom-width: 13px;\n      top:8px;\n    }\n\n    &:before,\n    .mfp-b {\n      border-top-width: 21px;\n      border-bottom-width: 21px;\n      opacity: 0.7;\n    }\n\n  }\n\n  .mfp-arrow-left {\n    left: 0;\n\n    &:after,\n    .mfp-a {\n      border-right: 17px solid $mfp-controls-color;\n      margin-left: 31px;\n    }\n    &:before,\n    .mfp-b {\n      margin-left: 25px;\n      border-right: 27px solid $mfp-controls-border-color; \n    }\n  }\n\n  .mfp-arrow-right {\n    right: 0;\n    &:after,\n    .mfp-a {\n      border-left: 17px solid $mfp-controls-color;\n      margin-left: 39px\n    }\n    &:before,\n    .mfp-b {\n      border-left: 27px solid $mfp-controls-border-color;\n    }\n  }\n}\n\n\n\n// Iframe content type\n@if $mfp-include-iframe-type {\n  .mfp-iframe-holder {\n    padding-top: $mfp-iframe-padding-top;\n    padding-bottom: $mfp-iframe-padding-top;\n    .mfp-content {\n      line-height: 0;\n      width: 100%;\n      max-width: $mfp-iframe-max-width;\n    }\n    .mfp-close {\n      top: -40px;\n    }\n  }\n  .mfp-iframe-scaler {\n    width: 100%;\n    height: 0;\n    overflow: hidden;\n    padding-top: $mfp-iframe-ratio * 100%;\n    iframe {\n      position: absolute;\n      display: block;\n      top: 0;\n      left: 0;\n      width: 100%;\n      height: 100%;\n      box-shadow: $mfp-shadow;\n      background: $mfp-iframe-background;\n    }\n  }\n}\n\n\n\n// Image content type\n@if $mfp-include-image-type {\n\n  /* Main image in popup */\n  img {\n    &.mfp-img {\n      width: auto;\n      max-width: 100%;\n      height: auto;\n      display: block;\n      line-height: 0;\n      -webkit-box-sizing: border-box;\n      -moz-box-sizing: border-box;\n      box-sizing: border-box;\n      padding: $mfp-image-padding-top 0 $mfp-image-padding-bottom;\n      margin: 0 auto;\n    }\n  }\n\n  /* The shadow behind the image */\n  .mfp-figure {\n    line-height: 0;\n    &:after {\n      content: '';\n      position: absolute;\n      left: 0;\n      top: $mfp-image-padding-top;\n      bottom: $mfp-image-padding-bottom;\n      display: block;\n      right: 0;\n      width: auto;\n      height: auto;\n      z-index: -1;\n      box-shadow: $mfp-shadow;\n      background: $mfp-image-background;\n    }\n    small {\n      color: $mfp-caption-subtitle-color;\n      display: block;\n      font-size: 12px;\n      line-height: 14px;\n    }\n    figure {\n      margin: 0;\n    }\n  }\n  .mfp-bottom-bar {\n    margin-top: -$mfp-image-padding-bottom + 4;\n    position: absolute;\n    top: 100%;\n    left: 0;\n    width: 100%;\n    cursor: auto;\n  }\n  .mfp-title {\n    text-align: left;\n    line-height: 18px;\n    color: $mfp-caption-title-color;\n    word-wrap: break-word;\n    padding-right: 36px; // leave some space for counter at right side\n  }\n\n  .mfp-image-holder {\n    .mfp-content {\n      max-width: 100%;\n    }\n  }\n\n  .mfp-gallery {\n    .mfp-image-holder {\n      .mfp-figure {\n        cursor: pointer;\n      }\n    }\n  }\n\n\n  @if $mfp-include-mobile-layout-for-image {\n    @media screen and (max-width: 800px) and (orientation:landscape), screen and (max-height: 300px) {\n      /**\n       * Remove all paddings around the image on small screen\n       */\n      .mfp-img-mobile {\n        .mfp-image-holder {\n          padding-left: 0;\n          padding-right: 0;\n        }\n        img {\n          &.mfp-img {\n            padding: 0;\n          }\n        }\n        .mfp-figure {\n          // The shadow behind the image\n          &:after {\n            top: 0;\n            bottom: 0;\n          }\n          small {\n            display: inline;\n            margin-left: 5px;\n          }\n        }\n        .mfp-bottom-bar {\n          background: rgba(0,0,0,0.6);\n          bottom: 0;\n          margin: 0;\n          top: auto;\n          padding: 3px 5px;\n          position: fixed;\n          -webkit-box-sizing: border-box;\n          -moz-box-sizing: border-box;\n          box-sizing: border-box;\n          &:empty {\n            padding: 0;\n          }\n        }\n        .mfp-counter {\n          right: 5px;\n          top: 3px;\n        }\n        .mfp-close {\n          top: 0;\n          right: 0;\n          width: 35px;\n          height: 35px;\n          line-height: 35px;\n          background: rgba(0, 0, 0, 0.6);\n          position: fixed;\n          text-align: center;\n          padding: 0;\n        }\n      }\n    }\n  }\n}\n\n\n\n// Scale navigation arrows and reduce padding from sides\n@media all and (max-width: 900px) {\n  .mfp-arrow {\n    -webkit-transform: scale(0.75);\n    transform: scale(0.75);\n  }\n  .mfp-arrow-left {\n    -webkit-transform-origin: 0;\n    transform-origin: 0;\n  }\n  .mfp-arrow-right {\n    -webkit-transform-origin: 100%;\n    transform-origin: 100%;\n  }\n  .mfp-container {\n    padding-left: $mfp-popup-padding-left-mobile;\n    padding-right: $mfp-popup-padding-left-mobile;\n  }\n}\n\n\n\n// IE7 support\n// Styles that make popup look nicier in old IE\n@if $mfp-IE7support {\n  .mfp-ie7 {\n    .mfp-img {\n      padding: 0;\n    }\n    .mfp-bottom-bar {\n      width: 600px;\n      left: 50%;\n      margin-left: -300px;\n      margin-top: 5px;\n      padding-bottom: 5px;\n    }\n    .mfp-container {\n      padding: 0;\n    }\n    .mfp-content {\n      padding-top: 44px;\n    }\n    .mfp-close {\n      top: 0;\n      right: 0;\n      padding-top: 0;\n    }\n  }\n}\n"
  },
  {
    "path": "static/assets/plugins/magnific-popup/src/js/ajax.js",
    "content": "var AJAX_NS = 'ajax',\n\t_ajaxCur,\n\t_removeAjaxCursor = function() {\n\t\tif(_ajaxCur) {\n\t\t\t_body.removeClass(_ajaxCur);\n\t\t}\n\t},\n\t_destroyAjaxRequest = function() {\n\t\t_removeAjaxCursor();\n\t\tif(mfp.req) {\n\t\t\tmfp.req.abort();\n\t\t}\n\t};\n\n$.magnificPopup.registerModule(AJAX_NS, {\n\n\toptions: {\n\t\tsettings: null,\n\t\tcursor: 'mfp-ajax-cur',\n\t\ttError: '<a href=\"%url%\">The content</a> could not be loaded.'\n\t},\n\n\tproto: {\n\t\tinitAjax: function() {\n\t\t\tmfp.types.push(AJAX_NS);\n\t\t\t_ajaxCur = mfp.st.ajax.cursor;\n\n\t\t\t_mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest);\n\t\t\t_mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest);\n\t\t},\n\t\tgetAjax: function(item) {\n\n\t\t\tif(_ajaxCur)\n\t\t\t\t_body.addClass(_ajaxCur);\n\n\t\t\tmfp.updateStatus('loading');\n\n\t\t\tvar opts = $.extend({\n\t\t\t\turl: item.src,\n\t\t\t\tsuccess: function(data, textStatus, jqXHR) {\n\t\t\t\t\tvar temp = {\n\t\t\t\t\t\tdata:data,\n\t\t\t\t\t\txhr:jqXHR\n\t\t\t\t\t};\n\n\t\t\t\t\t_mfpTrigger('ParseAjax', temp);\n\n\t\t\t\t\tmfp.appendContent( $(temp.data), AJAX_NS );\n\n\t\t\t\t\titem.finished = true;\n\n\t\t\t\t\t_removeAjaxCursor();\n\n\t\t\t\t\tmfp._setFocus();\n\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tmfp.wrap.addClass(READY_CLASS);\n\t\t\t\t\t}, 16);\n\n\t\t\t\t\tmfp.updateStatus('ready');\n\n\t\t\t\t\t_mfpTrigger('AjaxContentAdded');\n\t\t\t\t},\n\t\t\t\terror: function() {\n\t\t\t\t\t_removeAjaxCursor();\n\t\t\t\t\titem.finished = item.loadError = true;\n\t\t\t\t\tmfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src));\n\t\t\t\t}\n\t\t\t}, mfp.st.ajax.settings);\n\n\t\t\tmfp.req = $.ajax(opts);\n\n\t\t\treturn '';\n\t\t}\n\t}\n});\n\n\n\n\n\n\t"
  },
  {
    "path": "static/assets/plugins/magnific-popup/src/js/core.js",
    "content": "/**\n * \n * Magnific Popup Core JS file\n * \n */\n\n\n/**\n * Private static constants\n */\nvar CLOSE_EVENT = 'Close',\n\tBEFORE_CLOSE_EVENT = 'BeforeClose',\n\tAFTER_CLOSE_EVENT = 'AfterClose',\n\tBEFORE_APPEND_EVENT = 'BeforeAppend',\n\tMARKUP_PARSE_EVENT = 'MarkupParse',\n\tOPEN_EVENT = 'Open',\n\tCHANGE_EVENT = 'Change',\n\tNS = 'mfp',\n\tEVENT_NS = '.' + NS,\n\tREADY_CLASS = 'mfp-ready',\n\tREMOVING_CLASS = 'mfp-removing',\n\tPREVENT_CLOSE_CLASS = 'mfp-prevent-close';\n\n\n/**\n * Private vars \n */\nvar mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this'\n\tMagnificPopup = function(){},\n\t_isJQ = !!(window.jQuery),\n\t_prevStatus,\n\t_window = $(window),\n\t_body,\n\t_document,\n\t_prevContentType,\n\t_wrapClasses,\n\t_currPopupType;\n\n\n/**\n * Private functions\n */\nvar _mfpOn = function(name, f) {\n\t\tmfp.ev.on(NS + name + EVENT_NS, f);\n\t},\n\t_getEl = function(className, appendTo, html, raw) {\n\t\tvar el = document.createElement('div');\n\t\tel.className = 'mfp-'+className;\n\t\tif(html) {\n\t\t\tel.innerHTML = html;\n\t\t}\n\t\tif(!raw) {\n\t\t\tel = $(el);\n\t\t\tif(appendTo) {\n\t\t\t\tel.appendTo(appendTo);\n\t\t\t}\n\t\t} else if(appendTo) {\n\t\t\tappendTo.appendChild(el);\n\t\t}\n\t\treturn el;\n\t},\n\t_mfpTrigger = function(e, data) {\n\t\tmfp.ev.triggerHandler(NS + e, data);\n\n\t\tif(mfp.st.callbacks) {\n\t\t\t// converts \"mfpEventName\" to \"eventName\" callback and triggers it if it's present\n\t\t\te = e.charAt(0).toLowerCase() + e.slice(1);\n\t\t\tif(mfp.st.callbacks[e]) {\n\t\t\t\tmfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]);\n\t\t\t}\n\t\t}\n\t},\n\t_getCloseBtn = function(type) {\n\t\tif(type !== _currPopupType || !mfp.currTemplate.closeBtn) {\n\t\t\tmfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) );\n\t\t\t_currPopupType = type;\n\t\t}\n\t\treturn mfp.currTemplate.closeBtn;\n\t},\n\t// Initialize Magnific Popup only when called at least once\n\t_checkInstance = function() {\n\t\tif(!$.magnificPopup.instance) {\n\t\t\tmfp = new MagnificPopup();\n\t\t\tmfp.init();\n\t\t\t$.magnificPopup.instance = mfp;\n\t\t}\n\t},\n\t// CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr\n\tsupportsTransitions = function() {\n\t\tvar s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist\n\t\t\tv = ['ms','O','Moz','Webkit']; // 'v' for vendor\n\n\t\tif( s['transition'] !== undefined ) {\n\t\t\treturn true; \n\t\t}\n\t\t\t\n\t\twhile( v.length ) {\n\t\t\tif( v.pop() + 'Transition' in s ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\t\t\t\n\t\treturn false;\n\t};\n\n\n\n/**\n * Public functions\n */\nMagnificPopup.prototype = {\n\n\tconstructor: MagnificPopup,\n\n\t/**\n\t * Initializes Magnific Popup plugin. \n\t * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed\n\t */\n\tinit: function() {\n\t\tvar appVersion = navigator.appVersion;\n\t\tmfp.isIE7 = appVersion.indexOf(\"MSIE 7.\") !== -1; \n\t\tmfp.isIE8 = appVersion.indexOf(\"MSIE 8.\") !== -1;\n\t\tmfp.isLowIE = mfp.isIE7 || mfp.isIE8;\n\t\tmfp.isAndroid = (/android/gi).test(appVersion);\n\t\tmfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion);\n\t\tmfp.supportsTransition = supportsTransitions();\n\n\t\t// We disable fixed positioned lightbox on devices that don't handle it nicely.\n\t\t// If you know a better way of detecting this - let me know.\n\t\tmfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) );\n\t\t_document = $(document);\n\n\t\tmfp.popupsCache = {};\n\t},\n\n\t/**\n\t * Opens popup\n\t * @param  data [description]\n\t */\n\topen: function(data) {\n\n\t\tif(!_body) {\n\t\t\t_body = $(document.body);\n\t\t}\n\n\t\tvar i;\n\n\t\tif(data.isObj === false) { \n\t\t\t// convert jQuery collection to array to avoid conflicts later\n\t\t\tmfp.items = data.items.toArray();\n\n\t\t\tmfp.index = 0;\n\t\t\tvar items = data.items,\n\t\t\t\titem;\n\t\t\tfor(i = 0; i < items.length; i++) {\n\t\t\t\titem = items[i];\n\t\t\t\tif(item.parsed) {\n\t\t\t\t\titem = item.el[0];\n\t\t\t\t}\n\t\t\t\tif(item === data.el[0]) {\n\t\t\t\t\tmfp.index = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tmfp.items = $.isArray(data.items) ? data.items : [data.items];\n\t\t\tmfp.index = data.index || 0;\n\t\t}\n\n\t\t// if popup is already opened - we just update the content\n\t\tif(mfp.isOpen) {\n\t\t\tmfp.updateItemHTML();\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tmfp.types = []; \n\t\t_wrapClasses = '';\n\t\tif(data.mainEl && data.mainEl.length) {\n\t\t\tmfp.ev = data.mainEl.eq(0);\n\t\t} else {\n\t\t\tmfp.ev = _document;\n\t\t}\n\n\t\tif(data.key) {\n\t\t\tif(!mfp.popupsCache[data.key]) {\n\t\t\t\tmfp.popupsCache[data.key] = {};\n\t\t\t}\n\t\t\tmfp.currTemplate = mfp.popupsCache[data.key];\n\t\t} else {\n\t\t\tmfp.currTemplate = {};\n\t\t}\n\n\n\n\t\tmfp.st = $.extend(true, {}, $.magnificPopup.defaults, data ); \n\t\tmfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos;\n\n\t\tif(mfp.st.modal) {\n\t\t\tmfp.st.closeOnContentClick = false;\n\t\t\tmfp.st.closeOnBgClick = false;\n\t\t\tmfp.st.showCloseBtn = false;\n\t\t\tmfp.st.enableEscapeKey = false;\n\t\t}\n\t\t\n\n\t\t// Building markup\n\t\t// main containers are created only once\n\t\tif(!mfp.bgOverlay) {\n\n\t\t\t// Dark overlay\n\t\t\tmfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() {\n\t\t\t\tmfp.close();\n\t\t\t});\n\n\t\t\tmfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) {\n\t\t\t\tif(mfp._checkIfClose(e.target)) {\n\t\t\t\t\tmfp.close();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tmfp.container = _getEl('container', mfp.wrap);\n\t\t}\n\n\t\tmfp.contentContainer = _getEl('content');\n\t\tif(mfp.st.preloader) {\n\t\t\tmfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading);\n\t\t}\n\n\n\t\t// Initializing modules\n\t\tvar modules = $.magnificPopup.modules;\n\t\tfor(i = 0; i < modules.length; i++) {\n\t\t\tvar n = modules[i];\n\t\t\tn = n.charAt(0).toUpperCase() + n.slice(1);\n\t\t\tmfp['init'+n].call(mfp);\n\t\t}\n\t\t_mfpTrigger('BeforeOpen');\n\n\n\t\tif(mfp.st.showCloseBtn) {\n\t\t\t// Close button\n\t\t\tif(!mfp.st.closeBtnInside) {\n\t\t\t\tmfp.wrap.append( _getCloseBtn() );\n\t\t\t} else {\n\t\t\t\t_mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) {\n\t\t\t\t\tvalues.close_replaceWith = _getCloseBtn(item.type);\n\t\t\t\t});\n\t\t\t\t_wrapClasses += ' mfp-close-btn-in';\n\t\t\t}\n\t\t}\n\n\t\tif(mfp.st.alignTop) {\n\t\t\t_wrapClasses += ' mfp-align-top';\n\t\t}\n\n\t\n\n\t\tif(mfp.fixedContentPos) {\n\t\t\tmfp.wrap.css({\n\t\t\t\toverflow: mfp.st.overflowY,\n\t\t\t\toverflowX: 'hidden',\n\t\t\t\toverflowY: mfp.st.overflowY\n\t\t\t});\n\t\t} else {\n\t\t\tmfp.wrap.css({ \n\t\t\t\ttop: _window.scrollTop(),\n\t\t\t\tposition: 'absolute'\n\t\t\t});\n\t\t}\n\t\tif( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) {\n\t\t\tmfp.bgOverlay.css({\n\t\t\t\theight: _document.height(),\n\t\t\t\tposition: 'absolute'\n\t\t\t});\n\t\t}\n\n\t\t\n\n\t\tif(mfp.st.enableEscapeKey) {\n\t\t\t// Close on ESC key\n\t\t\t_document.on('keyup' + EVENT_NS, function(e) {\n\t\t\t\tif(e.keyCode === 27) {\n\t\t\t\t\tmfp.close();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t_window.on('resize' + EVENT_NS, function() {\n\t\t\tmfp.updateSize();\n\t\t});\n\n\n\t\tif(!mfp.st.closeOnContentClick) {\n\t\t\t_wrapClasses += ' mfp-auto-cursor';\n\t\t}\n\t\t\n\t\tif(_wrapClasses)\n\t\t\tmfp.wrap.addClass(_wrapClasses);\n\n\n\t\t// this triggers recalculation of layout, so we get it once to not to trigger twice\n\t\tvar windowHeight = mfp.wH = _window.height();\n\n\t\t\n\t\tvar windowStyles = {};\n\n\t\tif( mfp.fixedContentPos ) {\n            if(mfp._hasScrollBar(windowHeight)){\n                var s = mfp._getScrollbarSize();\n                if(s) {\n                    windowStyles.marginRight = s;\n                }\n            }\n        }\n\n\t\tif(mfp.fixedContentPos) {\n\t\t\tif(!mfp.isIE7) {\n\t\t\t\twindowStyles.overflow = 'hidden';\n\t\t\t} else {\n\t\t\t\t// ie7 double-scroll bug\n\t\t\t\t$('body, html').css('overflow', 'hidden');\n\t\t\t}\n\t\t}\n\n\t\t\n\t\t\n\t\tvar classesToadd = mfp.st.mainClass;\n\t\tif(mfp.isIE7) {\n\t\t\tclassesToadd += ' mfp-ie7';\n\t\t}\n\t\tif(classesToadd) {\n\t\t\tmfp._addClassToMFP( classesToadd );\n\t\t}\n\n\t\t// add content\n\t\tmfp.updateItemHTML();\n\n\t\t_mfpTrigger('BuildControls');\n\n\t\t// remove scrollbar, add margin e.t.c\n\t\t$('html').css(windowStyles);\n\t\t\n\t\t// add everything to DOM\n\t\tmfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || _body );\n\n\t\t// Save last focused element\n\t\tmfp._lastFocusedEl = document.activeElement;\n\t\t\n\t\t// Wait for next cycle to allow CSS transition\n\t\tsetTimeout(function() {\n\t\t\t\n\t\t\tif(mfp.content) {\n\t\t\t\tmfp._addClassToMFP(READY_CLASS);\n\t\t\t\tmfp._setFocus();\n\t\t\t} else {\n\t\t\t\t// if content is not defined (not loaded e.t.c) we add class only for BG\n\t\t\t\tmfp.bgOverlay.addClass(READY_CLASS);\n\t\t\t}\n\t\t\t\n\t\t\t// Trap the focus in popup\n\t\t\t_document.on('focusin' + EVENT_NS, mfp._onFocusIn);\n\n\t\t}, 16);\n\n\t\tmfp.isOpen = true;\n\t\tmfp.updateSize(windowHeight);\n\t\t_mfpTrigger(OPEN_EVENT);\n\n\t\treturn data;\n\t},\n\n\t/**\n\t * Closes the popup\n\t */\n\tclose: function() {\n\t\tif(!mfp.isOpen) return;\n\t\t_mfpTrigger(BEFORE_CLOSE_EVENT);\n\n\t\tmfp.isOpen = false;\n\t\t// for CSS3 animation\n\t\tif(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition )  {\n\t\t\tmfp._addClassToMFP(REMOVING_CLASS);\n\t\t\tsetTimeout(function() {\n\t\t\t\tmfp._close();\n\t\t\t}, mfp.st.removalDelay);\n\t\t} else {\n\t\t\tmfp._close();\n\t\t}\n\t},\n\n\t/**\n\t * Helper for close() function\n\t */\n\t_close: function() {\n\t\t_mfpTrigger(CLOSE_EVENT);\n\n\t\tvar classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' ';\n\n\t\tmfp.bgOverlay.detach();\n\t\tmfp.wrap.detach();\n\t\tmfp.container.empty();\n\n\t\tif(mfp.st.mainClass) {\n\t\t\tclassesToRemove += mfp.st.mainClass + ' ';\n\t\t}\n\n\t\tmfp._removeClassFromMFP(classesToRemove);\n\n\t\tif(mfp.fixedContentPos) {\n\t\t\tvar windowStyles = {marginRight: ''};\n\t\t\tif(mfp.isIE7) {\n\t\t\t\t$('body, html').css('overflow', '');\n\t\t\t} else {\n\t\t\t\twindowStyles.overflow = '';\n\t\t\t}\n\t\t\t$('html').css(windowStyles);\n\t\t}\n\t\t\n\t\t_document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS);\n\t\tmfp.ev.off(EVENT_NS);\n\n\t\t// clean up DOM elements that aren't removed\n\t\tmfp.wrap.attr('class', 'mfp-wrap').removeAttr('style');\n\t\tmfp.bgOverlay.attr('class', 'mfp-bg');\n\t\tmfp.container.attr('class', 'mfp-container');\n\n\t\t// remove close button from target element\n\t\tif(mfp.st.showCloseBtn &&\n\t\t(!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) {\n\t\t\tif(mfp.currTemplate.closeBtn)\n\t\t\t\tmfp.currTemplate.closeBtn.detach();\n\t\t}\n\n\n\t\tif(mfp._lastFocusedEl) {\n\t\t\t$(mfp._lastFocusedEl).focus(); // put tab focus back\n\t\t}\n\t\tmfp.currItem = null;\t\n\t\tmfp.content = null;\n\t\tmfp.currTemplate = null;\n\t\tmfp.prevHeight = 0;\n\n\t\t_mfpTrigger(AFTER_CLOSE_EVENT);\n\t},\n\t\n\tupdateSize: function(winHeight) {\n\n\t\tif(mfp.isIOS) {\n\t\t\t// fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2\n\t\t\tvar zoomLevel = document.documentElement.clientWidth / window.innerWidth;\n\t\t\tvar height = window.innerHeight * zoomLevel;\n\t\t\tmfp.wrap.css('height', height);\n\t\t\tmfp.wH = height;\n\t\t} else {\n\t\t\tmfp.wH = winHeight || _window.height();\n\t\t}\n\t\t// Fixes #84: popup incorrectly positioned with position:relative on body\n\t\tif(!mfp.fixedContentPos) {\n\t\t\tmfp.wrap.css('height', mfp.wH);\n\t\t}\n\n\t\t_mfpTrigger('Resize');\n\n\t},\n\n\t/**\n\t * Set content of popup based on current index\n\t */\n\tupdateItemHTML: function() {\n\t\tvar item = mfp.items[mfp.index];\n\n\t\t// Detach and perform modifications\n\t\tmfp.contentContainer.detach();\n\n\t\tif(mfp.content)\n\t\t\tmfp.content.detach();\n\n\t\tif(!item.parsed) {\n\t\t\titem = mfp.parseEl( mfp.index );\n\t\t}\n\n\t\tvar type = item.type;\t\n\n\t\t_mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]);\n\t\t// BeforeChange event works like so:\n\t\t// _mfpOn('BeforeChange', function(e, prevType, newType) { });\n\t\t\n\t\tmfp.currItem = item;\n\n\t\t\n\n\t\t\n\n\t\tif(!mfp.currTemplate[type]) {\n\t\t\tvar markup = mfp.st[type] ? mfp.st[type].markup : false;\n\n\t\t\t// allows to modify markup\n\t\t\t_mfpTrigger('FirstMarkupParse', markup);\n\n\t\t\tif(markup) {\n\t\t\t\tmfp.currTemplate[type] = $(markup);\n\t\t\t} else {\n\t\t\t\t// if there is no markup found we just define that template is parsed\n\t\t\t\tmfp.currTemplate[type] = true;\n\t\t\t}\n\t\t}\n\n\t\tif(_prevContentType && _prevContentType !== item.type) {\n\t\t\tmfp.container.removeClass('mfp-'+_prevContentType+'-holder');\n\t\t}\n\t\t\n\t\tvar newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]);\n\t\tmfp.appendContent(newContent, type);\n\n\t\titem.preloaded = true;\n\n\t\t_mfpTrigger(CHANGE_EVENT, item);\n\t\t_prevContentType = item.type;\n\t\t\n\t\t// Append container back after its content changed\n\t\tmfp.container.prepend(mfp.contentContainer);\n\n\t\t_mfpTrigger('AfterChange');\n\t},\n\n\n\t/**\n\t * Set HTML content of popup\n\t */\n\tappendContent: function(newContent, type) {\n\t\tmfp.content = newContent;\n\t\t\n\t\tif(newContent) {\n\t\t\tif(mfp.st.showCloseBtn && mfp.st.closeBtnInside &&\n\t\t\t\tmfp.currTemplate[type] === true) {\n\t\t\t\t// if there is no markup, we just append close button element inside\n\t\t\t\tif(!mfp.content.find('.mfp-close').length) {\n\t\t\t\t\tmfp.content.append(_getCloseBtn());\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tmfp.content = newContent;\n\t\t\t}\n\t\t} else {\n\t\t\tmfp.content = '';\n\t\t}\n\n\t\t_mfpTrigger(BEFORE_APPEND_EVENT);\n\t\tmfp.container.addClass('mfp-'+type+'-holder');\n\n\t\tmfp.contentContainer.append(mfp.content);\n\t},\n\n\n\n\t\n\t/**\n\t * Creates Magnific Popup data object based on given data\n\t * @param  {int} index Index of item to parse\n\t */\n\tparseEl: function(index) {\n\t\tvar item = mfp.items[index],\n\t\t\ttype;\n\n\t\tif(item.tagName) {\n\t\t\titem = { el: $(item) };\n\t\t} else {\n\t\t\ttype = item.type;\n\t\t\titem = { data: item, src: item.src };\n\t\t}\n\n\t\tif(item.el) {\n\t\t\tvar types = mfp.types;\n\n\t\t\t// check for 'mfp-TYPE' class\n\t\t\tfor(var i = 0; i < types.length; i++) {\n\t\t\t\tif( item.el.hasClass('mfp-'+types[i]) ) {\n\t\t\t\t\ttype = types[i];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\titem.src = item.el.attr('data-mfp-src');\n\t\t\tif(!item.src) {\n\t\t\t\titem.src = item.el.attr('href');\n\t\t\t}\n\t\t}\n\n\t\titem.type = type || mfp.st.type || 'inline';\n\t\titem.index = index;\n\t\titem.parsed = true;\n\t\tmfp.items[index] = item;\n\t\t_mfpTrigger('ElementParse', item);\n\n\t\treturn mfp.items[index];\n\t},\n\n\n\t/**\n\t * Initializes single popup or a group of popups\n\t */\n\taddGroup: function(el, options) {\n\t\tvar eHandler = function(e) {\n\t\t\te.mfpEl = this;\n\t\t\tmfp._openClick(e, el, options);\n\t\t};\n\n\t\tif(!options) {\n\t\t\toptions = {};\n\t\t} \n\n\t\tvar eName = 'click.magnificPopup';\n\t\toptions.mainEl = el;\n\t\t\n\t\tif(options.items) {\n\t\t\toptions.isObj = true;\n\t\t\tel.off(eName).on(eName, eHandler);\n\t\t} else {\n\t\t\toptions.isObj = false;\n\t\t\tif(options.delegate) {\n\t\t\t\tel.off(eName).on(eName, options.delegate , eHandler);\n\t\t\t} else {\n\t\t\t\toptions.items = el;\n\t\t\t\tel.off(eName).on(eName, eHandler);\n\t\t\t}\n\t\t}\n\t},\n\t_openClick: function(e, el, options) {\n\t\tvar midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick;\n\n\n\t\tif(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn;\n\n\t\tif(disableOn) {\n\t\t\tif($.isFunction(disableOn)) {\n\t\t\t\tif( !disableOn.call(mfp) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} else { // else it's number\n\t\t\t\tif( _window.width() < disableOn ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\tif(e.type) {\n\t\t\te.preventDefault();\n\n\t\t\t// This will prevent popup from closing if element is inside and popup is already opened\n\t\t\tif(mfp.isOpen) {\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t}\n\t\t\t\n\n\t\toptions.el = $(e.mfpEl);\n\t\tif(options.delegate) {\n\t\t\toptions.items = el.find(options.delegate);\n\t\t}\n\t\tmfp.open(options);\n\t},\n\n\n\t/**\n\t * Updates text on preloader\n\t */\n\tupdateStatus: function(status, text) {\n\n\t\tif(mfp.preloader) {\n\t\t\tif(_prevStatus !== status) {\n\t\t\t\tmfp.container.removeClass('mfp-s-'+_prevStatus);\n\t\t\t}\n\n\t\t\tif(!text && status === 'loading') {\n\t\t\t\ttext = mfp.st.tLoading;\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tstatus: status,\n\t\t\t\ttext: text\n\t\t\t};\n\t\t\t// allows to modify status\n\t\t\t_mfpTrigger('UpdateStatus', data);\n\n\t\t\tstatus = data.status;\n\t\t\ttext = data.text;\n\n\t\t\tmfp.preloader.html(text);\n\n\t\t\tmfp.preloader.find('a').on('click', function(e) {\n\t\t\t\te.stopImmediatePropagation();\n\t\t\t});\n\n\t\t\tmfp.container.addClass('mfp-s-'+status);\n\t\t\t_prevStatus = status;\n\t\t}\n\t},\n\n\n\t/*\n\t\t\"Private\" helpers that aren't private at all\n\t */\n\t// Check to close popup or not\n\t// \"target\" is an element that was clicked\n\t_checkIfClose: function(target) {\n\n\t\tif($(target).hasClass(PREVENT_CLOSE_CLASS)) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar closeOnContent = mfp.st.closeOnContentClick;\n\t\tvar closeOnBg = mfp.st.closeOnBgClick;\n\n\t\tif(closeOnContent && closeOnBg) {\n\t\t\treturn true;\n\t\t} else {\n\n\t\t\t// We close the popup if click is on close button or on preloader. Or if there is no content.\n\t\t\tif(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// if click is outside the content\n\t\t\tif(  (target !== mfp.content[0] && !$.contains(mfp.content[0], target))  ) {\n\t\t\t\tif(closeOnBg) {\n\t\t\t\t\t// last check, if the clicked element is in DOM, (in case it's removed onclick)\n\t\t\t\t\tif( $.contains(document, target) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if(closeOnContent) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t}\n\t\treturn false;\n\t},\n\t_addClassToMFP: function(cName) {\n\t\tmfp.bgOverlay.addClass(cName);\n\t\tmfp.wrap.addClass(cName);\n\t},\n\t_removeClassFromMFP: function(cName) {\n\t\tthis.bgOverlay.removeClass(cName);\n\t\tmfp.wrap.removeClass(cName);\n\t},\n\t_hasScrollBar: function(winHeight) {\n\t\treturn (  (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) );\n\t},\n\t_setFocus: function() {\n\t\t(mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus();\n\t},\n\t_onFocusIn: function(e) {\n\t\tif( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) {\n\t\t\tmfp._setFocus();\n\t\t\treturn false;\n\t\t}\n\t},\n\t_parseMarkup: function(template, values, item) {\n\t\tvar arr;\n\t\tif(item.data) {\n\t\t\tvalues = $.extend(item.data, values);\n\t\t}\n\t\t_mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] );\n\n\t\t$.each(values, function(key, value) {\n\t\t\tif(value === undefined || value === false) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tarr = key.split('_');\n\t\t\tif(arr.length > 1) {\n\t\t\t\tvar el = template.find(EVENT_NS + '-'+arr[0]);\n\n\t\t\t\tif(el.length > 0) {\n\t\t\t\t\tvar attr = arr[1];\n\t\t\t\t\tif(attr === 'replaceWith') {\n\t\t\t\t\t\tif(el[0] !== value[0]) {\n\t\t\t\t\t\t\tel.replaceWith(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if(attr === 'img') {\n\t\t\t\t\t\tif(el.is('img')) {\n\t\t\t\t\t\t\tel.attr('src', value);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tel.replaceWith( '<img src=\"'+value+'\" class=\"' + el.attr('class') + '\" />' );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tel.attr(arr[1], value);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\ttemplate.find(EVENT_NS + '-'+key).html(value);\n\t\t\t}\n\t\t});\n\t},\n\n\t_getScrollbarSize: function() {\n\t\t// thx David\n\t\tif(mfp.scrollbarSize === undefined) {\n\t\t\tvar scrollDiv = document.createElement(\"div\");\n\t\t\tscrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';\n\t\t\tdocument.body.appendChild(scrollDiv);\n\t\t\tmfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;\n\t\t\tdocument.body.removeChild(scrollDiv);\n\t\t}\n\t\treturn mfp.scrollbarSize;\n\t}\n\n}; /* MagnificPopup core prototype end */\n\n\n\n\n/**\n * Public static functions\n */\n$.magnificPopup = {\n\tinstance: null,\n\tproto: MagnificPopup.prototype,\n\tmodules: [],\n\n\topen: function(options, index) {\n\t\t_checkInstance();\t\n\n\t\tif(!options) {\n\t\t\toptions = {};\n\t\t} else {\n\t\t\toptions = $.extend(true, {}, options);\n\t\t}\n\t\t\t\n\n\t\toptions.isObj = true;\n\t\toptions.index = index || 0;\n\t\treturn this.instance.open(options);\n\t},\n\n\tclose: function() {\n\t\treturn $.magnificPopup.instance && $.magnificPopup.instance.close();\n\t},\n\n\tregisterModule: function(name, module) {\n\t\tif(module.options) {\n\t\t\t$.magnificPopup.defaults[name] = module.options;\n\t\t}\n\t\t$.extend(this.proto, module.proto);\t\t\t\n\t\tthis.modules.push(name);\n\t},\n\n\tdefaults: {   \n\n\t\t// Info about options is in docs:\n\t\t// http://dimsemenov.com/plugins/magnific-popup/documentation.html#options\n\t\t\n\t\tdisableOn: 0,\t\n\n\t\tkey: null,\n\n\t\tmidClick: false,\n\n\t\tmainClass: '',\n\n\t\tpreloader: true,\n\n\t\tfocus: '', // CSS selector of input to focus after popup is opened\n\t\t\n\t\tcloseOnContentClick: false,\n\n\t\tcloseOnBgClick: true,\n\n\t\tcloseBtnInside: true, \n\n\t\tshowCloseBtn: true,\n\n\t\tenableEscapeKey: true,\n\n\t\tmodal: false,\n\n\t\talignTop: false,\n\t\n\t\tremovalDelay: 0,\n\n\t\tprependTo: null,\n\t\t\n\t\tfixedContentPos: 'auto', \n\t\n\t\tfixedBgPos: 'auto',\n\n\t\toverflowY: 'auto',\n\n\t\tcloseMarkup: '<button title=\"%title%\" type=\"button\" class=\"mfp-close\">&times;</button>',\n\n\t\ttClose: 'Close (Esc)',\n\n\t\ttLoading: 'Loading...'\n\n\t}\n};\n\n\n\n$.fn.magnificPopup = function(options) {\n\t_checkInstance();\n\n\tvar jqEl = $(this);\n\n\t// We call some API method of first param is a string\n\tif (typeof options === \"string\" ) {\n\n\t\tif(options === 'open') {\n\t\t\tvar items,\n\t\t\t\titemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup,\n\t\t\t\tindex = parseInt(arguments[1], 10) || 0;\n\n\t\t\tif(itemOpts.items) {\n\t\t\t\titems = itemOpts.items[index];\n\t\t\t} else {\n\t\t\t\titems = jqEl;\n\t\t\t\tif(itemOpts.delegate) {\n\t\t\t\t\titems = items.find(itemOpts.delegate);\n\t\t\t\t}\n\t\t\t\titems = items.eq( index );\n\t\t\t}\n\t\t\tmfp._openClick({mfpEl:items}, jqEl, itemOpts);\n\t\t} else {\n\t\t\tif(mfp.isOpen)\n\t\t\t\tmfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1));\n\t\t}\n\n\t} else {\n\t\t// clone options obj\n\t\toptions = $.extend(true, {}, options);\n\t\t\n\t\t/*\n\t\t * As Zepto doesn't support .data() method for objects \n\t\t * and it works only in normal browsers\n\t\t * we assign \"options\" object directly to the DOM element. FTW!\n\t\t */\n\t\tif(_isJQ) {\n\t\t\tjqEl.data('magnificPopup', options);\n\t\t} else {\n\t\t\tjqEl[0].magnificPopup = options;\n\t\t}\n\n\t\tmfp.addGroup(jqEl, options);\n\n\t}\n\treturn jqEl;\n};\n\n\n//Quick benchmark\n/*\nvar start = performance.now(),\n\ti,\n\trounds = 1000;\n\nfor(i = 0; i < rounds; i++) {\n\n}\nconsole.log('Test #1:', performance.now() - start);\n\nstart = performance.now();\nfor(i = 0; i < rounds; i++) {\n\n}\nconsole.log('Test #2:', performance.now() - start);\n*/\n"
  },
  {
    "path": "static/assets/plugins/magnific-popup/src/js/fastclick.js",
    "content": "/**\n * FastClick event implementation. (removes 300ms delay on touch devices)\n * Based on https://developers.google.com/mobile/articles/fast_buttons\n *\n * You may use it outside the Magnific Popup by calling just:\n *\n * $('.your-el').mfpFastClick(function() {\n *     console.log('Clicked!');\n * });\n *\n * To unbind:\n * $('.your-el').destroyMfpFastClick();\n * \n * \n * Note that it's a very basic and simple implementation, it blocks ghost click on the same element where it was bound.\n * If you need something more advanced, use plugin by FT Labs https://github.com/ftlabs/fastclick\n * \n */\n\n(function() {\n\tvar ghostClickDelay = 1000,\n\t\tsupportsTouch = 'ontouchstart' in window,\n\t\tunbindTouchMove = function() {\n\t\t\t_window.off('touchmove'+ns+' touchend'+ns);\n\t\t},\n\t\teName = 'mfpFastClick',\n\t\tns = '.'+eName;\n\n\n\t// As Zepto.js doesn't have an easy way to add custom events (like jQuery), so we implement it in this way\n\t$.fn.mfpFastClick = function(callback) {\n\n\t\treturn $(this).each(function() {\n\n\t\t\tvar elem = $(this),\n\t\t\t\tlock;\n\n\t\t\tif( supportsTouch ) {\n\n\t\t\t\tvar timeout,\n\t\t\t\t\tstartX,\n\t\t\t\t\tstartY,\n\t\t\t\t\tpointerMoved,\n\t\t\t\t\tpoint,\n\t\t\t\t\tnumPointers;\n\n\t\t\t\telem.on('touchstart' + ns, function(e) {\n\t\t\t\t\tpointerMoved = false;\n\t\t\t\t\tnumPointers = 1;\n\n\t\t\t\t\tpoint = e.originalEvent ? e.originalEvent.touches[0] : e.touches[0];\n\t\t\t\t\tstartX = point.clientX;\n\t\t\t\t\tstartY = point.clientY;\n\n\t\t\t\t\t_window.on('touchmove'+ns, function(e) {\n\t\t\t\t\t\tpoint = e.originalEvent ? e.originalEvent.touches : e.touches;\n\t\t\t\t\t\tnumPointers = point.length;\n\t\t\t\t\t\tpoint = point[0];\n\t\t\t\t\t\tif (Math.abs(point.clientX - startX) > 10 ||\n\t\t\t\t\t\t\tMath.abs(point.clientY - startY) > 10) {\n\t\t\t\t\t\t\tpointerMoved = true;\n\t\t\t\t\t\t\tunbindTouchMove();\n\t\t\t\t\t\t}\n\t\t\t\t\t}).on('touchend'+ns, function(e) {\n\t\t\t\t\t\tunbindTouchMove();\n\t\t\t\t\t\tif(pointerMoved || numPointers > 1) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlock = true;\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\t\ttimeout = setTimeout(function() {\n\t\t\t\t\t\t\tlock = false;\n\t\t\t\t\t\t}, ghostClickDelay);\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t}\n\n\t\t\telem.on('click' + ns, function() {\n\t\t\t\tif(!lock) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t};\n\n\t$.fn.destroyMfpFastClick = function() {\n\t\t$(this).off('touchstart' + ns + ' click' + ns);\n\t\tif(supportsTouch) _window.off('touchmove'+ns+' touchend'+ns);\n\t};\n})();"
  },
  {
    "path": "static/assets/plugins/magnific-popup/src/js/gallery.js",
    "content": "/**\n * Get looped index depending on number of slides\n */\nvar _getLoopedId = function(index) {\n\t\tvar numSlides = mfp.items.length;\n\t\tif(index > numSlides - 1) {\n\t\t\treturn index - numSlides;\n\t\t} else  if(index < 0) {\n\t\t\treturn numSlides + index;\n\t\t}\n\t\treturn index;\n\t},\n\t_replaceCurrTotal = function(text, curr, total) {\n\t\treturn text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total);\n\t};\n\n$.magnificPopup.registerModule('gallery', {\n\n\toptions: {\n\t\tenabled: false,\n\t\tarrowMarkup: '<button title=\"%title%\" type=\"button\" class=\"mfp-arrow mfp-arrow-%dir%\"></button>',\n\t\tpreload: [0,2],\n\t\tnavigateByImgClick: true,\n\t\tarrows: true,\n\n\t\ttPrev: 'Previous (Left arrow key)',\n\t\ttNext: 'Next (Right arrow key)',\n\t\ttCounter: '%curr% of %total%'\n\t},\n\n\tproto: {\n\t\tinitGallery: function() {\n\n\t\t\tvar gSt = mfp.st.gallery,\n\t\t\t\tns = '.mfp-gallery',\n\t\t\t\tsupportsFastClick = Boolean($.fn.mfpFastClick);\n\n\t\t\tmfp.direction = true; // true - next, false - prev\n\t\t\t\n\t\t\tif(!gSt || !gSt.enabled ) return false;\n\n\t\t\t_wrapClasses += ' mfp-gallery';\n\n\t\t\t_mfpOn(OPEN_EVENT+ns, function() {\n\n\t\t\t\tif(gSt.navigateByImgClick) {\n\t\t\t\t\tmfp.wrap.on('click'+ns, '.mfp-img', function() {\n\t\t\t\t\t\tif(mfp.items.length > 1) {\n\t\t\t\t\t\t\tmfp.next();\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t_document.on('keydown'+ns, function(e) {\n\t\t\t\t\tif (e.keyCode === 37) {\n\t\t\t\t\t\tmfp.prev();\n\t\t\t\t\t} else if (e.keyCode === 39) {\n\t\t\t\t\t\tmfp.next();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t_mfpOn('UpdateStatus'+ns, function(e, data) {\n\t\t\t\tif(data.text) {\n\t\t\t\t\tdata.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t_mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) {\n\t\t\t\tvar l = mfp.items.length;\n\t\t\t\tvalues.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : '';\n\t\t\t});\n\n\t\t\t_mfpOn('BuildControls' + ns, function() {\n\t\t\t\tif(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) {\n\t\t\t\t\tvar markup = gSt.arrowMarkup,\n\t\t\t\t\t\tarrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS),\t\t\t\n\t\t\t\t\t\tarrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS);\n\n\t\t\t\t\tvar eName = supportsFastClick ? 'mfpFastClick' : 'click';\n\t\t\t\t\tarrowLeft[eName](function() {\n\t\t\t\t\t\tmfp.prev();\n\t\t\t\t\t});\t\t\t\n\t\t\t\t\tarrowRight[eName](function() {\n\t\t\t\t\t\tmfp.next();\n\t\t\t\t\t});\t\n\n\t\t\t\t\t// Polyfill for :before and :after (adds elements with classes mfp-a and mfp-b)\n\t\t\t\t\tif(mfp.isIE7) {\n\t\t\t\t\t\t_getEl('b', arrowLeft[0], false, true);\n\t\t\t\t\t\t_getEl('a', arrowLeft[0], false, true);\n\t\t\t\t\t\t_getEl('b', arrowRight[0], false, true);\n\t\t\t\t\t\t_getEl('a', arrowRight[0], false, true);\n\t\t\t\t\t}\n\n\t\t\t\t\tmfp.container.append(arrowLeft.add(arrowRight));\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t_mfpOn(CHANGE_EVENT+ns, function() {\n\t\t\t\tif(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout);\n\n\t\t\t\tmfp._preloadTimeout = setTimeout(function() {\n\t\t\t\t\tmfp.preloadNearbyImages();\n\t\t\t\t\tmfp._preloadTimeout = null;\n\t\t\t\t}, 16);\t\t\n\t\t\t});\n\n\n\t\t\t_mfpOn(CLOSE_EVENT+ns, function() {\n\t\t\t\t_document.off(ns);\n\t\t\t\tmfp.wrap.off('click'+ns);\n\t\t\t\n\t\t\t\tif(mfp.arrowLeft && supportsFastClick) {\n\t\t\t\t\tmfp.arrowLeft.add(mfp.arrowRight).destroyMfpFastClick();\n\t\t\t\t}\n\t\t\t\tmfp.arrowRight = mfp.arrowLeft = null;\n\t\t\t});\n\n\t\t}, \n\t\tnext: function() {\n\t\t\tmfp.direction = true;\n\t\t\tmfp.index = _getLoopedId(mfp.index + 1);\n\t\t\tmfp.updateItemHTML();\n\t\t},\n\t\tprev: function() {\n\t\t\tmfp.direction = false;\n\t\t\tmfp.index = _getLoopedId(mfp.index - 1);\n\t\t\tmfp.updateItemHTML();\n\t\t},\n\t\tgoTo: function(newIndex) {\n\t\t\tmfp.direction = (newIndex >= mfp.index);\n\t\t\tmfp.index = newIndex;\n\t\t\tmfp.updateItemHTML();\n\t\t},\n\t\tpreloadNearbyImages: function() {\n\t\t\tvar p = mfp.st.gallery.preload,\n\t\t\t\tpreloadBefore = Math.min(p[0], mfp.items.length),\n\t\t\t\tpreloadAfter = Math.min(p[1], mfp.items.length),\n\t\t\t\ti;\n\n\t\t\tfor(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) {\n\t\t\t\tmfp._preloadItem(mfp.index+i);\n\t\t\t}\n\t\t\tfor(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) {\n\t\t\t\tmfp._preloadItem(mfp.index-i);\n\t\t\t}\n\t\t},\n\t\t_preloadItem: function(index) {\n\t\t\tindex = _getLoopedId(index);\n\n\t\t\tif(mfp.items[index].preloaded) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar item = mfp.items[index];\n\t\t\tif(!item.parsed) {\n\t\t\t\titem = mfp.parseEl( index );\n\t\t\t}\n\n\t\t\t_mfpTrigger('LazyLoad', item);\n\n\t\t\tif(item.type === 'image') {\n\t\t\t\titem.img = $('<img class=\"mfp-img\" />').on('load.mfploader', function() {\n\t\t\t\t\titem.hasSize = true;\n\t\t\t\t}).on('error.mfploader', function() {\n\t\t\t\t\titem.hasSize = true;\n\t\t\t\t\titem.loadError = true;\n\t\t\t\t\t_mfpTrigger('LazyLoadError', item);\n\t\t\t\t}).attr('src', item.src);\n\t\t\t}\n\n\n\t\t\titem.preloaded = true;\n\t\t}\n\t}\n});\n\n/*\nTouch Support that might be implemented some day\n\naddSwipeGesture: function() {\n\tvar startX,\n\t\tmoved,\n\t\tmultipleTouches;\n\n\t\treturn;\n\n\tvar namespace = '.mfp',\n\t\taddEventNames = function(pref, down, move, up, cancel) {\n\t\t\tmfp._tStart = pref + down + namespace;\n\t\t\tmfp._tMove = pref + move + namespace;\n\t\t\tmfp._tEnd = pref + up + namespace;\n\t\t\tmfp._tCancel = pref + cancel + namespace;\n\t\t};\n\n\tif(window.navigator.msPointerEnabled) {\n\t\taddEventNames('MSPointer', 'Down', 'Move', 'Up', 'Cancel');\n\t} else if('ontouchstart' in window) {\n\t\taddEventNames('touch', 'start', 'move', 'end', 'cancel');\n\t} else {\n\t\treturn;\n\t}\n\t_window.on(mfp._tStart, function(e) {\n\t\tvar oE = e.originalEvent;\n\t\tmultipleTouches = moved = false;\n\t\tstartX = oE.pageX || oE.changedTouches[0].pageX;\n\t}).on(mfp._tMove, function(e) {\n\t\tif(e.originalEvent.touches.length > 1) {\n\t\t\tmultipleTouches = e.originalEvent.touches.length;\n\t\t} else {\n\t\t\t//e.preventDefault();\n\t\t\tmoved = true;\n\t\t}\n\t}).on(mfp._tEnd + ' ' + mfp._tCancel, function(e) {\n\t\tif(moved && !multipleTouches) {\n\t\t\tvar oE = e.originalEvent,\n\t\t\t\tdiff = startX - (oE.pageX || oE.changedTouches[0].pageX);\n\n\t\t\tif(diff > 20) {\n\t\t\t\tmfp.next();\n\t\t\t} else if(diff < -20) {\n\t\t\t\tmfp.prev();\n\t\t\t}\n\t\t}\n\t});\n},\n*/\n"
  },
  {
    "path": "static/assets/plugins/magnific-popup/src/js/iframe.js",
    "content": "\nvar IFRAME_NS = 'iframe',\n\t_emptyPage = '//about:blank',\n\t\n\t_fixIframeBugs = function(isShowing) {\n\t\tif(mfp.currTemplate[IFRAME_NS]) {\n\t\t\tvar el = mfp.currTemplate[IFRAME_NS].find('iframe');\n\t\t\tif(el.length) { \n\t\t\t\t// reset src after the popup is closed to avoid \"video keeps playing after popup is closed\" bug\n\t\t\t\tif(!isShowing) {\n\t\t\t\t\tel[0].src = _emptyPage;\n\t\t\t\t}\n\n\t\t\t\t// IE8 black screen bug fix\n\t\t\t\tif(mfp.isIE8) {\n\t\t\t\t\tel.css('display', isShowing ? 'block' : 'none');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n$.magnificPopup.registerModule(IFRAME_NS, {\n\n\toptions: {\n\t\tmarkup: '<div class=\"mfp-iframe-scaler\">'+\n\t\t\t\t\t'<div class=\"mfp-close\"></div>'+\n\t\t\t\t\t'<iframe class=\"mfp-iframe\" src=\"//about:blank\" frameborder=\"0\" allowfullscreen></iframe>'+\n\t\t\t\t'</div>',\n\n\t\tsrcAction: 'iframe_src',\n\n\t\t// we don't care and support only one default type of URL by default\n\t\tpatterns: {\n\t\t\tyoutube: {\n\t\t\t\tindex: 'youtube.com', \n\t\t\t\tid: 'v=', \n\t\t\t\tsrc: '//www.youtube.com/embed/%id%?autoplay=1'\n\t\t\t},\n\t\t\tvimeo: {\n\t\t\t\tindex: 'vimeo.com/',\n\t\t\t\tid: '/',\n\t\t\t\tsrc: '//player.vimeo.com/video/%id%?autoplay=1'\n\t\t\t},\n\t\t\tgmaps: {\n\t\t\t\tindex: '//maps.google.',\n\t\t\t\tsrc: '%id%&output=embed'\n\t\t\t}\n\t\t}\n\t},\n\n\tproto: {\n\t\tinitIframe: function() {\n\t\t\tmfp.types.push(IFRAME_NS);\n\n\t\t\t_mfpOn('BeforeChange', function(e, prevType, newType) {\n\t\t\t\tif(prevType !== newType) {\n\t\t\t\t\tif(prevType === IFRAME_NS) {\n\t\t\t\t\t\t_fixIframeBugs(); // iframe if removed\n\t\t\t\t\t} else if(newType === IFRAME_NS) {\n\t\t\t\t\t\t_fixIframeBugs(true); // iframe is showing\n\t\t\t\t\t} \n\t\t\t\t}// else {\n\t\t\t\t\t// iframe source is switched, don't do anything\n\t\t\t\t//}\n\t\t\t});\n\n\t\t\t_mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() {\n\t\t\t\t_fixIframeBugs();\n\t\t\t});\n\t\t},\n\n\t\tgetIframe: function(item, template) {\n\t\t\tvar embedSrc = item.src;\n\t\t\tvar iframeSt = mfp.st.iframe;\n\t\t\t\t\n\t\t\t$.each(iframeSt.patterns, function() {\n\t\t\t\tif(embedSrc.indexOf( this.index ) > -1) {\n\t\t\t\t\tif(this.id) {\n\t\t\t\t\t\tif(typeof this.id === 'string') {\n\t\t\t\t\t\t\tembedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tembedSrc = this.id.call( this, embedSrc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tembedSrc = this.src.replace('%id%', embedSrc );\n\t\t\t\t\treturn false; // break;\n\t\t\t\t}\n\t\t\t});\n\t\t\t\n\t\t\tvar dataObj = {};\n\t\t\tif(iframeSt.srcAction) {\n\t\t\t\tdataObj[iframeSt.srcAction] = embedSrc;\n\t\t\t}\n\t\t\tmfp._parseMarkup(template, dataObj, item);\n\n\t\t\tmfp.updateStatus('ready');\n\n\t\t\treturn template;\n\t\t}\n\t}\n});\n\n"
  },
  {
    "path": "static/assets/plugins/magnific-popup/src/js/image.js",
    "content": "var _imgInterval,\n\t_getTitle = function(item) {\n\t\tif(item.data && item.data.title !== undefined) \n\t\t\treturn item.data.title;\n\n\t\tvar src = mfp.st.image.titleSrc;\n\n\t\tif(src) {\n\t\t\tif($.isFunction(src)) {\n\t\t\t\treturn src.call(mfp, item);\n\t\t\t} else if(item.el) {\n\t\t\t\treturn item.el.attr(src) || '';\n\t\t\t}\n\t\t}\n\t\treturn '';\n\t};\n\n$.magnificPopup.registerModule('image', {\n\n\toptions: {\n\t\tmarkup: '<div class=\"mfp-figure\">'+\n\t\t\t\t\t'<div class=\"mfp-close\"></div>'+\n\t\t\t\t\t'<figure>'+\n\t\t\t\t\t\t'<div class=\"mfp-img\"></div>'+\n\t\t\t\t\t\t'<figcaption>'+\n\t\t\t\t\t\t\t'<div class=\"mfp-bottom-bar\">'+\n\t\t\t\t\t\t\t\t'<div class=\"mfp-title\"></div>'+\n\t\t\t\t\t\t\t\t'<div class=\"mfp-counter\"></div>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t'</figcaption>'+\n\t\t\t\t\t'</figure>'+\n\t\t\t\t'</div>',\n\t\tcursor: 'mfp-zoom-out-cur',\n\t\ttitleSrc: 'title', \n\t\tverticalFit: true,\n\t\ttError: '<a href=\"%url%\">The image</a> could not be loaded.'\n\t},\n\n\tproto: {\n\t\tinitImage: function() {\n\t\t\tvar imgSt = mfp.st.image,\n\t\t\t\tns = '.image';\n\n\t\t\tmfp.types.push('image');\n\n\t\t\t_mfpOn(OPEN_EVENT+ns, function() {\n\t\t\t\tif(mfp.currItem.type === 'image' && imgSt.cursor) {\n\t\t\t\t\t_body.addClass(imgSt.cursor);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t_mfpOn(CLOSE_EVENT+ns, function() {\n\t\t\t\tif(imgSt.cursor) {\n\t\t\t\t\t_body.removeClass(imgSt.cursor);\n\t\t\t\t}\n\t\t\t\t_window.off('resize' + EVENT_NS);\n\t\t\t});\n\n\t\t\t_mfpOn('Resize'+ns, mfp.resizeImage);\n\t\t\tif(mfp.isLowIE) {\n\t\t\t\t_mfpOn('AfterChange', mfp.resizeImage);\n\t\t\t}\n\t\t},\n\t\tresizeImage: function() {\n\t\t\tvar item = mfp.currItem;\n\t\t\tif(!item || !item.img) return;\n\n\t\t\tif(mfp.st.image.verticalFit) {\n\t\t\t\tvar decr = 0;\n\t\t\t\t// fix box-sizing in ie7/8\n\t\t\t\tif(mfp.isLowIE) {\n\t\t\t\t\tdecr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10);\n\t\t\t\t}\n\t\t\t\titem.img.css('max-height', mfp.wH-decr);\n\t\t\t}\n\t\t},\n\t\t_onImageHasSize: function(item) {\n\t\t\tif(item.img) {\n\t\t\t\t\n\t\t\t\titem.hasSize = true;\n\n\t\t\t\tif(_imgInterval) {\n\t\t\t\t\tclearInterval(_imgInterval);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\titem.isCheckingImgSize = false;\n\n\t\t\t\t_mfpTrigger('ImageHasSize', item);\n\n\t\t\t\tif(item.imgHidden) {\n\t\t\t\t\tif(mfp.content)\n\t\t\t\t\t\tmfp.content.removeClass('mfp-loading');\n\t\t\t\t\t\n\t\t\t\t\titem.imgHidden = false;\n\t\t\t\t}\n\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Function that loops until the image has size to display elements that rely on it asap\n\t\t */\n\t\tfindImageSize: function(item) {\n\n\t\t\tvar counter = 0,\n\t\t\t\timg = item.img[0],\n\t\t\t\tmfpSetInterval = function(delay) {\n\n\t\t\t\t\tif(_imgInterval) {\n\t\t\t\t\t\tclearInterval(_imgInterval);\n\t\t\t\t\t}\n\t\t\t\t\t// decelerating interval that checks for size of an image\n\t\t\t\t\t_imgInterval = setInterval(function() {\n\t\t\t\t\t\tif(img.naturalWidth > 0) {\n\t\t\t\t\t\t\tmfp._onImageHasSize(item);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(counter > 200) {\n\t\t\t\t\t\t\tclearInterval(_imgInterval);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcounter++;\n\t\t\t\t\t\tif(counter === 3) {\n\t\t\t\t\t\t\tmfpSetInterval(10);\n\t\t\t\t\t\t} else if(counter === 40) {\n\t\t\t\t\t\t\tmfpSetInterval(50);\n\t\t\t\t\t\t} else if(counter === 100) {\n\t\t\t\t\t\t\tmfpSetInterval(500);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, delay);\n\t\t\t\t};\n\n\t\t\tmfpSetInterval(1);\n\t\t},\n\n\t\tgetImage: function(item, template) {\n\n\t\t\tvar guard = 0,\n\n\t\t\t\t// image load complete handler\n\t\t\t\tonLoadComplete = function() {\n\t\t\t\t\tif(item) {\n\t\t\t\t\t\tif (item.img[0].complete) {\n\t\t\t\t\t\t\titem.img.off('.mfploader');\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tif(item === mfp.currItem){\n\t\t\t\t\t\t\t\tmfp._onImageHasSize(item);\n\n\t\t\t\t\t\t\t\tmfp.updateStatus('ready');\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\titem.hasSize = true;\n\t\t\t\t\t\t\titem.loaded = true;\n\n\t\t\t\t\t\t\t_mfpTrigger('ImageLoadComplete');\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// if image complete check fails 200 times (20 sec), we assume that there was an error.\n\t\t\t\t\t\t\tguard++;\n\t\t\t\t\t\t\tif(guard < 200) {\n\t\t\t\t\t\t\t\tsetTimeout(onLoadComplete,100);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tonLoadError();\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\n\t\t\t\t// image error handler\n\t\t\t\tonLoadError = function() {\n\t\t\t\t\tif(item) {\n\t\t\t\t\t\titem.img.off('.mfploader');\n\t\t\t\t\t\tif(item === mfp.currItem){\n\t\t\t\t\t\t\tmfp._onImageHasSize(item);\n\t\t\t\t\t\t\tmfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\titem.hasSize = true;\n\t\t\t\t\t\titem.loaded = true;\n\t\t\t\t\t\titem.loadError = true;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\timgSt = mfp.st.image;\n\n\n\t\t\tvar el = template.find('.mfp-img');\n\t\t\tif(el.length) {\n\t\t\t\tvar img = document.createElement('img');\n\t\t\t\timg.className = 'mfp-img';\n\t\t\t\tif(item.el && item.el.find('img').length) {\n\t\t\t\t\timg.alt = item.el.find('img').attr('alt');\n\t\t\t\t}\n\t\t\t\titem.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError);\n\t\t\t\timg.src = item.src;\n\n\t\t\t\t// without clone() \"error\" event is not firing when IMG is replaced by new IMG\n\t\t\t\t// TODO: find a way to avoid such cloning\n\t\t\t\tif(el.is('img')) {\n\t\t\t\t\titem.img = item.img.clone();\n\t\t\t\t}\n\n\t\t\t\timg = item.img[0];\n\t\t\t\tif(img.naturalWidth > 0) {\n\t\t\t\t\titem.hasSize = true;\n\t\t\t\t} else if(!img.width) {\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\titem.hasSize = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmfp._parseMarkup(template, {\n\t\t\t\ttitle: _getTitle(item),\n\t\t\t\timg_replaceWith: item.img\n\t\t\t}, item);\n\n\t\t\tmfp.resizeImage();\n\n\t\t\tif(item.hasSize) {\n\t\t\t\tif(_imgInterval) clearInterval(_imgInterval);\n\n\t\t\t\tif(item.loadError) {\n\t\t\t\t\ttemplate.addClass('mfp-loading');\n\t\t\t\t\tmfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );\n\t\t\t\t} else {\n\t\t\t\t\ttemplate.removeClass('mfp-loading');\n\t\t\t\t\tmfp.updateStatus('ready');\n\t\t\t\t}\n\t\t\t\treturn template;\n\t\t\t}\n\n\t\t\tmfp.updateStatus('loading');\n\t\t\titem.loading = true;\n\n\t\t\tif(!item.hasSize) {\n\t\t\t\titem.imgHidden = true;\n\t\t\t\ttemplate.addClass('mfp-loading');\n\t\t\t\tmfp.findImageSize(item);\n\t\t\t} \n\n\t\t\treturn template;\n\t\t}\n\t}\n});\n\n"
  },
  {
    "path": "static/assets/plugins/magnific-popup/src/js/inline.js",
    "content": "\nvar INLINE_NS = 'inline',\n\t_hiddenClass,\n\t_inlinePlaceholder, \n\t_lastInlineElement,\n\t_putInlineElementsBack = function() {\n\t\tif(_lastInlineElement) {\n\t\t\t_inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach();\n\t\t\t_lastInlineElement = null;\n\t\t}\n\t};\n\n$.magnificPopup.registerModule(INLINE_NS, {\n\toptions: {\n\t\thiddenClass: 'hide', // will be appended with `mfp-` prefix\n\t\tmarkup: '',\n\t\ttNotFound: 'Content not found'\n\t},\n\tproto: {\n\n\t\tinitInline: function() {\n\t\t\tmfp.types.push(INLINE_NS);\n\n\t\t\t_mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() {\n\t\t\t\t_putInlineElementsBack();\n\t\t\t});\n\t\t},\n\n\t\tgetInline: function(item, template) {\n\n\t\t\t_putInlineElementsBack();\n\n\t\t\tif(item.src) {\n\t\t\t\tvar inlineSt = mfp.st.inline,\n\t\t\t\t\tel = $(item.src);\n\n\t\t\t\tif(el.length) {\n\n\t\t\t\t\t// If target element has parent - we replace it with placeholder and put it back after popup is closed\n\t\t\t\t\tvar parent = el[0].parentNode;\n\t\t\t\t\tif(parent && parent.tagName) {\n\t\t\t\t\t\tif(!_inlinePlaceholder) {\n\t\t\t\t\t\t\t_hiddenClass = inlineSt.hiddenClass;\n\t\t\t\t\t\t\t_inlinePlaceholder = _getEl(_hiddenClass);\n\t\t\t\t\t\t\t_hiddenClass = 'mfp-'+_hiddenClass;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// replace target inline element with placeholder\n\t\t\t\t\t\t_lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass);\n\t\t\t\t\t}\n\n\t\t\t\t\tmfp.updateStatus('ready');\n\t\t\t\t} else {\n\t\t\t\t\tmfp.updateStatus('error', inlineSt.tNotFound);\n\t\t\t\t\tel = $('<div>');\n\t\t\t\t}\n\n\t\t\t\titem.inlineElement = el;\n\t\t\t\treturn el;\n\t\t\t}\n\n\t\t\tmfp.updateStatus('ready');\n\t\t\tmfp._parseMarkup(template, {}, item);\n\t\t\treturn template;\n\t\t}\n\t}\n});"
  },
  {
    "path": "static/assets/plugins/magnific-popup/src/js/retina.js",
    "content": "\nvar RETINA_NS = 'retina';\n\n$.magnificPopup.registerModule(RETINA_NS, {\n\toptions: {\n\t\treplaceSrc: function(item) {\n\t\t\treturn item.src.replace(/\\.\\w+$/, function(m) { return '@2x' + m; });\n\t\t},\n\t\tratio: 1 // Function or number.  Set to 1 to disable.\n\t},\n\tproto: {\n\t\tinitRetina: function() {\n\t\t\tif(window.devicePixelRatio > 1) {\n\n\t\t\t\tvar st = mfp.st.retina,\n\t\t\t\t\tratio = st.ratio;\n\n\t\t\t\tratio = !isNaN(ratio) ? ratio : ratio();\n\n\t\t\t\tif(ratio > 1) {\n\t\t\t\t\t_mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) {\n\t\t\t\t\t\titem.img.css({\n\t\t\t\t\t\t\t'max-width': item.img[0].naturalWidth / ratio,\n\t\t\t\t\t\t\t'width': '100%'\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t\t_mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) {\n\t\t\t\t\t\titem.src = st.replaceSrc(item, ratio);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n});"
  },
  {
    "path": "static/assets/plugins/magnific-popup/src/js/zoom.js",
    "content": "var hasMozTransform,\n\tgetHasMozTransform = function() {\n\t\tif(hasMozTransform === undefined) {\n\t\t\thasMozTransform = document.createElement('p').style.MozTransform !== undefined;\n\t\t}\n\t\treturn hasMozTransform;\t\t\n\t};\n\n$.magnificPopup.registerModule('zoom', {\n\n\toptions: {\n\t\tenabled: false,\n\t\teasing: 'ease-in-out',\n\t\tduration: 300,\n\t\topener: function(element) {\n\t\t\treturn element.is('img') ? element : element.find('img');\n\t\t}\n\t},\n\n\tproto: {\n\n\t\tinitZoom: function() {\n\t\t\tvar zoomSt = mfp.st.zoom,\n\t\t\t\tns = '.zoom',\n\t\t\t\timage;\n\t\t\t\t\n\t\t\tif(!zoomSt.enabled || !mfp.supportsTransition) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar duration = zoomSt.duration,\n\t\t\t\tgetElToAnimate = function(image) {\n\t\t\t\t\tvar newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'),\n\t\t\t\t\t\ttransition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing,\n\t\t\t\t\t\tcssObj = {\n\t\t\t\t\t\t\tposition: 'fixed',\n\t\t\t\t\t\t\tzIndex: 9999,\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\t'-webkit-backface-visibility': 'hidden'\n\t\t\t\t\t\t},\n\t\t\t\t\t\tt = 'transition';\n\n\t\t\t\t\tcssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition;\n\n\t\t\t\t\tnewImg.css(cssObj);\n\t\t\t\t\treturn newImg;\n\t\t\t\t},\n\t\t\t\tshowMainContent = function() {\n\t\t\t\t\tmfp.content.css('visibility', 'visible');\n\t\t\t\t},\n\t\t\t\topenTimeout,\n\t\t\t\tanimatedImg;\n\n\t\t\t_mfpOn('BuildControls'+ns, function() {\n\t\t\t\tif(mfp._allowZoom()) {\n\n\t\t\t\t\tclearTimeout(openTimeout);\n\t\t\t\t\tmfp.content.css('visibility', 'hidden');\n\n\t\t\t\t\t// Basically, all code below does is clones existing image, puts in on top of the current one and animated it\n\t\t\t\t\t\n\t\t\t\t\timage = mfp._getItemToZoom();\n\n\t\t\t\t\tif(!image) {\n\t\t\t\t\t\tshowMainContent();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tanimatedImg = getElToAnimate(image); \n\t\t\t\t\t\n\t\t\t\t\tanimatedImg.css( mfp._getOffset() );\n\n\t\t\t\t\tmfp.wrap.append(animatedImg);\n\n\t\t\t\t\topenTimeout = setTimeout(function() {\n\t\t\t\t\t\tanimatedImg.css( mfp._getOffset( true ) );\n\t\t\t\t\t\topenTimeout = setTimeout(function() {\n\n\t\t\t\t\t\t\tshowMainContent();\n\n\t\t\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\t\t\tanimatedImg.remove();\n\t\t\t\t\t\t\t\timage = animatedImg = null;\n\t\t\t\t\t\t\t\t_mfpTrigger('ZoomAnimationEnded');\n\t\t\t\t\t\t\t}, 16); // avoid blink when switching images \n\n\t\t\t\t\t\t}, duration); // this timeout equals animation duration\n\n\t\t\t\t\t}, 16); // by adding this timeout we avoid short glitch at the beginning of animation\n\n\n\t\t\t\t\t// Lots of timeouts...\n\t\t\t\t}\n\t\t\t});\n\t\t\t_mfpOn(BEFORE_CLOSE_EVENT+ns, function() {\n\t\t\t\tif(mfp._allowZoom()) {\n\n\t\t\t\t\tclearTimeout(openTimeout);\n\n\t\t\t\t\tmfp.st.removalDelay = duration;\n\n\t\t\t\t\tif(!image) {\n\t\t\t\t\t\timage = mfp._getItemToZoom();\n\t\t\t\t\t\tif(!image) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tanimatedImg = getElToAnimate(image);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\tanimatedImg.css( mfp._getOffset(true) );\n\t\t\t\t\tmfp.wrap.append(animatedImg);\n\t\t\t\t\tmfp.content.css('visibility', 'hidden');\n\t\t\t\t\t\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tanimatedImg.css( mfp._getOffset() );\n\t\t\t\t\t}, 16);\n\t\t\t\t}\n\n\t\t\t});\n\n\t\t\t_mfpOn(CLOSE_EVENT+ns, function() {\n\t\t\t\tif(mfp._allowZoom()) {\n\t\t\t\t\tshowMainContent();\n\t\t\t\t\tif(animatedImg) {\n\t\t\t\t\t\tanimatedImg.remove();\n\t\t\t\t\t}\n\t\t\t\t\timage = null;\n\t\t\t\t}\t\n\t\t\t});\n\t\t},\n\n\t\t_allowZoom: function() {\n\t\t\treturn mfp.currItem.type === 'image';\n\t\t},\n\n\t\t_getItemToZoom: function() {\n\t\t\tif(mfp.currItem.hasSize) {\n\t\t\t\treturn mfp.currItem.img;\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\n\t\t// Get element postion relative to viewport\n\t\t_getOffset: function(isLarge) {\n\t\t\tvar el;\n\t\t\tif(isLarge) {\n\t\t\t\tel = mfp.currItem.img;\n\t\t\t} else {\n\t\t\t\tel = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem);\n\t\t\t}\n\n\t\t\tvar offset = el.offset();\n\t\t\tvar paddingTop = parseInt(el.css('padding-top'),10);\n\t\t\tvar paddingBottom = parseInt(el.css('padding-bottom'),10);\n\t\t\toffset.top -= ( $(window).scrollTop() - paddingTop );\n\n\n\t\t\t/*\n\t\t\t\n\t\t\tAnimating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa.\n\n\t\t\t */\n\t\t\tvar obj = {\n\t\t\t\twidth: el.width(),\n\t\t\t\t// fix Zepto height+padding issue\n\t\t\t\theight: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop\n\t\t\t};\n\n\t\t\t// I hate to do this, but there is no another option\n\t\t\tif( getHasMozTransform() ) {\n\t\t\t\tobj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)';\n\t\t\t} else {\n\t\t\t\tobj.left = offset.left;\n\t\t\t\tobj.top = offset.top;\n\t\t\t}\n\t\t\treturn obj;\n\t\t}\n\n\t}\n});\n\n"
  },
  {
    "path": "static/assets/plugins/morris/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/assets/plugins/morris/morris.js",
    "content": "/* @license\nmorris.js v0.5.0\nCopyright 2014 Olly Smith All rights reserved.\nLicensed under the BSD-2-Clause License.\n*/\n\n\n(function() {\n  var $, Morris, minutesSpecHelper, secondsSpecHelper,\n    __slice = [].slice,\n    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },\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  Morris = window.Morris = {};\n\n  $ = jQuery;\n\n  Morris.EventEmitter = (function() {\n    function EventEmitter() {}\n\n    EventEmitter.prototype.on = function(name, handler) {\n      if (this.handlers == null) {\n        this.handlers = {};\n      }\n      if (this.handlers[name] == null) {\n        this.handlers[name] = [];\n      }\n      this.handlers[name].push(handler);\n      return this;\n    };\n\n    EventEmitter.prototype.fire = function() {\n      var args, handler, name, _i, _len, _ref, _results;\n      name = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n      if ((this.handlers != null) && (this.handlers[name] != null)) {\n        _ref = this.handlers[name];\n        _results = [];\n        for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n          handler = _ref[_i];\n          _results.push(handler.apply(null, args));\n        }\n        return _results;\n      }\n    };\n\n    return EventEmitter;\n\n  })();\n\n  Morris.commas = function(num) {\n    var absnum, intnum, ret, strabsnum;\n    if (num != null) {\n      ret = num < 0 ? \"-\" : \"\";\n      absnum = Math.abs(num);\n      intnum = Math.floor(absnum).toFixed(0);\n      ret += intnum.replace(/(?=(?:\\d{3})+$)(?!^)/g, ',');\n      strabsnum = absnum.toString();\n      if (strabsnum.length > intnum.length) {\n        ret += strabsnum.slice(intnum.length);\n      }\n      return ret;\n    } else {\n      return '-';\n    }\n  };\n\n  Morris.pad2 = function(number) {\n    return (number < 10 ? '0' : '') + number;\n  };\n\n  Morris.Grid = (function(_super) {\n    __extends(Grid, _super);\n\n    function Grid(options) {\n      this.resizeHandler = __bind(this.resizeHandler, this);\n      var _this = this;\n      if (typeof options.element === 'string') {\n        this.el = $(document.getElementById(options.element));\n      } else {\n        this.el = $(options.element);\n      }\n      if ((this.el == null) || this.el.length === 0) {\n        throw new Error(\"Graph container element not found\");\n      }\n      if (this.el.css('position') === 'static') {\n        this.el.css('position', 'relative');\n      }\n      this.options = $.extend({}, this.gridDefaults, this.defaults || {}, options);\n      if (typeof this.options.units === 'string') {\n        this.options.postUnits = options.units;\n      }\n      this.raphael = new Raphael(this.el[0]);\n      this.elementWidth = null;\n      this.elementHeight = null;\n      this.dirty = false;\n      this.selectFrom = null;\n      if (this.init) {\n        this.init();\n      }\n      this.setData(this.options.data);\n      this.el.bind('mousemove', function(evt) {\n        var left, offset, right, width, x;\n        offset = _this.el.offset();\n        x = evt.pageX - offset.left;\n        if (_this.selectFrom) {\n          left = _this.data[_this.hitTest(Math.min(x, _this.selectFrom))]._x;\n          right = _this.data[_this.hitTest(Math.max(x, _this.selectFrom))]._x;\n          width = right - left;\n          return _this.selectionRect.attr({\n            x: left,\n            width: width\n          });\n        } else {\n          return _this.fire('hovermove', x, evt.pageY - offset.top);\n        }\n      });\n      this.el.bind('mouseleave', function(evt) {\n        if (_this.selectFrom) {\n          _this.selectionRect.hide();\n          _this.selectFrom = null;\n        }\n        return _this.fire('hoverout');\n      });\n      this.el.bind('touchstart touchmove touchend', function(evt) {\n        var offset, touch;\n        touch = evt.originalEvent.touches[0] || evt.originalEvent.changedTouches[0];\n        offset = _this.el.offset();\n        return _this.fire('hovermove', touch.pageX - offset.left, touch.pageY - offset.top);\n      });\n      this.el.bind('click', function(evt) {\n        var offset;\n        offset = _this.el.offset();\n        return _this.fire('gridclick', evt.pageX - offset.left, evt.pageY - offset.top);\n      });\n      if (this.options.rangeSelect) {\n        this.selectionRect = this.raphael.rect(0, 0, 0, this.el.innerHeight()).attr({\n          fill: this.options.rangeSelectColor,\n          stroke: false\n        }).toBack().hide();\n        this.el.bind('mousedown', function(evt) {\n          var offset;\n          offset = _this.el.offset();\n          return _this.startRange(evt.pageX - offset.left);\n        });\n        this.el.bind('mouseup', function(evt) {\n          var offset;\n          offset = _this.el.offset();\n          _this.endRange(evt.pageX - offset.left);\n          return _this.fire('hovermove', evt.pageX - offset.left, evt.pageY - offset.top);\n        });\n      }\n      if (this.options.resize) {\n        $(window).bind('resize', function(evt) {\n          if (_this.timeoutId != null) {\n            window.clearTimeout(_this.timeoutId);\n          }\n          return _this.timeoutId = window.setTimeout(_this.resizeHandler, 100);\n        });\n      }\n      this.el.css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');\n      if (this.postInit) {\n        this.postInit();\n      }\n    }\n\n    Grid.prototype.gridDefaults = {\n      dateFormat: null,\n      axes: true,\n      grid: true,\n      gridLineColor: '#aaa',\n      gridStrokeWidth: 0.5,\n      gridTextColor: '#888',\n      gridTextSize: 12,\n      gridTextFamily: 'sans-serif',\n      gridTextWeight: 'normal',\n      hideHover: false,\n      yLabelFormat: null,\n      xLabelAngle: 0,\n      numLines: 5,\n      padding: 25,\n      parseTime: true,\n      postUnits: '',\n      preUnits: '',\n      ymax: 'auto',\n      ymin: 'auto 0',\n      goals: [],\n      goalStrokeWidth: 1.0,\n      goalLineColors: ['#666633', '#999966', '#cc6666', '#663333'],\n      events: [],\n      eventStrokeWidth: 1.0,\n      eventLineColors: ['#005a04', '#ccffbb', '#3a5f0b', '#005502'],\n      rangeSelect: null,\n      rangeSelectColor: '#eef',\n      resize: false\n    };\n\n    Grid.prototype.setData = function(data, redraw) {\n      var e, idx, index, maxGoal, minGoal, ret, row, step, total, y, ykey, ymax, ymin, yval, _ref;\n      if (redraw == null) {\n        redraw = true;\n      }\n      this.options.data = data;\n      if ((data == null) || data.length === 0) {\n        this.data = [];\n        this.raphael.clear();\n        if (this.hover != null) {\n          this.hover.hide();\n        }\n        return;\n      }\n      ymax = this.cumulative ? 0 : null;\n      ymin = this.cumulative ? 0 : null;\n      if (this.options.goals.length > 0) {\n        minGoal = Math.min.apply(Math, this.options.goals);\n        maxGoal = Math.max.apply(Math, this.options.goals);\n        ymin = ymin != null ? Math.min(ymin, minGoal) : minGoal;\n        ymax = ymax != null ? Math.max(ymax, maxGoal) : maxGoal;\n      }\n      this.data = (function() {\n        var _i, _len, _results;\n        _results = [];\n        for (index = _i = 0, _len = data.length; _i < _len; index = ++_i) {\n          row = data[index];\n          ret = {\n            src: row\n          };\n          ret.label = row[this.options.xkey];\n          if (this.options.parseTime) {\n            ret.x = Morris.parseDate(ret.label);\n            if (this.options.dateFormat) {\n              ret.label = this.options.dateFormat(ret.x);\n            } else if (typeof ret.label === 'number') {\n              ret.label = new Date(ret.label).toString();\n            }\n          } else {\n            ret.x = index;\n            if (this.options.xLabelFormat) {\n              ret.label = this.options.xLabelFormat(ret);\n            }\n          }\n          total = 0;\n          ret.y = (function() {\n            var _j, _len1, _ref, _results1;\n            _ref = this.options.ykeys;\n            _results1 = [];\n            for (idx = _j = 0, _len1 = _ref.length; _j < _len1; idx = ++_j) {\n              ykey = _ref[idx];\n              yval = row[ykey];\n              if (typeof yval === 'string') {\n                yval = parseFloat(yval);\n              }\n              if ((yval != null) && typeof yval !== 'number') {\n                yval = null;\n              }\n              if (yval != null) {\n                if (this.cumulative) {\n                  total += yval;\n                } else {\n                  if (ymax != null) {\n                    ymax = Math.max(yval, ymax);\n                    ymin = Math.min(yval, ymin);\n                  } else {\n                    ymax = ymin = yval;\n                  }\n                }\n              }\n              if (this.cumulative && (total != null)) {\n                ymax = Math.max(total, ymax);\n                ymin = Math.min(total, ymin);\n              }\n              _results1.push(yval);\n            }\n            return _results1;\n          }).call(this);\n          _results.push(ret);\n        }\n        return _results;\n      }).call(this);\n      if (this.options.parseTime) {\n        this.data = this.data.sort(function(a, b) {\n          return (a.x > b.x) - (b.x > a.x);\n        });\n      }\n      this.xmin = this.data[0].x;\n      this.xmax = this.data[this.data.length - 1].x;\n      this.events = [];\n      if (this.options.events.length > 0) {\n        if (this.options.parseTime) {\n          this.events = (function() {\n            var _i, _len, _ref, _results;\n            _ref = this.options.events;\n            _results = [];\n            for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n              e = _ref[_i];\n              _results.push(Morris.parseDate(e));\n            }\n            return _results;\n          }).call(this);\n        } else {\n          this.events = this.options.events;\n        }\n        this.xmax = Math.max(this.xmax, Math.max.apply(Math, this.events));\n        this.xmin = Math.min(this.xmin, Math.min.apply(Math, this.events));\n      }\n      if (this.xmin === this.xmax) {\n        this.xmin -= 1;\n        this.xmax += 1;\n      }\n      this.ymin = this.yboundary('min', ymin);\n      this.ymax = this.yboundary('max', ymax);\n      if (this.ymin === this.ymax) {\n        if (ymin) {\n          this.ymin -= 1;\n        }\n        this.ymax += 1;\n      }\n      if (((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'y') || this.options.grid === true) {\n        if (this.options.ymax === this.gridDefaults.ymax && this.options.ymin === this.gridDefaults.ymin) {\n          this.grid = this.autoGridLines(this.ymin, this.ymax, this.options.numLines);\n          this.ymin = Math.min(this.ymin, this.grid[0]);\n          this.ymax = Math.max(this.ymax, this.grid[this.grid.length - 1]);\n        } else {\n          step = (this.ymax - this.ymin) / (this.options.numLines - 1);\n          this.grid = (function() {\n            var _i, _ref1, _ref2, _results;\n            _results = [];\n            for (y = _i = _ref1 = this.ymin, _ref2 = this.ymax; step > 0 ? _i <= _ref2 : _i >= _ref2; y = _i += step) {\n              _results.push(y);\n            }\n            return _results;\n          }).call(this);\n        }\n      }\n      this.dirty = true;\n      if (redraw) {\n        return this.redraw();\n      }\n    };\n\n    Grid.prototype.yboundary = function(boundaryType, currentValue) {\n      var boundaryOption, suggestedValue;\n      boundaryOption = this.options[\"y\" + boundaryType];\n      if (typeof boundaryOption === 'string') {\n        if (boundaryOption.slice(0, 4) === 'auto') {\n          if (boundaryOption.length > 5) {\n            suggestedValue = parseInt(boundaryOption.slice(5), 10);\n            if (currentValue == null) {\n              return suggestedValue;\n            }\n            return Math[boundaryType](currentValue, suggestedValue);\n          } else {\n            if (currentValue != null) {\n              return currentValue;\n            } else {\n              return 0;\n            }\n          }\n        } else {\n          return parseInt(boundaryOption, 10);\n        }\n      } else {\n        return boundaryOption;\n      }\n    };\n\n    Grid.prototype.autoGridLines = function(ymin, ymax, nlines) {\n      var gmax, gmin, grid, smag, span, step, unit, y, ymag;\n      span = ymax - ymin;\n      ymag = Math.floor(Math.log(span) / Math.log(10));\n      unit = Math.pow(10, ymag);\n      gmin = Math.floor(ymin / unit) * unit;\n      gmax = Math.ceil(ymax / unit) * unit;\n      step = (gmax - gmin) / (nlines - 1);\n      if (unit === 1 && step > 1 && Math.ceil(step) !== step) {\n        step = Math.ceil(step);\n        gmax = gmin + step * (nlines - 1);\n      }\n      if (gmin < 0 && gmax > 0) {\n        gmin = Math.floor(ymin / step) * step;\n        gmax = Math.ceil(ymax / step) * step;\n      }\n      if (step < 1) {\n        smag = Math.floor(Math.log(step) / Math.log(10));\n        grid = (function() {\n          var _i, _results;\n          _results = [];\n          for (y = _i = gmin; step > 0 ? _i <= gmax : _i >= gmax; y = _i += step) {\n            _results.push(parseFloat(y.toFixed(1 - smag)));\n          }\n          return _results;\n        })();\n      } else {\n        grid = (function() {\n          var _i, _results;\n          _results = [];\n          for (y = _i = gmin; step > 0 ? _i <= gmax : _i >= gmax; y = _i += step) {\n            _results.push(y);\n          }\n          return _results;\n        })();\n      }\n      return grid;\n    };\n\n    Grid.prototype._calc = function() {\n      var bottomOffsets, gridLine, h, i, w, yLabelWidths, _ref, _ref1;\n      w = this.el.width();\n      h = this.el.height();\n      if (this.elementWidth !== w || this.elementHeight !== h || this.dirty) {\n        this.elementWidth = w;\n        this.elementHeight = h;\n        this.dirty = false;\n        this.left = this.options.padding;\n        this.right = this.elementWidth - this.options.padding;\n        this.top = this.options.padding;\n        this.bottom = this.elementHeight - this.options.padding;\n        if ((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'y') {\n          yLabelWidths = (function() {\n            var _i, _len, _ref1, _results;\n            _ref1 = this.grid;\n            _results = [];\n            for (_i = 0, _len = _ref1.length; _i < _len; _i++) {\n              gridLine = _ref1[_i];\n              _results.push(this.measureText(this.yAxisFormat(gridLine)).width);\n            }\n            return _results;\n          }).call(this);\n          this.left += Math.max.apply(Math, yLabelWidths);\n        }\n        if ((_ref1 = this.options.axes) === true || _ref1 === 'both' || _ref1 === 'x') {\n          bottomOffsets = (function() {\n            var _i, _ref2, _results;\n            _results = [];\n            for (i = _i = 0, _ref2 = this.data.length; 0 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 0 <= _ref2 ? ++_i : --_i) {\n              _results.push(this.measureText(this.data[i].text, -this.options.xLabelAngle).height);\n            }\n            return _results;\n          }).call(this);\n          this.bottom -= Math.max.apply(Math, bottomOffsets);\n        }\n        this.width = Math.max(1, this.right - this.left);\n        this.height = Math.max(1, this.bottom - this.top);\n        this.dx = this.width / (this.xmax - this.xmin);\n        this.dy = this.height / (this.ymax - this.ymin);\n        if (this.calc) {\n          return this.calc();\n        }\n      }\n    };\n\n    Grid.prototype.transY = function(y) {\n      return this.bottom - (y - this.ymin) * this.dy;\n    };\n\n    Grid.prototype.transX = function(x) {\n      if (this.data.length === 1) {\n        return (this.left + this.right) / 2;\n      } else {\n        return this.left + (x - this.xmin) * this.dx;\n      }\n    };\n\n    Grid.prototype.redraw = function() {\n      this.raphael.clear();\n      this._calc();\n      this.drawGrid();\n      this.drawGoals();\n      this.drawEvents();\n      if (this.draw) {\n        return this.draw();\n      }\n    };\n\n    Grid.prototype.measureText = function(text, angle) {\n      var ret, tt;\n      if (angle == null) {\n        angle = 0;\n      }\n      tt = this.raphael.text(100, 100, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).rotate(angle);\n      ret = tt.getBBox();\n      tt.remove();\n      return ret;\n    };\n\n    Grid.prototype.yAxisFormat = function(label) {\n      return this.yLabelFormat(label);\n    };\n\n    Grid.prototype.yLabelFormat = function(label) {\n      if (typeof this.options.yLabelFormat === 'function') {\n        return this.options.yLabelFormat(label);\n      } else {\n        return \"\" + this.options.preUnits + (Morris.commas(label)) + this.options.postUnits;\n      }\n    };\n\n    Grid.prototype.drawGrid = function() {\n      var lineY, y, _i, _len, _ref, _ref1, _ref2, _results;\n      if (this.options.grid === false && ((_ref = this.options.axes) !== true && _ref !== 'both' && _ref !== 'y')) {\n        return;\n      }\n      _ref1 = this.grid;\n      _results = [];\n      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {\n        lineY = _ref1[_i];\n        y = this.transY(lineY);\n        if ((_ref2 = this.options.axes) === true || _ref2 === 'both' || _ref2 === 'y') {\n          this.drawYAxisLabel(this.left - this.options.padding / 2, y, this.yAxisFormat(lineY));\n        }\n        if (this.options.grid) {\n          _results.push(this.drawGridLine(\"M\" + this.left + \",\" + y + \"H\" + (this.left + this.width)));\n        } else {\n          _results.push(void 0);\n        }\n      }\n      return _results;\n    };\n\n    Grid.prototype.drawGoals = function() {\n      var color, goal, i, _i, _len, _ref, _results;\n      _ref = this.options.goals;\n      _results = [];\n      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {\n        goal = _ref[i];\n        color = this.options.goalLineColors[i % this.options.goalLineColors.length];\n        _results.push(this.drawGoal(goal, color));\n      }\n      return _results;\n    };\n\n    Grid.prototype.drawEvents = function() {\n      var color, event, i, _i, _len, _ref, _results;\n      _ref = this.events;\n      _results = [];\n      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {\n        event = _ref[i];\n        color = this.options.eventLineColors[i % this.options.eventLineColors.length];\n        _results.push(this.drawEvent(event, color));\n      }\n      return _results;\n    };\n\n    Grid.prototype.drawGoal = function(goal, color) {\n      return this.raphael.path(\"M\" + this.left + \",\" + (this.transY(goal)) + \"H\" + this.right).attr('stroke', color).attr('stroke-width', this.options.goalStrokeWidth);\n    };\n\n    Grid.prototype.drawEvent = function(event, color) {\n      return this.raphael.path(\"M\" + (this.transX(event)) + \",\" + this.bottom + \"V\" + this.top).attr('stroke', color).attr('stroke-width', this.options.eventStrokeWidth);\n    };\n\n    Grid.prototype.drawYAxisLabel = function(xPos, yPos, text) {\n      return this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end');\n    };\n\n    Grid.prototype.drawGridLine = function(path) {\n      return this.raphael.path(path).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth);\n    };\n\n    Grid.prototype.startRange = function(x) {\n      this.hover.hide();\n      this.selectFrom = x;\n      return this.selectionRect.attr({\n        x: x,\n        width: 0\n      }).show();\n    };\n\n    Grid.prototype.endRange = function(x) {\n      var end, start;\n      if (this.selectFrom) {\n        start = Math.min(this.selectFrom, x);\n        end = Math.max(this.selectFrom, x);\n        this.options.rangeSelect.call(this.el, {\n          start: this.data[this.hitTest(start)].x,\n          end: this.data[this.hitTest(end)].x\n        });\n        return this.selectFrom = null;\n      }\n    };\n\n    Grid.prototype.resizeHandler = function() {\n      this.timeoutId = null;\n      this.raphael.setSize(this.el.width(), this.el.height());\n      return this.redraw();\n    };\n\n    return Grid;\n\n  })(Morris.EventEmitter);\n\n  Morris.parseDate = function(date) {\n    var isecs, m, msecs, n, o, offsetmins, p, q, r, ret, secs;\n    if (typeof date === 'number') {\n      return date;\n    }\n    m = date.match(/^(\\d+) Q(\\d)$/);\n    n = date.match(/^(\\d+)-(\\d+)$/);\n    o = date.match(/^(\\d+)-(\\d+)-(\\d+)$/);\n    p = date.match(/^(\\d+) W(\\d+)$/);\n    q = date.match(/^(\\d+)-(\\d+)-(\\d+)[ T](\\d+):(\\d+)(Z|([+-])(\\d\\d):?(\\d\\d))?$/);\n    r = date.match(/^(\\d+)-(\\d+)-(\\d+)[ T](\\d+):(\\d+):(\\d+(\\.\\d+)?)(Z|([+-])(\\d\\d):?(\\d\\d))?$/);\n    if (m) {\n      return new Date(parseInt(m[1], 10), parseInt(m[2], 10) * 3 - 1, 1).getTime();\n    } else if (n) {\n      return new Date(parseInt(n[1], 10), parseInt(n[2], 10) - 1, 1).getTime();\n    } else if (o) {\n      return new Date(parseInt(o[1], 10), parseInt(o[2], 10) - 1, parseInt(o[3], 10)).getTime();\n    } else if (p) {\n      ret = new Date(parseInt(p[1], 10), 0, 1);\n      if (ret.getDay() !== 4) {\n        ret.setMonth(0, 1 + ((4 - ret.getDay()) + 7) % 7);\n      }\n      return ret.getTime() + parseInt(p[2], 10) * 604800000;\n    } else if (q) {\n      if (!q[6]) {\n        return new Date(parseInt(q[1], 10), parseInt(q[2], 10) - 1, parseInt(q[3], 10), parseInt(q[4], 10), parseInt(q[5], 10)).getTime();\n      } else {\n        offsetmins = 0;\n        if (q[6] !== 'Z') {\n          offsetmins = parseInt(q[8], 10) * 60 + parseInt(q[9], 10);\n          if (q[7] === '+') {\n            offsetmins = 0 - offsetmins;\n          }\n        }\n        return Date.UTC(parseInt(q[1], 10), parseInt(q[2], 10) - 1, parseInt(q[3], 10), parseInt(q[4], 10), parseInt(q[5], 10) + offsetmins);\n      }\n    } else if (r) {\n      secs = parseFloat(r[6]);\n      isecs = Math.floor(secs);\n      msecs = Math.round((secs - isecs) * 1000);\n      if (!r[8]) {\n        return new Date(parseInt(r[1], 10), parseInt(r[2], 10) - 1, parseInt(r[3], 10), parseInt(r[4], 10), parseInt(r[5], 10), isecs, msecs).getTime();\n      } else {\n        offsetmins = 0;\n        if (r[8] !== 'Z') {\n          offsetmins = parseInt(r[10], 10) * 60 + parseInt(r[11], 10);\n          if (r[9] === '+') {\n            offsetmins = 0 - offsetmins;\n          }\n        }\n        return Date.UTC(parseInt(r[1], 10), parseInt(r[2], 10) - 1, parseInt(r[3], 10), parseInt(r[4], 10), parseInt(r[5], 10) + offsetmins, isecs, msecs);\n      }\n    } else {\n      return new Date(parseInt(date, 10), 0, 1).getTime();\n    }\n  };\n\n  Morris.Hover = (function() {\n    Hover.defaults = {\n      \"class\": 'morris-hover morris-default-style'\n    };\n\n    function Hover(options) {\n      if (options == null) {\n        options = {};\n      }\n      this.options = $.extend({}, Morris.Hover.defaults, options);\n      this.el = $(\"<div class='\" + this.options[\"class\"] + \"'></div>\");\n      this.el.hide();\n      this.options.parent.append(this.el);\n    }\n\n    Hover.prototype.update = function(html, x, y) {\n      if (!html) {\n        return this.hide();\n      } else {\n        this.html(html);\n        this.show();\n        return this.moveTo(x, y);\n      }\n    };\n\n    Hover.prototype.html = function(content) {\n      return this.el.html(content);\n    };\n\n    Hover.prototype.moveTo = function(x, y) {\n      var hoverHeight, hoverWidth, left, parentHeight, parentWidth, top;\n      parentWidth = this.options.parent.innerWidth();\n      parentHeight = this.options.parent.innerHeight();\n      hoverWidth = this.el.outerWidth();\n      hoverHeight = this.el.outerHeight();\n      left = Math.min(Math.max(0, x - hoverWidth / 2), parentWidth - hoverWidth);\n      if (y != null) {\n        top = y - hoverHeight - 10;\n        if (top < 0) {\n          top = y + 10;\n          if (top + hoverHeight > parentHeight) {\n            top = parentHeight / 2 - hoverHeight / 2;\n          }\n        }\n      } else {\n        top = parentHeight / 2 - hoverHeight / 2;\n      }\n      return this.el.css({\n        left: left + \"px\",\n        top: parseInt(top) + \"px\"\n      });\n    };\n\n    Hover.prototype.show = function() {\n      return this.el.show();\n    };\n\n    Hover.prototype.hide = function() {\n      return this.el.hide();\n    };\n\n    return Hover;\n\n  })();\n\n  Morris.Line = (function(_super) {\n    __extends(Line, _super);\n\n    function Line(options) {\n      this.hilight = __bind(this.hilight, this);\n      this.onHoverOut = __bind(this.onHoverOut, this);\n      this.onHoverMove = __bind(this.onHoverMove, this);\n      this.onGridClick = __bind(this.onGridClick, this);\n      if (!(this instanceof Morris.Line)) {\n        return new Morris.Line(options);\n      }\n      Line.__super__.constructor.call(this, options);\n    }\n\n    Line.prototype.init = function() {\n      if (this.options.hideHover !== 'always') {\n        this.hover = new Morris.Hover({\n          parent: this.el\n        });\n        this.on('hovermove', this.onHoverMove);\n        this.on('hoverout', this.onHoverOut);\n        return this.on('gridclick', this.onGridClick);\n      }\n    };\n\n    Line.prototype.defaults = {\n      lineWidth: 3,\n      pointSize: 4,\n      lineColors: ['#0b62a4', '#7A92A3', '#4da74d', '#afd8f8', '#edc240', '#cb4b4b', '#9440ed'],\n      pointStrokeWidths: [1],\n      pointStrokeColors: ['#ffffff'],\n      pointFillColors: [],\n      smooth: true,\n      xLabels: 'auto',\n      xLabelFormat: null,\n      xLabelMargin: 24,\n      hideHover: false\n    };\n\n    Line.prototype.calc = function() {\n      this.calcPoints();\n      return this.generatePaths();\n    };\n\n    Line.prototype.calcPoints = function() {\n      var row, y, _i, _len, _ref, _results;\n      _ref = this.data;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        row = _ref[_i];\n        row._x = this.transX(row.x);\n        row._y = (function() {\n          var _j, _len1, _ref1, _results1;\n          _ref1 = row.y;\n          _results1 = [];\n          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n            y = _ref1[_j];\n            if (y != null) {\n              _results1.push(this.transY(y));\n            } else {\n              _results1.push(y);\n            }\n          }\n          return _results1;\n        }).call(this);\n        _results.push(row._ymax = Math.min.apply(Math, [this.bottom].concat((function() {\n          var _j, _len1, _ref1, _results1;\n          _ref1 = row._y;\n          _results1 = [];\n          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n            y = _ref1[_j];\n            if (y != null) {\n              _results1.push(y);\n            }\n          }\n          return _results1;\n        })())));\n      }\n      return _results;\n    };\n\n    Line.prototype.hitTest = function(x) {\n      var index, r, _i, _len, _ref;\n      if (this.data.length === 0) {\n        return null;\n      }\n      _ref = this.data.slice(1);\n      for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {\n        r = _ref[index];\n        if (x < (r._x + this.data[index]._x) / 2) {\n          break;\n        }\n      }\n      return index;\n    };\n\n    Line.prototype.onGridClick = function(x, y) {\n      var index;\n      index = this.hitTest(x);\n      return this.fire('click', index, this.data[index].src, x, y);\n    };\n\n    Line.prototype.onHoverMove = function(x, y) {\n      var index;\n      index = this.hitTest(x);\n      return this.displayHoverForRow(index);\n    };\n\n    Line.prototype.onHoverOut = function() {\n      if (this.options.hideHover !== false) {\n        return this.displayHoverForRow(null);\n      }\n    };\n\n    Line.prototype.displayHoverForRow = function(index) {\n      var _ref;\n      if (index != null) {\n        (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index));\n        return this.hilight(index);\n      } else {\n        this.hover.hide();\n        return this.hilight();\n      }\n    };\n\n    Line.prototype.hoverContentForRow = function(index) {\n      var content, j, row, y, _i, _len, _ref;\n      row = this.data[index];\n      content = \"<div class='morris-hover-row-label'>\" + row.label + \"</div>\";\n      _ref = row.y;\n      for (j = _i = 0, _len = _ref.length; _i < _len; j = ++_i) {\n        y = _ref[j];\n        content += \"<div class='morris-hover-point' style='color: \" + (this.colorFor(row, j, 'label')) + \"'>\\n  \" + this.options.labels[j] + \":\\n  \" + (this.yLabelFormat(y)) + \"\\n</div>\";\n      }\n      if (typeof this.options.hoverCallback === 'function') {\n        content = this.options.hoverCallback(index, this.options, content, row.src);\n      }\n      return [content, row._x, row._ymax];\n    };\n\n    Line.prototype.generatePaths = function() {\n      var coords, i, r, smooth;\n      return this.paths = (function() {\n        var _i, _ref, _ref1, _results;\n        _results = [];\n        for (i = _i = 0, _ref = this.options.ykeys.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n          smooth = typeof this.options.smooth === \"boolean\" ? this.options.smooth : (_ref1 = this.options.ykeys[i], __indexOf.call(this.options.smooth, _ref1) >= 0);\n          coords = (function() {\n            var _j, _len, _ref2, _results1;\n            _ref2 = this.data;\n            _results1 = [];\n            for (_j = 0, _len = _ref2.length; _j < _len; _j++) {\n              r = _ref2[_j];\n              if (r._y[i] !== void 0) {\n                _results1.push({\n                  x: r._x,\n                  y: r._y[i]\n                });\n              }\n            }\n            return _results1;\n          }).call(this);\n          if (coords.length > 1) {\n            _results.push(Morris.Line.createPath(coords, smooth, this.bottom));\n          } else {\n            _results.push(null);\n          }\n        }\n        return _results;\n      }).call(this);\n    };\n\n    Line.prototype.draw = function() {\n      var _ref;\n      if ((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'x') {\n        this.drawXAxis();\n      }\n      this.drawSeries();\n      if (this.options.hideHover === false) {\n        return this.displayHoverForRow(this.data.length - 1);\n      }\n    };\n\n    Line.prototype.drawXAxis = function() {\n      var drawLabel, l, labels, prevAngleMargin, prevLabelMargin, row, ypos, _i, _len, _results,\n        _this = this;\n      ypos = this.bottom + this.options.padding / 2;\n      prevLabelMargin = null;\n      prevAngleMargin = null;\n      drawLabel = function(labelText, xpos) {\n        var label, labelBox, margin, offset, textBox;\n        label = _this.drawXAxisLabel(_this.transX(xpos), ypos, labelText);\n        textBox = label.getBBox();\n        label.transform(\"r\" + (-_this.options.xLabelAngle));\n        labelBox = label.getBBox();\n        label.transform(\"t0,\" + (labelBox.height / 2) + \"...\");\n        if (_this.options.xLabelAngle !== 0) {\n          offset = -0.5 * textBox.width * Math.cos(_this.options.xLabelAngle * Math.PI / 180.0);\n          label.transform(\"t\" + offset + \",0...\");\n        }\n        labelBox = label.getBBox();\n        if (((prevLabelMargin == null) || prevLabelMargin >= labelBox.x + labelBox.width || (prevAngleMargin != null) && prevAngleMargin >= labelBox.x) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < _this.el.width()) {\n          if (_this.options.xLabelAngle !== 0) {\n            margin = 1.25 * _this.options.gridTextSize / Math.sin(_this.options.xLabelAngle * Math.PI / 180.0);\n            prevAngleMargin = labelBox.x - margin;\n          }\n          return prevLabelMargin = labelBox.x - _this.options.xLabelMargin;\n        } else {\n          return label.remove();\n        }\n      };\n      if (this.options.parseTime) {\n        if (this.data.length === 1 && this.options.xLabels === 'auto') {\n          labels = [[this.data[0].label, this.data[0].x]];\n        } else {\n          labels = Morris.labelSeries(this.xmin, this.xmax, this.width, this.options.xLabels, this.options.xLabelFormat);\n        }\n      } else {\n        labels = (function() {\n          var _i, _len, _ref, _results;\n          _ref = this.data;\n          _results = [];\n          for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n            row = _ref[_i];\n            _results.push([row.label, row.x]);\n          }\n          return _results;\n        }).call(this);\n      }\n      labels.reverse();\n      _results = [];\n      for (_i = 0, _len = labels.length; _i < _len; _i++) {\n        l = labels[_i];\n        _results.push(drawLabel(l[0], l[1]));\n      }\n      return _results;\n    };\n\n    Line.prototype.drawSeries = function() {\n      var i, _i, _j, _ref, _ref1, _results;\n      this.seriesPoints = [];\n      for (i = _i = _ref = this.options.ykeys.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) {\n        this._drawLineFor(i);\n      }\n      _results = [];\n      for (i = _j = _ref1 = this.options.ykeys.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; i = _ref1 <= 0 ? ++_j : --_j) {\n        _results.push(this._drawPointFor(i));\n      }\n      return _results;\n    };\n\n    Line.prototype._drawPointFor = function(index) {\n      var circle, row, _i, _len, _ref, _results;\n      this.seriesPoints[index] = [];\n      _ref = this.data;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        row = _ref[_i];\n        circle = null;\n        if (row._y[index] != null) {\n          circle = this.drawLinePoint(row._x, row._y[index], this.colorFor(row, index, 'point'), index);\n        }\n        _results.push(this.seriesPoints[index].push(circle));\n      }\n      return _results;\n    };\n\n    Line.prototype._drawLineFor = function(index) {\n      var path;\n      path = this.paths[index];\n      if (path !== null) {\n        return this.drawLinePath(path, this.colorFor(null, index, 'line'), index);\n      }\n    };\n\n    Line.createPath = function(coords, smooth, bottom) {\n      var coord, g, grads, i, ix, lg, path, prevCoord, x1, x2, y1, y2, _i, _len;\n      path = \"\";\n      if (smooth) {\n        grads = Morris.Line.gradients(coords);\n      }\n      prevCoord = {\n        y: null\n      };\n      for (i = _i = 0, _len = coords.length; _i < _len; i = ++_i) {\n        coord = coords[i];\n        if (coord.y != null) {\n          if (prevCoord.y != null) {\n            if (smooth) {\n              g = grads[i];\n              lg = grads[i - 1];\n              ix = (coord.x - prevCoord.x) / 4;\n              x1 = prevCoord.x + ix;\n              y1 = Math.min(bottom, prevCoord.y + ix * lg);\n              x2 = coord.x - ix;\n              y2 = Math.min(bottom, coord.y - ix * g);\n              path += \"C\" + x1 + \",\" + y1 + \",\" + x2 + \",\" + y2 + \",\" + coord.x + \",\" + coord.y;\n            } else {\n              path += \"L\" + coord.x + \",\" + coord.y;\n            }\n          } else {\n            if (!smooth || (grads[i] != null)) {\n              path += \"M\" + coord.x + \",\" + coord.y;\n            }\n          }\n        }\n        prevCoord = coord;\n      }\n      return path;\n    };\n\n    Line.gradients = function(coords) {\n      var coord, grad, i, nextCoord, prevCoord, _i, _len, _results;\n      grad = function(a, b) {\n        return (a.y - b.y) / (a.x - b.x);\n      };\n      _results = [];\n      for (i = _i = 0, _len = coords.length; _i < _len; i = ++_i) {\n        coord = coords[i];\n        if (coord.y != null) {\n          nextCoord = coords[i + 1] || {\n            y: null\n          };\n          prevCoord = coords[i - 1] || {\n            y: null\n          };\n          if ((prevCoord.y != null) && (nextCoord.y != null)) {\n            _results.push(grad(prevCoord, nextCoord));\n          } else if (prevCoord.y != null) {\n            _results.push(grad(prevCoord, coord));\n          } else if (nextCoord.y != null) {\n            _results.push(grad(coord, nextCoord));\n          } else {\n            _results.push(null);\n          }\n        } else {\n          _results.push(null);\n        }\n      }\n      return _results;\n    };\n\n    Line.prototype.hilight = function(index) {\n      var i, _i, _j, _ref, _ref1;\n      if (this.prevHilight !== null && this.prevHilight !== index) {\n        for (i = _i = 0, _ref = this.seriesPoints.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {\n          if (this.seriesPoints[i][this.prevHilight]) {\n            this.seriesPoints[i][this.prevHilight].animate(this.pointShrinkSeries(i));\n          }\n        }\n      }\n      if (index !== null && this.prevHilight !== index) {\n        for (i = _j = 0, _ref1 = this.seriesPoints.length - 1; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = 0 <= _ref1 ? ++_j : --_j) {\n          if (this.seriesPoints[i][index]) {\n            this.seriesPoints[i][index].animate(this.pointGrowSeries(i));\n          }\n        }\n      }\n      return this.prevHilight = index;\n    };\n\n    Line.prototype.colorFor = function(row, sidx, type) {\n      if (typeof this.options.lineColors === 'function') {\n        return this.options.lineColors.call(this, row, sidx, type);\n      } else if (type === 'point') {\n        return this.options.pointFillColors[sidx % this.options.pointFillColors.length] || this.options.lineColors[sidx % this.options.lineColors.length];\n      } else {\n        return this.options.lineColors[sidx % this.options.lineColors.length];\n      }\n    };\n\n    Line.prototype.drawXAxisLabel = function(xPos, yPos, text) {\n      return this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor);\n    };\n\n    Line.prototype.drawLinePath = function(path, lineColor, lineIndex) {\n      return this.raphael.path(path).attr('stroke', lineColor).attr('stroke-width', this.lineWidthForSeries(lineIndex));\n    };\n\n    Line.prototype.drawLinePoint = function(xPos, yPos, pointColor, lineIndex) {\n      return this.raphael.circle(xPos, yPos, this.pointSizeForSeries(lineIndex)).attr('fill', pointColor).attr('stroke-width', this.pointStrokeWidthForSeries(lineIndex)).attr('stroke', this.pointStrokeColorForSeries(lineIndex));\n    };\n\n    Line.prototype.pointStrokeWidthForSeries = function(index) {\n      return this.options.pointStrokeWidths[index % this.options.pointStrokeWidths.length];\n    };\n\n    Line.prototype.pointStrokeColorForSeries = function(index) {\n      return this.options.pointStrokeColors[index % this.options.pointStrokeColors.length];\n    };\n\n    Line.prototype.lineWidthForSeries = function(index) {\n      if (this.options.lineWidth instanceof Array) {\n        return this.options.lineWidth[index % this.options.lineWidth.length];\n      } else {\n        return this.options.lineWidth;\n      }\n    };\n\n    Line.prototype.pointSizeForSeries = function(index) {\n      if (this.options.pointSize instanceof Array) {\n        return this.options.pointSize[index % this.options.pointSize.length];\n      } else {\n        return this.options.pointSize;\n      }\n    };\n\n    Line.prototype.pointGrowSeries = function(index) {\n      return Raphael.animation({\n        r: this.pointSizeForSeries(index) + 3\n      }, 25, 'linear');\n    };\n\n    Line.prototype.pointShrinkSeries = function(index) {\n      return Raphael.animation({\n        r: this.pointSizeForSeries(index)\n      }, 25, 'linear');\n    };\n\n    return Line;\n\n  })(Morris.Grid);\n\n  Morris.labelSeries = function(dmin, dmax, pxwidth, specName, xLabelFormat) {\n    var d, d0, ddensity, name, ret, s, spec, t, _i, _len, _ref;\n    ddensity = 200 * (dmax - dmin) / pxwidth;\n    d0 = new Date(dmin);\n    spec = Morris.LABEL_SPECS[specName];\n    if (spec === void 0) {\n      _ref = Morris.AUTO_LABEL_ORDER;\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        name = _ref[_i];\n        s = Morris.LABEL_SPECS[name];\n        if (ddensity >= s.span) {\n          spec = s;\n          break;\n        }\n      }\n    }\n    if (spec === void 0) {\n      spec = Morris.LABEL_SPECS[\"second\"];\n    }\n    if (xLabelFormat) {\n      spec = $.extend({}, spec, {\n        fmt: xLabelFormat\n      });\n    }\n    d = spec.start(d0);\n    ret = [];\n    while ((t = d.getTime()) <= dmax) {\n      if (t >= dmin) {\n        ret.push([spec.fmt(d), t]);\n      }\n      spec.incr(d);\n    }\n    return ret;\n  };\n\n  minutesSpecHelper = function(interval) {\n    return {\n      span: interval * 60 * 1000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours());\n      },\n      fmt: function(d) {\n        return \"\" + (Morris.pad2(d.getHours())) + \":\" + (Morris.pad2(d.getMinutes()));\n      },\n      incr: function(d) {\n        return d.setUTCMinutes(d.getUTCMinutes() + interval);\n      }\n    };\n  };\n\n  secondsSpecHelper = function(interval) {\n    return {\n      span: interval * 1000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes());\n      },\n      fmt: function(d) {\n        return \"\" + (Morris.pad2(d.getHours())) + \":\" + (Morris.pad2(d.getMinutes())) + \":\" + (Morris.pad2(d.getSeconds()));\n      },\n      incr: function(d) {\n        return d.setUTCSeconds(d.getUTCSeconds() + interval);\n      }\n    };\n  };\n\n  Morris.LABEL_SPECS = {\n    \"decade\": {\n      span: 172800000000,\n      start: function(d) {\n        return new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1);\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear());\n      },\n      incr: function(d) {\n        return d.setFullYear(d.getFullYear() + 10);\n      }\n    },\n    \"year\": {\n      span: 17280000000,\n      start: function(d) {\n        return new Date(d.getFullYear(), 0, 1);\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear());\n      },\n      incr: function(d) {\n        return d.setFullYear(d.getFullYear() + 1);\n      }\n    },\n    \"month\": {\n      span: 2419200000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), 1);\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear()) + \"-\" + (Morris.pad2(d.getMonth() + 1));\n      },\n      incr: function(d) {\n        return d.setMonth(d.getMonth() + 1);\n      }\n    },\n    \"week\": {\n      span: 604800000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear()) + \"-\" + (Morris.pad2(d.getMonth() + 1)) + \"-\" + (Morris.pad2(d.getDate()));\n      },\n      incr: function(d) {\n        return d.setDate(d.getDate() + 7);\n      }\n    },\n    \"day\": {\n      span: 86400000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear()) + \"-\" + (Morris.pad2(d.getMonth() + 1)) + \"-\" + (Morris.pad2(d.getDate()));\n      },\n      incr: function(d) {\n        return d.setDate(d.getDate() + 1);\n      }\n    },\n    \"hour\": minutesSpecHelper(60),\n    \"30min\": minutesSpecHelper(30),\n    \"15min\": minutesSpecHelper(15),\n    \"10min\": minutesSpecHelper(10),\n    \"5min\": minutesSpecHelper(5),\n    \"minute\": minutesSpecHelper(1),\n    \"30sec\": secondsSpecHelper(30),\n    \"15sec\": secondsSpecHelper(15),\n    \"10sec\": secondsSpecHelper(10),\n    \"5sec\": secondsSpecHelper(5),\n    \"second\": secondsSpecHelper(1)\n  };\n\n  Morris.AUTO_LABEL_ORDER = [\"decade\", \"year\", \"month\", \"week\", \"day\", \"hour\", \"30min\", \"15min\", \"10min\", \"5min\", \"minute\", \"30sec\", \"15sec\", \"10sec\", \"5sec\", \"second\"];\n\n  Morris.Area = (function(_super) {\n    var areaDefaults;\n\n    __extends(Area, _super);\n\n    areaDefaults = {\n      fillOpacity: 'auto',\n      behaveLikeLine: false\n    };\n\n    function Area(options) {\n      var areaOptions;\n      if (!(this instanceof Morris.Area)) {\n        return new Morris.Area(options);\n      }\n      areaOptions = $.extend({}, areaDefaults, options);\n      this.cumulative = !areaOptions.behaveLikeLine;\n      if (areaOptions.fillOpacity === 'auto') {\n        areaOptions.fillOpacity = areaOptions.behaveLikeLine ? .8 : 1;\n      }\n      Area.__super__.constructor.call(this, areaOptions);\n    }\n\n    Area.prototype.calcPoints = function() {\n      var row, total, y, _i, _len, _ref, _results;\n      _ref = this.data;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        row = _ref[_i];\n        row._x = this.transX(row.x);\n        total = 0;\n        row._y = (function() {\n          var _j, _len1, _ref1, _results1;\n          _ref1 = row.y;\n          _results1 = [];\n          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n            y = _ref1[_j];\n            if (this.options.behaveLikeLine) {\n              _results1.push(this.transY(y));\n            } else {\n              total += y || 0;\n              _results1.push(this.transY(total));\n            }\n          }\n          return _results1;\n        }).call(this);\n        _results.push(row._ymax = Math.max.apply(Math, row._y));\n      }\n      return _results;\n    };\n\n    Area.prototype.drawSeries = function() {\n      var i, range, _i, _j, _k, _len, _ref, _ref1, _results, _results1, _results2;\n      this.seriesPoints = [];\n      if (this.options.behaveLikeLine) {\n        range = (function() {\n          _results = [];\n          for (var _i = 0, _ref = this.options.ykeys.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); }\n          return _results;\n        }).apply(this);\n      } else {\n        range = (function() {\n          _results1 = [];\n          for (var _j = _ref1 = this.options.ykeys.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; _ref1 <= 0 ? _j++ : _j--){ _results1.push(_j); }\n          return _results1;\n        }).apply(this);\n      }\n      _results2 = [];\n      for (_k = 0, _len = range.length; _k < _len; _k++) {\n        i = range[_k];\n        this._drawFillFor(i);\n        this._drawLineFor(i);\n        _results2.push(this._drawPointFor(i));\n      }\n      return _results2;\n    };\n\n    Area.prototype._drawFillFor = function(index) {\n      var path;\n      path = this.paths[index];\n      if (path !== null) {\n        path = path + (\"L\" + (this.transX(this.xmax)) + \",\" + this.bottom + \"L\" + (this.transX(this.xmin)) + \",\" + this.bottom + \"Z\");\n        return this.drawFilledPath(path, this.fillForSeries(index));\n      }\n    };\n\n    Area.prototype.fillForSeries = function(i) {\n      var color;\n      color = Raphael.rgb2hsl(this.colorFor(this.data[i], i, 'line'));\n      return Raphael.hsl(color.h, this.options.behaveLikeLine ? color.s * 0.9 : color.s * 0.75, Math.min(0.98, this.options.behaveLikeLine ? color.l * 1.2 : color.l * 1.25));\n    };\n\n    Area.prototype.drawFilledPath = function(path, fill) {\n      return this.raphael.path(path).attr('fill', fill).attr('fill-opacity', this.options.fillOpacity).attr('stroke', 'none');\n    };\n\n    return Area;\n\n  })(Morris.Line);\n\n  Morris.Bar = (function(_super) {\n    __extends(Bar, _super);\n\n    function Bar(options) {\n      this.onHoverOut = __bind(this.onHoverOut, this);\n      this.onHoverMove = __bind(this.onHoverMove, this);\n      this.onGridClick = __bind(this.onGridClick, this);\n      if (!(this instanceof Morris.Bar)) {\n        return new Morris.Bar(options);\n      }\n      Bar.__super__.constructor.call(this, $.extend({}, options, {\n        parseTime: false\n      }));\n    }\n\n    Bar.prototype.init = function() {\n      this.cumulative = this.options.stacked;\n      if (this.options.hideHover !== 'always') {\n        this.hover = new Morris.Hover({\n          parent: this.el\n        });\n        this.on('hovermove', this.onHoverMove);\n        this.on('hoverout', this.onHoverOut);\n        return this.on('gridclick', this.onGridClick);\n      }\n    };\n\n    Bar.prototype.defaults = {\n      barSizeRatio: 0.75,\n      barGap: 3,\n      barColors: ['#0b62a4', '#7a92a3', '#4da74d', '#afd8f8', '#edc240', '#cb4b4b', '#9440ed'],\n      barOpacity: 1.0,\n      barRadius: [0, 0, 0, 0],\n      xLabelMargin: 50\n    };\n\n    Bar.prototype.calc = function() {\n      var _ref;\n      this.calcBars();\n      if (this.options.hideHover === false) {\n        return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(this.data.length - 1));\n      }\n    };\n\n    Bar.prototype.calcBars = function() {\n      var idx, row, y, _i, _len, _ref, _results;\n      _ref = this.data;\n      _results = [];\n      for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {\n        row = _ref[idx];\n        row._x = this.left + this.width * (idx + 0.5) / this.data.length;\n        _results.push(row._y = (function() {\n          var _j, _len1, _ref1, _results1;\n          _ref1 = row.y;\n          _results1 = [];\n          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n            y = _ref1[_j];\n            if (y != null) {\n              _results1.push(this.transY(y));\n            } else {\n              _results1.push(null);\n            }\n          }\n          return _results1;\n        }).call(this));\n      }\n      return _results;\n    };\n\n    Bar.prototype.draw = function() {\n      var _ref;\n      if ((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'x') {\n        this.drawXAxis();\n      }\n      return this.drawSeries();\n    };\n\n    Bar.prototype.drawXAxis = function() {\n      var i, label, labelBox, margin, offset, prevAngleMargin, prevLabelMargin, row, textBox, ypos, _i, _ref, _results;\n      ypos = this.bottom + (this.options.xAxisLabelTopPadding || this.options.padding / 2);\n      prevLabelMargin = null;\n      prevAngleMargin = null;\n      _results = [];\n      for (i = _i = 0, _ref = this.data.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n        row = this.data[this.data.length - 1 - i];\n        label = this.drawXAxisLabel(row._x, ypos, row.label);\n        textBox = label.getBBox();\n        label.transform(\"r\" + (-this.options.xLabelAngle));\n        labelBox = label.getBBox();\n        label.transform(\"t0,\" + (labelBox.height / 2) + \"...\");\n        if (this.options.xLabelAngle !== 0) {\n          offset = -0.5 * textBox.width * Math.cos(this.options.xLabelAngle * Math.PI / 180.0);\n          label.transform(\"t\" + offset + \",0...\");\n        }\n        if (((prevLabelMargin == null) || prevLabelMargin >= labelBox.x + labelBox.width || (prevAngleMargin != null) && prevAngleMargin >= labelBox.x) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < this.el.width()) {\n          if (this.options.xLabelAngle !== 0) {\n            margin = 1.25 * this.options.gridTextSize / Math.sin(this.options.xLabelAngle * Math.PI / 180.0);\n            prevAngleMargin = labelBox.x - margin;\n          }\n          _results.push(prevLabelMargin = labelBox.x - this.options.xLabelMargin);\n        } else {\n          _results.push(label.remove());\n        }\n      }\n      return _results;\n    };\n\n    Bar.prototype.drawSeries = function() {\n      var barWidth, bottom, groupWidth, idx, lastTop, left, leftPadding, numBars, row, sidx, size, spaceLeft, top, ypos, zeroPos;\n      groupWidth = this.width / this.options.data.length;\n      numBars = this.options.stacked ? 1 : this.options.ykeys.length;\n      barWidth = (groupWidth * this.options.barSizeRatio - this.options.barGap * (numBars - 1)) / numBars;\n      if (this.options.barSize) {\n        barWidth = Math.min(barWidth, this.options.barSize);\n      }\n      spaceLeft = groupWidth - barWidth * numBars - this.options.barGap * (numBars - 1);\n      leftPadding = spaceLeft / 2;\n      zeroPos = this.ymin <= 0 && this.ymax >= 0 ? this.transY(0) : null;\n      return this.bars = (function() {\n        var _i, _len, _ref, _results;\n        _ref = this.data;\n        _results = [];\n        for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {\n          row = _ref[idx];\n          lastTop = 0;\n          _results.push((function() {\n            var _j, _len1, _ref1, _results1;\n            _ref1 = row._y;\n            _results1 = [];\n            for (sidx = _j = 0, _len1 = _ref1.length; _j < _len1; sidx = ++_j) {\n              ypos = _ref1[sidx];\n              if (ypos !== null) {\n                if (zeroPos) {\n                  top = Math.min(ypos, zeroPos);\n                  bottom = Math.max(ypos, zeroPos);\n                } else {\n                  top = ypos;\n                  bottom = this.bottom;\n                }\n                left = this.left + idx * groupWidth + leftPadding;\n                if (!this.options.stacked) {\n                  left += sidx * (barWidth + this.options.barGap);\n                }\n                size = bottom - top;\n                if (this.options.verticalGridCondition && this.options.verticalGridCondition(row.x)) {\n                  this.drawBar(this.left + idx * groupWidth, this.top, groupWidth, Math.abs(this.top - this.bottom), this.options.verticalGridColor, this.options.verticalGridOpacity, this.options.barRadius);\n                }\n                if (this.options.stacked) {\n                  top -= lastTop;\n                }\n                this.drawBar(left, top, barWidth, size, this.colorFor(row, sidx, 'bar'), this.options.barOpacity, this.options.barRadius);\n                _results1.push(lastTop += size);\n              } else {\n                _results1.push(null);\n              }\n            }\n            return _results1;\n          }).call(this));\n        }\n        return _results;\n      }).call(this);\n    };\n\n    Bar.prototype.colorFor = function(row, sidx, type) {\n      var r, s;\n      if (typeof this.options.barColors === 'function') {\n        r = {\n          x: row.x,\n          y: row.y[sidx],\n          label: row.label\n        };\n        s = {\n          index: sidx,\n          key: this.options.ykeys[sidx],\n          label: this.options.labels[sidx]\n        };\n        return this.options.barColors.call(this, r, s, type);\n      } else {\n        return this.options.barColors[sidx % this.options.barColors.length];\n      }\n    };\n\n    Bar.prototype.hitTest = function(x) {\n      if (this.data.length === 0) {\n        return null;\n      }\n      x = Math.max(Math.min(x, this.right), this.left);\n      return Math.min(this.data.length - 1, Math.floor((x - this.left) / (this.width / this.data.length)));\n    };\n\n    Bar.prototype.onGridClick = function(x, y) {\n      var index;\n      index = this.hitTest(x);\n      return this.fire('click', index, this.data[index].src, x, y);\n    };\n\n    Bar.prototype.onHoverMove = function(x, y) {\n      var index, _ref;\n      index = this.hitTest(x);\n      return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index));\n    };\n\n    Bar.prototype.onHoverOut = function() {\n      if (this.options.hideHover !== false) {\n        return this.hover.hide();\n      }\n    };\n\n    Bar.prototype.hoverContentForRow = function(index) {\n      var content, j, row, x, y, _i, _len, _ref;\n      row = this.data[index];\n      content = \"<div class='morris-hover-row-label'>\" + row.label + \"</div>\";\n      _ref = row.y;\n      for (j = _i = 0, _len = _ref.length; _i < _len; j = ++_i) {\n        y = _ref[j];\n        content += \"<div class='morris-hover-point' style='color: \" + (this.colorFor(row, j, 'label')) + \"'>\\n  \" + this.options.labels[j] + \":\\n  \" + (this.yLabelFormat(y)) + \"\\n</div>\";\n      }\n      if (typeof this.options.hoverCallback === 'function') {\n        content = this.options.hoverCallback(index, this.options, content, row.src);\n      }\n      x = this.left + (index + 0.5) * this.width / this.data.length;\n      return [content, x];\n    };\n\n    Bar.prototype.drawXAxisLabel = function(xPos, yPos, text) {\n      var label;\n      return label = this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor);\n    };\n\n    Bar.prototype.drawBar = function(xPos, yPos, width, height, barColor, opacity, radiusArray) {\n      var maxRadius, path;\n      maxRadius = Math.max.apply(Math, radiusArray);\n      if (maxRadius === 0 || maxRadius > height) {\n        path = this.raphael.rect(xPos, yPos, width, height);\n      } else {\n        path = this.raphael.path(this.roundedRect(xPos, yPos, width, height, radiusArray));\n      }\n      return path.attr('fill', barColor).attr('fill-opacity', opacity).attr('stroke', 'none');\n    };\n\n    Bar.prototype.roundedRect = function(x, y, w, h, r) {\n      if (r == null) {\n        r = [0, 0, 0, 0];\n      }\n      return [\"M\", x, r[0] + y, \"Q\", x, y, x + r[0], y, \"L\", x + w - r[1], y, \"Q\", x + w, y, x + w, y + r[1], \"L\", x + w, y + h - r[2], \"Q\", x + w, y + h, x + w - r[2], y + h, \"L\", x + r[3], y + h, \"Q\", x, y + h, x, y + h - r[3], \"Z\"];\n    };\n\n    return Bar;\n\n  })(Morris.Grid);\n\n  Morris.Donut = (function(_super) {\n    __extends(Donut, _super);\n\n    Donut.prototype.defaults = {\n      colors: ['#0B62A4', '#3980B5', '#679DC6', '#95BBD7', '#B0CCE1', '#095791', '#095085', '#083E67', '#052C48', '#042135'],\n      backgroundColor: '#FFFFFF',\n      labelColor: '#000000',\n      formatter: Morris.commas,\n      resize: false\n    };\n\n    function Donut(options) {\n      this.resizeHandler = __bind(this.resizeHandler, this);\n      this.select = __bind(this.select, this);\n      this.click = __bind(this.click, this);\n      var _this = this;\n      if (!(this instanceof Morris.Donut)) {\n        return new Morris.Donut(options);\n      }\n      this.options = $.extend({}, this.defaults, options);\n      if (typeof options.element === 'string') {\n        this.el = $(document.getElementById(options.element));\n      } else {\n        this.el = $(options.element);\n      }\n      if (this.el === null || this.el.length === 0) {\n        throw new Error(\"Graph placeholder not found.\");\n      }\n      if (options.data === void 0 || options.data.length === 0) {\n        return;\n      }\n      this.raphael = new Raphael(this.el[0]);\n      if (this.options.resize) {\n        $(window).bind('resize', function(evt) {\n          if (_this.timeoutId != null) {\n            window.clearTimeout(_this.timeoutId);\n          }\n          return _this.timeoutId = window.setTimeout(_this.resizeHandler, 100);\n        });\n      }\n      this.setData(options.data);\n    }\n\n    Donut.prototype.redraw = function() {\n      var C, cx, cy, i, idx, last, max_value, min, next, seg, total, value, w, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results;\n      this.raphael.clear();\n      cx = this.el.width() / 2;\n      cy = this.el.height() / 2;\n      w = (Math.min(cx, cy) - 10) / 3;\n      total = 0;\n      _ref = this.values;\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        value = _ref[_i];\n        total += value;\n      }\n      min = 5 / (2 * w);\n      C = 1.9999 * Math.PI - min * this.data.length;\n      last = 0;\n      idx = 0;\n      this.segments = [];\n      _ref1 = this.values;\n      for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {\n        value = _ref1[i];\n        next = last + min + C * (value / total);\n        seg = new Morris.DonutSegment(cx, cy, w * 2, w, last, next, this.data[i].color || this.options.colors[idx % this.options.colors.length], this.options.backgroundColor, idx, this.raphael);\n        seg.render();\n        this.segments.push(seg);\n        seg.on('hover', this.select);\n        seg.on('click', this.click);\n        last = next;\n        idx += 1;\n      }\n      this.text1 = this.drawEmptyDonutLabel(cx, cy - 10, this.options.labelColor, 15, 800);\n      this.text2 = this.drawEmptyDonutLabel(cx, cy + 10, this.options.labelColor, 14);\n      max_value = Math.max.apply(Math, this.values);\n      idx = 0;\n      _ref2 = this.values;\n      _results = [];\n      for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {\n        value = _ref2[_k];\n        if (value === max_value) {\n          this.select(idx);\n          break;\n        }\n        _results.push(idx += 1);\n      }\n      return _results;\n    };\n\n    Donut.prototype.setData = function(data) {\n      var row;\n      this.data = data;\n      this.values = (function() {\n        var _i, _len, _ref, _results;\n        _ref = this.data;\n        _results = [];\n        for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n          row = _ref[_i];\n          _results.push(parseFloat(row.value));\n        }\n        return _results;\n      }).call(this);\n      return this.redraw();\n    };\n\n    Donut.prototype.click = function(idx) {\n      return this.fire('click', idx, this.data[idx]);\n    };\n\n    Donut.prototype.select = function(idx) {\n      var row, s, segment, _i, _len, _ref;\n      _ref = this.segments;\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        s = _ref[_i];\n        s.deselect();\n      }\n      segment = this.segments[idx];\n      segment.select();\n      row = this.data[idx];\n      return this.setLabels(row.label, this.options.formatter(row.value, row));\n    };\n\n    Donut.prototype.setLabels = function(label1, label2) {\n      var inner, maxHeightBottom, maxHeightTop, maxWidth, text1bbox, text1scale, text2bbox, text2scale;\n      inner = (Math.min(this.el.width() / 2, this.el.height() / 2) - 10) * 2 / 3;\n      maxWidth = 1.8 * inner;\n      maxHeightTop = inner / 2;\n      maxHeightBottom = inner / 3;\n      this.text1.attr({\n        text: label1,\n        transform: ''\n      });\n      text1bbox = this.text1.getBBox();\n      text1scale = Math.min(maxWidth / text1bbox.width, maxHeightTop / text1bbox.height);\n      this.text1.attr({\n        transform: \"S\" + text1scale + \",\" + text1scale + \",\" + (text1bbox.x + text1bbox.width / 2) + \",\" + (text1bbox.y + text1bbox.height)\n      });\n      this.text2.attr({\n        text: label2,\n        transform: ''\n      });\n      text2bbox = this.text2.getBBox();\n      text2scale = Math.min(maxWidth / text2bbox.width, maxHeightBottom / text2bbox.height);\n      return this.text2.attr({\n        transform: \"S\" + text2scale + \",\" + text2scale + \",\" + (text2bbox.x + text2bbox.width / 2) + \",\" + text2bbox.y\n      });\n    };\n\n    Donut.prototype.drawEmptyDonutLabel = function(xPos, yPos, color, fontSize, fontWeight) {\n      var text;\n      text = this.raphael.text(xPos, yPos, '').attr('font-size', fontSize).attr('fill', color);\n      if (fontWeight != null) {\n        text.attr('font-weight', fontWeight);\n      }\n      return text;\n    };\n\n    Donut.prototype.resizeHandler = function() {\n      this.timeoutId = null;\n      this.raphael.setSize(this.el.width(), this.el.height());\n      return this.redraw();\n    };\n\n    return Donut;\n\n  })(Morris.EventEmitter);\n\n  Morris.DonutSegment = (function(_super) {\n    __extends(DonutSegment, _super);\n\n    function DonutSegment(cx, cy, inner, outer, p0, p1, color, backgroundColor, index, raphael) {\n      this.cx = cx;\n      this.cy = cy;\n      this.inner = inner;\n      this.outer = outer;\n      this.color = color;\n      this.backgroundColor = backgroundColor;\n      this.index = index;\n      this.raphael = raphael;\n      this.deselect = __bind(this.deselect, this);\n      this.select = __bind(this.select, this);\n      this.sin_p0 = Math.sin(p0);\n      this.cos_p0 = Math.cos(p0);\n      this.sin_p1 = Math.sin(p1);\n      this.cos_p1 = Math.cos(p1);\n      this.is_long = (p1 - p0) > Math.PI ? 1 : 0;\n      this.path = this.calcSegment(this.inner + 3, this.inner + this.outer - 5);\n      this.selectedPath = this.calcSegment(this.inner + 3, this.inner + this.outer);\n      this.hilight = this.calcArc(this.inner);\n    }\n\n    DonutSegment.prototype.calcArcPoints = function(r) {\n      return [this.cx + r * this.sin_p0, this.cy + r * this.cos_p0, this.cx + r * this.sin_p1, this.cy + r * this.cos_p1];\n    };\n\n    DonutSegment.prototype.calcSegment = function(r1, r2) {\n      var ix0, ix1, iy0, iy1, ox0, ox1, oy0, oy1, _ref, _ref1;\n      _ref = this.calcArcPoints(r1), ix0 = _ref[0], iy0 = _ref[1], ix1 = _ref[2], iy1 = _ref[3];\n      _ref1 = this.calcArcPoints(r2), ox0 = _ref1[0], oy0 = _ref1[1], ox1 = _ref1[2], oy1 = _ref1[3];\n      return (\"M\" + ix0 + \",\" + iy0) + (\"A\" + r1 + \",\" + r1 + \",0,\" + this.is_long + \",0,\" + ix1 + \",\" + iy1) + (\"L\" + ox1 + \",\" + oy1) + (\"A\" + r2 + \",\" + r2 + \",0,\" + this.is_long + \",1,\" + ox0 + \",\" + oy0) + \"Z\";\n    };\n\n    DonutSegment.prototype.calcArc = function(r) {\n      var ix0, ix1, iy0, iy1, _ref;\n      _ref = this.calcArcPoints(r), ix0 = _ref[0], iy0 = _ref[1], ix1 = _ref[2], iy1 = _ref[3];\n      return (\"M\" + ix0 + \",\" + iy0) + (\"A\" + r + \",\" + r + \",0,\" + this.is_long + \",0,\" + ix1 + \",\" + iy1);\n    };\n\n    DonutSegment.prototype.render = function() {\n      var _this = this;\n      this.arc = this.drawDonutArc(this.hilight, this.color);\n      return this.seg = this.drawDonutSegment(this.path, this.color, this.backgroundColor, function() {\n        return _this.fire('hover', _this.index);\n      }, function() {\n        return _this.fire('click', _this.index);\n      });\n    };\n\n    DonutSegment.prototype.drawDonutArc = function(path, color) {\n      return this.raphael.path(path).attr({\n        stroke: color,\n        'stroke-width': 2,\n        opacity: 0\n      });\n    };\n\n    DonutSegment.prototype.drawDonutSegment = function(path, fillColor, strokeColor, hoverFunction, clickFunction) {\n      return this.raphael.path(path).attr({\n        fill: fillColor,\n        stroke: strokeColor,\n        'stroke-width': 3\n      }).hover(hoverFunction).click(clickFunction);\n    };\n\n    DonutSegment.prototype.select = function() {\n      if (!this.selected) {\n        this.seg.animate({\n          path: this.selectedPath\n        }, 150, '<>');\n        this.arc.animate({\n          opacity: 1\n        }, 150, '<>');\n        return this.selected = true;\n      }\n    };\n\n    DonutSegment.prototype.deselect = function() {\n      if (this.selected) {\n        this.seg.animate({\n          path: this.path\n        }, 150, '<>');\n        this.arc.animate({\n          opacity: 0\n        }, 150, '<>');\n        return this.selected = false;\n      }\n    };\n\n    return DonutSegment;\n\n  })(Morris.EventEmitter);\n\n}).call(this);\n"
  },
  {
    "path": "static/assets/plugins/multiselect/css/multi-select.css",
    "content": ".ms-container{\n  background: transparent url('../img/switch.png') no-repeat 50% 50%;\n  width: 370px;\n}\n\n.ms-container:after{\n  content: \".\";\n  display: block;\n  height: 0;\n  line-height: 0;\n  font-size: 0;\n  clear: both;\n  min-height: 0;\n  visibility: hidden;\n}\n\n.ms-container .ms-selectable, .ms-container .ms-selection{\n  background: #fff;\n  color: #555555;\n  float: left;\n  width: 45%;\n}\n.ms-container .ms-selection{\n  float: right;\n}\n\n.ms-container .ms-list{\n  -webkit-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  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;\n  -moz-transition: border linear 0.2s, box-shadow linear 0.2s;\n  -ms-transition: border linear 0.2s, box-shadow linear 0.2s;\n  -o-transition: border linear 0.2s, box-shadow linear 0.2s;\n  transition: border linear 0.2s, box-shadow linear 0.2s;\n  border: 1px solid #ccc;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n  position: relative;\n  height: 200px;\n  padding: 0;\n  overflow-y: auto;\n}\n\n.ms-container .ms-list.ms-focus{\n  border-color: rgba(82, 168, 236, 0.8);\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);\n  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);\n  outline: 0;\n  outline: thin dotted \\9;\n}\n\n.ms-container ul{\n  margin: 0;\n  list-style-type: none;\n  padding: 0;\n}\n\n.ms-container .ms-optgroup-container{\n  width: 100%;\n}\n\n.ms-container .ms-optgroup-label{\n  margin: 0;\n  padding: 5px 0px 0px 5px;\n  cursor: pointer;\n  color: #999;\n}\n\n.ms-container .ms-selectable li.ms-elem-selectable,\n.ms-container .ms-selection li.ms-elem-selection{\n  border-bottom: 1px #eee solid;\n  padding: 2px 10px;\n  color: #555;\n  font-size: 14px;\n}\n\n.ms-container .ms-selectable li.ms-hover,\n.ms-container .ms-selection li.ms-hover{\n  cursor: pointer;\n  color: #fff;\n  text-decoration: none;\n  background-color: #08c;\n}\n\n.ms-container .ms-selectable li.disabled,\n.ms-container .ms-selection li.disabled{\n  background-color: #eee;\n  color: #aaa;\n  cursor: text;\n}"
  },
  {
    "path": "static/assets/plugins/multiselect/js/jquery.multi-select.js",
    "content": "/*\n* MultiSelect v0.9.12\n* Copyright (c) 2012 Louis Cuny\n*\n* This program is free software. It comes without any warranty, to\n* the extent permitted by applicable law. You can redistribute it\n* and/or modify it under the terms of the Do What The Fuck You Want\n* To Public License, Version 2, as published by Sam Hocevar. See\n* http://sam.zoy.org/wtfpl/COPYING for more details.\n*/\n\n!function ($) {\n\n  \"use strict\";\n\n\n /* MULTISELECT CLASS DEFINITION\n  * ====================== */\n\n  var MultiSelect = function (element, options) {\n    this.options = options;\n    this.$element = $(element);\n    this.$container = $('<div/>', { 'class': \"ms-container\" });\n    this.$selectableContainer = $('<div/>', { 'class': 'ms-selectable' });\n    this.$selectionContainer = $('<div/>', { 'class': 'ms-selection' });\n    this.$selectableUl = $('<ul/>', { 'class': \"ms-list\", 'tabindex' : '-1' });\n    this.$selectionUl = $('<ul/>', { 'class': \"ms-list\", 'tabindex' : '-1' });\n    this.scrollTo = 0;\n    this.elemsSelector = 'li:visible:not(.ms-optgroup-label,.ms-optgroup-container,.'+options.disabledClass+')';\n  };\n\n  MultiSelect.prototype = {\n    constructor: MultiSelect,\n\n    init: function(){\n      var that = this,\n          ms = this.$element;\n\n      if (ms.next('.ms-container').length === 0){\n        ms.css({ position: 'absolute', left: '-9999px' });\n        ms.attr('id', ms.attr('id') ? ms.attr('id') : Math.ceil(Math.random()*1000)+'multiselect');\n        this.$container.attr('id', 'ms-'+ms.attr('id'));\n        this.$container.addClass(that.options.cssClass);\n        ms.find('option').each(function(){\n          that.generateLisFromOption(this);\n        });\n\n        this.$selectionUl.find('.ms-optgroup-label').hide();\n\n        if (that.options.selectableHeader){\n          that.$selectableContainer.append(that.options.selectableHeader);\n        }\n        that.$selectableContainer.append(that.$selectableUl);\n        if (that.options.selectableFooter){\n          that.$selectableContainer.append(that.options.selectableFooter);\n        }\n\n        if (that.options.selectionHeader){\n          that.$selectionContainer.append(that.options.selectionHeader);\n        }\n        that.$selectionContainer.append(that.$selectionUl);\n        if (that.options.selectionFooter){\n          that.$selectionContainer.append(that.options.selectionFooter);\n        }\n\n        that.$container.append(that.$selectableContainer);\n        that.$container.append(that.$selectionContainer);\n        ms.after(that.$container);\n\n        that.activeMouse(that.$selectableUl);\n        that.activeKeyboard(that.$selectableUl);\n\n        var action = that.options.dblClick ? 'dblclick' : 'click';\n\n        that.$selectableUl.on(action, '.ms-elem-selectable', function(){\n          that.select($(this).data('ms-value'));\n        });\n        that.$selectionUl.on(action, '.ms-elem-selection', function(){\n          that.deselect($(this).data('ms-value'));\n        });\n\n        that.activeMouse(that.$selectionUl);\n        that.activeKeyboard(that.$selectionUl);\n\n        ms.on('focus', function(){\n          that.$selectableUl.focus();\n        })\n      }\n\n      var selectedValues = ms.find('option:selected').map(function(){ return $(this).val(); }).get();\n      that.select(selectedValues, 'init');\n\n      if (typeof that.options.afterInit === 'function') {\n        that.options.afterInit.call(this, this.$container);\n      }\n    },\n\n    'generateLisFromOption' : function(option, index, $container){\n      var that = this,\n          ms = that.$element,\n          attributes = \"\",\n          $option = $(option);\n\n      for (var cpt = 0; cpt < option.attributes.length; cpt++){\n        var attr = option.attributes[cpt];\n\n        if(attr.name !== 'value' && attr.name !== 'disabled'){\n          attributes += attr.name+'=\"'+attr.value+'\" ';\n        }\n      }\n      var selectableLi = $('<li '+attributes+'><span>'+that.escapeHTML($option.text())+'</span></li>'),\n          selectedLi = selectableLi.clone(),\n          value = $option.val(),\n          elementId = that.sanitize(value);\n\n      selectableLi\n        .data('ms-value', value)\n        .addClass('ms-elem-selectable')\n        .attr('id', elementId+'-selectable');\n\n      selectedLi\n        .data('ms-value', value)\n        .addClass('ms-elem-selection')\n        .attr('id', elementId+'-selection')\n        .hide();\n\n      if ($option.prop('disabled') || ms.prop('disabled')){\n        selectedLi.addClass(that.options.disabledClass);\n        selectableLi.addClass(that.options.disabledClass);\n      }\n\n      var $optgroup = $option.parent('optgroup');\n\n      if ($optgroup.length > 0){\n        var optgroupLabel = $optgroup.attr('label'),\n            optgroupId = that.sanitize(optgroupLabel),\n            $selectableOptgroup = that.$selectableUl.find('#optgroup-selectable-'+optgroupId),\n            $selectionOptgroup = that.$selectionUl.find('#optgroup-selection-'+optgroupId);\n\n        if ($selectableOptgroup.length === 0){\n          var optgroupContainerTpl = '<li class=\"ms-optgroup-container\"></li>',\n              optgroupTpl = '<ul class=\"ms-optgroup\"><li class=\"ms-optgroup-label\"><span>'+optgroupLabel+'</span></li></ul>';\n\n          $selectableOptgroup = $(optgroupContainerTpl);\n          $selectionOptgroup = $(optgroupContainerTpl);\n          $selectableOptgroup.attr('id', 'optgroup-selectable-'+optgroupId);\n          $selectionOptgroup.attr('id', 'optgroup-selection-'+optgroupId);\n          $selectableOptgroup.append($(optgroupTpl));\n          $selectionOptgroup.append($(optgroupTpl));\n          if (that.options.selectableOptgroup){\n            $selectableOptgroup.find('.ms-optgroup-label').on('click', function(){\n              var values = $optgroup.children(':not(:selected, :disabled)').map(function(){ return $(this).val() }).get();\n              that.select(values);\n            });\n            $selectionOptgroup.find('.ms-optgroup-label').on('click', function(){\n              var values = $optgroup.children(':selected:not(:disabled)').map(function(){ return $(this).val() }).get();\n              that.deselect(values);\n            });\n          }\n          that.$selectableUl.append($selectableOptgroup);\n          that.$selectionUl.append($selectionOptgroup);\n        }\n        index = index == undefined ? $selectableOptgroup.find('ul').children().length : index + 1;\n        selectableLi.insertAt(index, $selectableOptgroup.children());\n        selectedLi.insertAt(index, $selectionOptgroup.children());\n      } else {\n        index = index == undefined ? that.$selectableUl.children().length : index;\n\n        selectableLi.insertAt(index, that.$selectableUl);\n        selectedLi.insertAt(index, that.$selectionUl);\n      }\n    },\n\n    'addOption' : function(options){\n      var that = this;\n\n      if (options.value) options = [options];\n      $.each(options, function(index, option){\n        if (option.value && that.$element.find(\"option[value='\"+option.value+\"']\").length === 0){\n          var $option = $('<option value=\"'+option.value+'\">'+option.text+'</option>'),\n              index = parseInt((typeof option.index === 'undefined' ? that.$element.children().length : option.index)),\n              $container = option.nested == undefined ? that.$element : $(\"optgroup[label='\"+option.nested+\"']\")\n\n          $option.insertAt(index, $container);\n          that.generateLisFromOption($option.get(0), index, option.nested);\n        }\n      })\n    },\n\n    'escapeHTML' : function(text){\n      return $(\"<div>\").text(text).html();\n    },\n\n    'activeKeyboard' : function($list){\n      var that = this;\n\n      $list.on('focus', function(){\n        $(this).addClass('ms-focus');\n      })\n      .on('blur', function(){\n        $(this).removeClass('ms-focus');\n      })\n      .on('keydown', function(e){\n        switch (e.which) {\n          case 40:\n          case 38:\n            e.preventDefault();\n            e.stopPropagation();\n            that.moveHighlight($(this), (e.which === 38) ? -1 : 1);\n            return;\n          case 37:\n          case 39:\n            e.preventDefault();\n            e.stopPropagation();\n            that.switchList($list);\n            return;\n          case 9:\n            if(that.$element.is('[tabindex]')){\n              e.preventDefault();\n              var tabindex = parseInt(that.$element.attr('tabindex'), 10);\n              tabindex = (e.shiftKey) ? tabindex-1 : tabindex+1;\n              $('[tabindex=\"'+(tabindex)+'\"]').focus();\n              return;\n            }else{\n              if(e.shiftKey){\n                that.$element.trigger('focus');\n              }\n            }\n        }\n        if($.inArray(e.which, that.options.keySelect) > -1){\n          e.preventDefault();\n          e.stopPropagation();\n          that.selectHighlighted($list);\n          return;\n        }\n      });\n    },\n\n    'moveHighlight': function($list, direction){\n      var $elems = $list.find(this.elemsSelector),\n          $currElem = $elems.filter('.ms-hover'),\n          $nextElem = null,\n          elemHeight = $elems.first().outerHeight(),\n          containerHeight = $list.height(),\n          containerSelector = '#'+this.$container.prop('id');\n\n      $elems.removeClass('ms-hover');\n      if (direction === 1){ // DOWN\n\n        $nextElem = $currElem.nextAll(this.elemsSelector).first();\n        if ($nextElem.length === 0){\n          var $optgroupUl = $currElem.parent();\n\n          if ($optgroupUl.hasClass('ms-optgroup')){\n            var $optgroupLi = $optgroupUl.parent(),\n                $nextOptgroupLi = $optgroupLi.next(':visible');\n\n            if ($nextOptgroupLi.length > 0){\n              $nextElem = $nextOptgroupLi.find(this.elemsSelector).first();\n            } else {\n              $nextElem = $elems.first();\n            }\n          } else {\n            $nextElem = $elems.first();\n          }\n        }\n      } else if (direction === -1){ // UP\n\n        $nextElem = $currElem.prevAll(this.elemsSelector).first();\n        if ($nextElem.length === 0){\n          var $optgroupUl = $currElem.parent();\n\n          if ($optgroupUl.hasClass('ms-optgroup')){\n            var $optgroupLi = $optgroupUl.parent(),\n                $prevOptgroupLi = $optgroupLi.prev(':visible');\n\n            if ($prevOptgroupLi.length > 0){\n              $nextElem = $prevOptgroupLi.find(this.elemsSelector).last();\n            } else {\n              $nextElem = $elems.last();\n            }\n          } else {\n            $nextElem = $elems.last();\n          }\n        }\n      }\n      if ($nextElem.length > 0){\n        $nextElem.addClass('ms-hover');\n        var scrollTo = $list.scrollTop() + $nextElem.position().top - \n                       containerHeight / 2 + elemHeight / 2;\n\n        $list.scrollTop(scrollTo);\n      }\n    },\n\n    'selectHighlighted' : function($list){\n      var $elems = $list.find(this.elemsSelector),\n          $highlightedElem = $elems.filter('.ms-hover').first();\n\n      if ($highlightedElem.length > 0){\n        if ($list.parent().hasClass('ms-selectable')){\n          this.select($highlightedElem.data('ms-value'));\n        } else {\n          this.deselect($highlightedElem.data('ms-value'));\n        }\n        $elems.removeClass('ms-hover');\n      }\n    },\n\n    'switchList' : function($list){\n      $list.blur();\n      this.$container.find(this.elemsSelector).removeClass('ms-hover');\n      if ($list.parent().hasClass('ms-selectable')){\n        this.$selectionUl.focus();\n      } else {\n        this.$selectableUl.focus();\n      }\n    },\n\n    'activeMouse' : function($list){\n      var that = this;\n\n      $('body').on('mouseenter', that.elemsSelector, function(){\n        $(this).parents('.ms-container').find(that.elemsSelector).removeClass('ms-hover');\n        $(this).addClass('ms-hover');\n      });\n    },\n\n    'refresh' : function() {\n      this.destroy();\n      this.$element.multiSelect(this.options);\n    },\n\n    'destroy' : function(){\n      $(\"#ms-\"+this.$element.attr(\"id\")).remove();\n      this.$element.css('position', '').css('left', '')\n      this.$element.removeData('multiselect');\n    },\n\n    'select' : function(value, method){\n      if (typeof value === 'string'){ value = [value]; }\n\n      var that = this,\n          ms = this.$element,\n          msIds = $.map(value, function(val){ return(that.sanitize(val)); }),\n          selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable').filter(':not(.'+that.options.disabledClass+')'),\n          selections = this.$selectionUl.find('#' + msIds.join('-selection, #') + '-selection').filter(':not(.'+that.options.disabledClass+')'),\n          options = ms.find('option:not(:disabled)').filter(function(){ return($.inArray(this.value, value) > -1); });\n\n      if (method === 'init'){\n        selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable'),\n        selections = this.$selectionUl.find('#' + msIds.join('-selection, #') + '-selection');\n      }\n\n      if (selectables.length > 0){\n        selectables.addClass('ms-selected').hide();\n        selections.addClass('ms-selected').show();\n\n        options.prop('selected', true);\n\n        that.$container.find(that.elemsSelector).removeClass('ms-hover');\n\n        var selectableOptgroups = that.$selectableUl.children('.ms-optgroup-container');\n        if (selectableOptgroups.length > 0){\n          selectableOptgroups.each(function(){\n            var selectablesLi = $(this).find('.ms-elem-selectable');\n            if (selectablesLi.length === selectablesLi.filter('.ms-selected').length){\n              $(this).find('.ms-optgroup-label').hide();\n            }\n          });\n\n          var selectionOptgroups = that.$selectionUl.children('.ms-optgroup-container');\n          selectionOptgroups.each(function(){\n            var selectionsLi = $(this).find('.ms-elem-selection');\n            if (selectionsLi.filter('.ms-selected').length > 0){\n              $(this).find('.ms-optgroup-label').show();\n            }\n          });\n        } else {\n          if (that.options.keepOrder && method !== 'init'){\n            var selectionLiLast = that.$selectionUl.find('.ms-selected');\n            if((selectionLiLast.length > 1) && (selectionLiLast.last().get(0) != selections.get(0))) {\n              selections.insertAfter(selectionLiLast.last());\n            }\n          }\n        }\n        if (method !== 'init'){\n          ms.trigger('change');\n          if (typeof that.options.afterSelect === 'function') {\n            that.options.afterSelect.call(this, value);\n          }\n        }\n      }\n    },\n\n    'deselect' : function(value){\n      if (typeof value === 'string'){ value = [value]; }\n\n      var that = this,\n          ms = this.$element,\n          msIds = $.map(value, function(val){ return(that.sanitize(val)); }),\n          selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable'),\n          selections = this.$selectionUl.find('#' + msIds.join('-selection, #')+'-selection').filter('.ms-selected').filter(':not(.'+that.options.disabledClass+')'),\n          options = ms.find('option').filter(function(){ return($.inArray(this.value, value) > -1); });\n\n      if (selections.length > 0){\n        selectables.removeClass('ms-selected').show();\n        selections.removeClass('ms-selected').hide();\n        options.prop('selected', false);\n\n        that.$container.find(that.elemsSelector).removeClass('ms-hover');\n\n        var selectableOptgroups = that.$selectableUl.children('.ms-optgroup-container');\n        if (selectableOptgroups.length > 0){\n          selectableOptgroups.each(function(){\n            var selectablesLi = $(this).find('.ms-elem-selectable');\n            if (selectablesLi.filter(':not(.ms-selected)').length > 0){\n              $(this).find('.ms-optgroup-label').show();\n            }\n          });\n\n          var selectionOptgroups = that.$selectionUl.children('.ms-optgroup-container');\n          selectionOptgroups.each(function(){\n            var selectionsLi = $(this).find('.ms-elem-selection');\n            if (selectionsLi.filter('.ms-selected').length === 0){\n              $(this).find('.ms-optgroup-label').hide();\n            }\n          });\n        }\n        ms.trigger('change');\n        if (typeof that.options.afterDeselect === 'function') {\n          that.options.afterDeselect.call(this, value);\n        }\n      }\n    },\n\n    'select_all' : function(){\n      var ms = this.$element,\n          values = ms.val();\n\n      ms.find('option:not(\":disabled\")').prop('selected', true);\n      this.$selectableUl.find('.ms-elem-selectable').filter(':not(.'+this.options.disabledClass+')').addClass('ms-selected').hide();\n      this.$selectionUl.find('.ms-optgroup-label').show();\n      this.$selectableUl.find('.ms-optgroup-label').hide();\n      this.$selectionUl.find('.ms-elem-selection').filter(':not(.'+this.options.disabledClass+')').addClass('ms-selected').show();\n      this.$selectionUl.focus();\n      ms.trigger('change');\n      if (typeof this.options.afterSelect === 'function') {\n        var selectedValues = $.grep(ms.val(), function(item){\n          return $.inArray(item, values) < 0;\n        });\n        this.options.afterSelect.call(this, selectedValues);\n      }\n    },\n\n    'deselect_all' : function(){\n      var ms = this.$element,\n          values = ms.val();\n\n      ms.find('option').prop('selected', false);\n      this.$selectableUl.find('.ms-elem-selectable').removeClass('ms-selected').show();\n      this.$selectionUl.find('.ms-optgroup-label').hide();\n      this.$selectableUl.find('.ms-optgroup-label').show();\n      this.$selectionUl.find('.ms-elem-selection').removeClass('ms-selected').hide();\n      this.$selectableUl.focus();\n      ms.trigger('change');\n      if (typeof this.options.afterDeselect === 'function') {\n        this.options.afterDeselect.call(this, values);\n      }\n    },\n\n    sanitize: function(value){\n      var hash = 0, i, character;\n      if (value.length == 0) return hash;\n      var ls = 0;\n      for (i = 0, ls = value.length; i < ls; i++) {\n        character  = value.charCodeAt(i);\n        hash  = ((hash<<5)-hash)+character;\n        hash |= 0; // Convert to 32bit integer\n      }\n      return hash;\n    }\n  };\n\n  /* MULTISELECT PLUGIN DEFINITION\n   * ======================= */\n\n  $.fn.multiSelect = function () {\n    var option = arguments[0],\n        args = arguments;\n\n    return this.each(function () {\n      var $this = $(this),\n          data = $this.data('multiselect'),\n          options = $.extend({}, $.fn.multiSelect.defaults, $this.data(), typeof option === 'object' && option);\n\n      if (!data){ $this.data('multiselect', (data = new MultiSelect(this, options))); }\n\n      if (typeof option === 'string'){\n        data[option](args[1]);\n      } else {\n        data.init();\n      }\n    });\n  };\n\n  $.fn.multiSelect.defaults = {\n    keySelect: [32],\n    selectableOptgroup: false,\n    disabledClass : 'disabled',\n    dblClick : false,\n    keepOrder: false,\n    cssClass: ''\n  };\n\n  $.fn.multiSelect.Constructor = MultiSelect;\n\n  $.fn.insertAt = function(index, $parent) {\n    return this.each(function() {\n      if (index === 0) {\n        $parent.prepend(this);\n      } else {\n        $parent.children().eq(index - 1).after(this);\n      }\n    });\n}\n\n}(window.jQuery);\n"
  },
  {
    "path": "static/assets/plugins/notifications/notification.css",
    "content": ".notifyjs-metro-base {\n\tposition: relative;\n    min-height: 52px;\n    min-width: 250px;\n    color:#444;\n    border-radius: 3px;\n    -webkit-border-radius: 3px;\n    box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.2);\n      -webkit-animation: dropdownOpen 0.3s ease-out;\n  -o-animation: dropdownOpen 0.3s ease-out;\n  animation: dropdownOpen 0.3s ease-out;\n}\n\n.notifyjs-metro-base .image {\n    display: table;\n    position: absolute;\n    height: auto;\n    width: auto;\n    left: 25px;\n    top: 50%;\n    font-size: 24px;\n    -moz-transform: translate(-50%, -50%);\n    -ms-transform: translate(-50%, -50%);\n    -o-transform: translate(-50%, -50%);\n    -webkit-transform: translate(-50%, -50%);\n    transform: translate(-50%, -50%);\n}\n\n.notifyjs-metro-base .text-wrapper {\n    display: inline-block;\n    vertical-align: top;\n    text-align: left;\n    margin: 10px 10px 10px 52px;\n    clear: both;\n\n}\n\n.notifyjs-metro-base .title {\n    font-size: 15px;\n    line-height: 20px;\n    margin-bottom: 5px;\n    font-weight: bold;\n}\n\n.notifyjs-metro-base .text {\n    font-size: 12px;\n    font-weight: normal;\n    max-width: 360px;\n    vertical-align: middle;\n\n}\n.notifyjs-metro-cool {\n    color: #fafafa !important;\n    background-color: #4A525F;\n    border: 1px solid #4A525F;\n}"
  },
  {
    "path": "static/assets/plugins/notifications/notify-metro.js",
    "content": "$.notify.addStyle(\"metro\", {\n    html:\n        \"<div>\" +\n            \"<div class='image' data-notify-html='image'/>\" +\n            \"<div class='text-wrapper'>\" +\n                \"<div class='title' data-notify-html='title'/>\" +\n                \"<div class='text' data-notify-html='text'/>\" +\n            \"</div>\" +\n        \"</div>\",\n    classes: {\n        default: {\n            \"color\": \"#fafafa !important\",\n            \"background-color\": \"#ABB7B7\",\n            \"border\": \"1px solid #ABB7B7\"\n        },\n        error: {\n            \"color\": \"#fafafa !important\",\n            \"background-color\": \"#f05050\",\n            \"border\": \"1px solid #ef5350\"\n        },\n        custom: {\n            \"color\": \"#fafafa !important\",\n            \"background-color\": \"#5fbeaa\",\n            \"border\": \"1px solid #5fbeaa\"\n        },\n        success: {\n            \"color\": \"#fafafa !important\",\n            \"background-color\": \"#81c868\",\n            \"border\": \"1px solid #33b86c\"\n        },\n        info: {\n            \"color\": \"#fafafa !important\",\n            \"background-color\": \"#34d3eb\",\n            \"border\": \"1px solid #29b6f6\"\n        },\n        warning: {\n            \"color\": \"#fafafa !important\",\n            \"background-color\": \"#ffbd4a\",\n            \"border\": \"1px solid #ffd740\"\n        },\n        black: {\n            \"color\": \"#fafafa !important\",\n            \"background-color\": \"#4c5667\",\n            \"border\": \"1px solid #212121\"\n        },\n        white: {\n            \"background-color\": \"#e6eaed\",\n            \"border\": \"1px solid #ddd\"\n        }\n    }\n});"
  },
  {
    "path": "static/assets/plugins/notifyjs/dist/notify-combined.js",
    "content": "/** Notify.js - v0.3.1 - 2014/06/29\n * http://notifyjs.com/\n * Copyright (c) 2014 Jaime Pillora - MIT\n */\n(function(window,document,$,undefined) {\n'use strict';\n\nvar Notification, addStyle, blankFieldName, coreStyle, createElem, defaults, encode, find, findFields, getAnchorElement, getStyle, globalAnchors, hAligns, incr, inherit, insertCSS, mainPositions, opposites, parsePosition, pluginClassName, pluginName, pluginOptions, positions, realign, stylePrefixes, styles, vAligns,\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\npluginName = 'notify';\n\npluginClassName = pluginName + 'js';\n\nblankFieldName = pluginName + \"!blank\";\n\npositions = {\n  t: 'top',\n  m: 'middle',\n  b: 'bottom',\n  l: 'left',\n  c: 'center',\n  r: 'right'\n};\n\nhAligns = ['l', 'c', 'r'];\n\nvAligns = ['t', 'm', 'b'];\n\nmainPositions = ['t', 'b', 'l', 'r'];\n\nopposites = {\n  t: 'b',\n  m: null,\n  b: 't',\n  l: 'r',\n  c: null,\n  r: 'l'\n};\n\nparsePosition = function(str) {\n  var pos;\n  pos = [];\n  $.each(str.split(/\\W+/), function(i, word) {\n    var w;\n    w = word.toLowerCase().charAt(0);\n    if (positions[w]) {\n      return pos.push(w);\n    }\n  });\n  return pos;\n};\n\nstyles = {};\n\ncoreStyle = {\n  name: 'core',\n  html: \"<div class=\\\"\" + pluginClassName + \"-wrapper\\\">\\n  <div class=\\\"\" + pluginClassName + \"-arrow\\\"></div>\\n  <div class=\\\"\" + pluginClassName + \"-container\\\"></div>\\n</div>\",\n  css: \".\" + pluginClassName + \"-corner {\\n  position: fixed;\\n  margin: 5px;\\n  z-index: 1050;\\n}\\n\\n.\" + pluginClassName + \"-corner .\" + pluginClassName + \"-wrapper,\\n.\" + pluginClassName + \"-corner .\" + pluginClassName + \"-container {\\n  position: relative;\\n  display: block;\\n  height: inherit;\\n  width: inherit;\\n  margin: 3px;\\n}\\n\\n.\" + pluginClassName + \"-wrapper {\\n  z-index: 1;\\n  position: absolute;\\n  display: inline-block;\\n  height: 0;\\n  width: 0;\\n}\\n\\n.\" + pluginClassName + \"-container {\\n  display: none;\\n  z-index: 1;\\n  position: absolute;\\n}\\n\\n.\" + pluginClassName + \"-hidable {\\n  cursor: pointer;\\n}\\n\\n[data-notify-text],[data-notify-html] {\\n  position: relative;\\n}\\n\\n.\" + pluginClassName + \"-arrow {\\n  position: absolute;\\n  z-index: 2;\\n  width: 0;\\n  height: 0;\\n}\"\n};\n\nstylePrefixes = {\n  \"border-radius\": [\"-webkit-\", \"-moz-\"]\n};\n\ngetStyle = function(name) {\n  return styles[name];\n};\n\naddStyle = function(name, def) {\n  var cssText, elem, fields, _ref;\n  if (!name) {\n    throw \"Missing Style name\";\n  }\n  if (!def) {\n    throw \"Missing Style definition\";\n  }\n  if (!def.html) {\n    throw \"Missing Style HTML\";\n  }\n  if ((_ref = styles[name]) != null ? _ref.cssElem : void 0) {\n    if (window.console) {\n      console.warn(\"\" + pluginName + \": overwriting style '\" + name + \"'\");\n    }\n    styles[name].cssElem.remove();\n  }\n  def.name = name;\n  styles[name] = def;\n  cssText = \"\";\n  if (def.classes) {\n    $.each(def.classes, function(className, props) {\n      cssText += \".\" + pluginClassName + \"-\" + def.name + \"-\" + className + \" {\\n\";\n      $.each(props, function(name, val) {\n        if (stylePrefixes[name]) {\n          $.each(stylePrefixes[name], function(i, prefix) {\n            return cssText += \"  \" + prefix + name + \": \" + val + \";\\n\";\n          });\n        }\n        return cssText += \"  \" + name + \": \" + val + \";\\n\";\n      });\n      return cssText += \"}\\n\";\n    });\n  }\n  if (def.css) {\n    cssText += \"/* styles for \" + def.name + \" */\\n\" + def.css;\n  }\n  if (cssText) {\n    def.cssElem = insertCSS(cssText);\n    def.cssElem.attr('id', \"notify-\" + def.name);\n  }\n  fields = {};\n  elem = $(def.html);\n  findFields('html', elem, fields);\n  findFields('text', elem, fields);\n  return def.fields = fields;\n};\n\ninsertCSS = function(cssText) {\n  var elem;\n  elem = createElem(\"style\");\n  elem.attr('type', 'text/css');\n  $(\"head\").append(elem);\n  try {\n    elem.html(cssText);\n  } catch (e) {\n    elem[0].styleSheet.cssText = cssText;\n  }\n  return elem;\n};\n\nfindFields = function(type, elem, fields) {\n  var attr;\n  if (type !== 'html') {\n    type = 'text';\n  }\n  attr = \"data-notify-\" + type;\n  return find(elem, \"[\" + attr + \"]\").each(function() {\n    var name;\n    name = $(this).attr(attr);\n    if (!name) {\n      name = blankFieldName;\n    }\n    return fields[name] = type;\n  });\n};\n\nfind = function(elem, selector) {\n  if (elem.is(selector)) {\n    return elem;\n  } else {\n    return elem.find(selector);\n  }\n};\n\npluginOptions = {\n  clickToHide: true,\n  autoHide: true,\n  autoHideDelay: 5000,\n  arrowShow: true,\n  arrowSize: 5,\n  breakNewLines: true,\n  elementPosition: 'bottom',\n  globalPosition: 'top right',\n  style: 'bootstrap',\n  className: 'error',\n  showAnimation: 'slideDown',\n  showDuration: 400,\n  hideAnimation: 'slideUp',\n  hideDuration: 200,\n  gap: 5\n};\n\ninherit = function(a, b) {\n  var F;\n  F = function() {};\n  F.prototype = a;\n  return $.extend(true, new F(), b);\n};\n\ndefaults = function(opts) {\n  return $.extend(pluginOptions, opts);\n};\n\ncreateElem = function(tag) {\n  return $(\"<\" + tag + \"></\" + tag + \">\");\n};\n\nglobalAnchors = {};\n\ngetAnchorElement = function(element) {\n  var radios;\n  if (element.is('[type=radio]')) {\n    radios = element.parents('form:first').find('[type=radio]').filter(function(i, e) {\n      return $(e).attr('name') === element.attr('name');\n    });\n    element = radios.first();\n  }\n  return element;\n};\n\nincr = function(obj, pos, val) {\n  var opp, temp;\n  if (typeof val === 'string') {\n    val = parseInt(val, 10);\n  } else if (typeof val !== 'number') {\n    return;\n  }\n  if (isNaN(val)) {\n    return;\n  }\n  opp = positions[opposites[pos.charAt(0)]];\n  temp = pos;\n  if (obj[opp] !== undefined) {\n    pos = positions[opp.charAt(0)];\n    val = -val;\n  }\n  if (obj[pos] === undefined) {\n    obj[pos] = val;\n  } else {\n    obj[pos] += val;\n  }\n  return null;\n};\n\nrealign = function(alignment, inner, outer) {\n  if (alignment === 'l' || alignment === 't') {\n    return 0;\n  } else if (alignment === 'c' || alignment === 'm') {\n    return outer / 2 - inner / 2;\n  } else if (alignment === 'r' || alignment === 'b') {\n    return outer - inner;\n  }\n  throw \"Invalid alignment\";\n};\n\nencode = function(text) {\n  encode.e = encode.e || createElem(\"div\");\n  return encode.e.text(text).html();\n};\n\nNotification = (function() {\n\n  function Notification(elem, data, options) {\n    if (typeof options === 'string') {\n      options = {\n        className: options\n      };\n    }\n    this.options = inherit(pluginOptions, $.isPlainObject(options) ? options : {});\n    this.loadHTML();\n    this.wrapper = $(coreStyle.html);\n    if (this.options.clickToHide) {\n      this.wrapper.addClass(\"\" + pluginClassName + \"-hidable\");\n    }\n    this.wrapper.data(pluginClassName, this);\n    this.arrow = this.wrapper.find(\".\" + pluginClassName + \"-arrow\");\n    this.container = this.wrapper.find(\".\" + pluginClassName + \"-container\");\n    this.container.append(this.userContainer);\n    if (elem && elem.length) {\n      this.elementType = elem.attr('type');\n      this.originalElement = elem;\n      this.elem = getAnchorElement(elem);\n      this.elem.data(pluginClassName, this);\n      this.elem.before(this.wrapper);\n    }\n    this.container.hide();\n    this.run(data);\n  }\n\n  Notification.prototype.loadHTML = function() {\n    var style;\n    style = this.getStyle();\n    this.userContainer = $(style.html);\n    return this.userFields = style.fields;\n  };\n\n  Notification.prototype.show = function(show, userCallback) {\n    var args, callback, elems, fn, hidden,\n      _this = this;\n    callback = function() {\n      if (!show && !_this.elem) {\n        _this.destroy();\n      }\n      if (userCallback) {\n        return userCallback();\n      }\n    };\n    hidden = this.container.parent().parents(':hidden').length > 0;\n    elems = this.container.add(this.arrow);\n    args = [];\n    if (hidden && show) {\n      fn = 'show';\n    } else if (hidden && !show) {\n      fn = 'hide';\n    } else if (!hidden && show) {\n      fn = this.options.showAnimation;\n      args.push(this.options.showDuration);\n    } else if (!hidden && !show) {\n      fn = this.options.hideAnimation;\n      args.push(this.options.hideDuration);\n    } else {\n      return callback();\n    }\n    args.push(callback);\n    return elems[fn].apply(elems, args);\n  };\n\n  Notification.prototype.setGlobalPosition = function() {\n    var align, anchor, css, key, main, pAlign, pMain, _ref;\n    _ref = this.getPosition(), pMain = _ref[0], pAlign = _ref[1];\n    main = positions[pMain];\n    align = positions[pAlign];\n    key = pMain + \"|\" + pAlign;\n    anchor = globalAnchors[key];\n    if (!anchor) {\n      anchor = globalAnchors[key] = createElem(\"div\");\n      css = {};\n      css[main] = 0;\n      if (align === 'middle') {\n        css.top = '45%';\n      } else if (align === 'center') {\n        css.left = '45%';\n      } else {\n        css[align] = 0;\n      }\n      anchor.css(css).addClass(\"\" + pluginClassName + \"-corner\");\n      $(\"body\").append(anchor);\n    }\n    return anchor.prepend(this.wrapper);\n  };\n\n  Notification.prototype.setElementPosition = function() {\n    var arrowColor, arrowCss, arrowSize, color, contH, contW, css, elemH, elemIH, elemIW, elemPos, elemW, gap, mainFull, margin, opp, oppFull, pAlign, pArrow, pMain, pos, posFull, position, wrapPos, _i, _j, _len, _len1, _ref;\n    position = this.getPosition();\n    pMain = position[0], pAlign = position[1], pArrow = position[2];\n    elemPos = this.elem.position();\n    elemH = this.elem.outerHeight();\n    elemW = this.elem.outerWidth();\n    elemIH = this.elem.innerHeight();\n    elemIW = this.elem.innerWidth();\n    wrapPos = this.wrapper.position();\n    contH = this.container.height();\n    contW = this.container.width();\n    mainFull = positions[pMain];\n    opp = opposites[pMain];\n    oppFull = positions[opp];\n    css = {};\n    css[oppFull] = pMain === 'b' ? elemH : pMain === 'r' ? elemW : 0;\n    incr(css, 'top', elemPos.top - wrapPos.top);\n    incr(css, 'left', elemPos.left - wrapPos.left);\n    _ref = ['top', 'left'];\n    for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n      pos = _ref[_i];\n      margin = parseInt(this.elem.css(\"margin-\" + pos), 10);\n      if (margin) {\n        incr(css, pos, margin);\n      }\n    }\n    gap = Math.max(0, this.options.gap - (this.options.arrowShow ? arrowSize : 0));\n    incr(css, oppFull, gap);\n    if (!this.options.arrowShow) {\n      this.arrow.hide();\n    } else {\n      arrowSize = this.options.arrowSize;\n      arrowCss = $.extend({}, css);\n      arrowColor = this.userContainer.css(\"border-color\") || this.userContainer.css(\"background-color\") || 'white';\n      for (_j = 0, _len1 = mainPositions.length; _j < _len1; _j++) {\n        pos = mainPositions[_j];\n        posFull = positions[pos];\n        if (pos === opp) {\n          continue;\n        }\n        color = posFull === mainFull ? arrowColor : 'transparent';\n        arrowCss[\"border-\" + posFull] = \"\" + arrowSize + \"px solid \" + color;\n      }\n      incr(css, positions[opp], arrowSize);\n      if (__indexOf.call(mainPositions, pAlign) >= 0) {\n        incr(arrowCss, positions[pAlign], arrowSize * 2);\n      }\n    }\n    if (__indexOf.call(vAligns, pMain) >= 0) {\n      incr(css, 'left', realign(pAlign, contW, elemW));\n      if (arrowCss) {\n        incr(arrowCss, 'left', realign(pAlign, arrowSize, elemIW));\n      }\n    } else if (__indexOf.call(hAligns, pMain) >= 0) {\n      incr(css, 'top', realign(pAlign, contH, elemH));\n      if (arrowCss) {\n        incr(arrowCss, 'top', realign(pAlign, arrowSize, elemIH));\n      }\n    }\n    if (this.container.is(\":visible\")) {\n      css.display = 'block';\n    }\n    this.container.removeAttr('style').css(css);\n    if (arrowCss) {\n      return this.arrow.removeAttr('style').css(arrowCss);\n    }\n  };\n\n  Notification.prototype.getPosition = function() {\n    var pos, text, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;\n    text = this.options.position || (this.elem ? this.options.elementPosition : this.options.globalPosition);\n    pos = parsePosition(text);\n    if (pos.length === 0) {\n      pos[0] = 'b';\n    }\n    if (_ref = pos[0], __indexOf.call(mainPositions, _ref) < 0) {\n      throw \"Must be one of [\" + mainPositions + \"]\";\n    }\n    if (pos.length === 1 || ((_ref1 = pos[0], __indexOf.call(vAligns, _ref1) >= 0) && (_ref2 = pos[1], __indexOf.call(hAligns, _ref2) < 0)) || ((_ref3 = pos[0], __indexOf.call(hAligns, _ref3) >= 0) && (_ref4 = pos[1], __indexOf.call(vAligns, _ref4) < 0))) {\n      pos[1] = (_ref5 = pos[0], __indexOf.call(hAligns, _ref5) >= 0) ? 'm' : 'l';\n    }\n    if (pos.length === 2) {\n      pos[2] = pos[1];\n    }\n    return pos;\n  };\n\n  Notification.prototype.getStyle = function(name) {\n    var style;\n    if (!name) {\n      name = this.options.style;\n    }\n    if (!name) {\n      name = 'default';\n    }\n    style = styles[name];\n    if (!style) {\n      throw \"Missing style: \" + name;\n    }\n    return style;\n  };\n\n  Notification.prototype.updateClasses = function() {\n    var classes, style;\n    classes = ['base'];\n    if ($.isArray(this.options.className)) {\n      classes = classes.concat(this.options.className);\n    } else if (this.options.className) {\n      classes.push(this.options.className);\n    }\n    style = this.getStyle();\n    classes = $.map(classes, function(n) {\n      return \"\" + pluginClassName + \"-\" + style.name + \"-\" + n;\n    }).join(' ');\n    return this.userContainer.attr('class', classes);\n  };\n\n  Notification.prototype.run = function(data, options) {\n    var d, datas, name, type, value,\n      _this = this;\n    if ($.isPlainObject(options)) {\n      $.extend(this.options, options);\n    } else if ($.type(options) === 'string') {\n      this.options.className = options;\n    }\n    if (this.container && !data) {\n      this.show(false);\n      return;\n    } else if (!this.container && !data) {\n      return;\n    }\n    datas = {};\n    if ($.isPlainObject(data)) {\n      datas = data;\n    } else {\n      datas[blankFieldName] = data;\n    }\n    for (name in datas) {\n      d = datas[name];\n      type = this.userFields[name];\n      if (!type) {\n        continue;\n      }\n      if (type === 'text') {\n        d = encode(d);\n        if (this.options.breakNewLines) {\n          d = d.replace(/\\n/g, '<br/>');\n        }\n      }\n      value = name === blankFieldName ? '' : '=' + name;\n      find(this.userContainer, \"[data-notify-\" + type + value + \"]\").html(d);\n    }\n    this.updateClasses();\n    if (this.elem) {\n      this.setElementPosition();\n    } else {\n      this.setGlobalPosition();\n    }\n    this.show(true);\n    if (this.options.autoHide) {\n      clearTimeout(this.autohideTimer);\n      return this.autohideTimer = setTimeout(function() {\n        return _this.show(false);\n      }, this.options.autoHideDelay);\n    }\n  };\n\n  Notification.prototype.destroy = function() {\n    return this.wrapper.remove();\n  };\n\n  return Notification;\n\n})();\n\n$[pluginName] = function(elem, data, options) {\n  if ((elem && elem.nodeName) || elem.jquery) {\n    $(elem)[pluginName](data, options);\n  } else {\n    options = data;\n    data = elem;\n    new Notification(null, data, options);\n  }\n  return elem;\n};\n\n$.fn[pluginName] = function(data, options) {\n  $(this).each(function() {\n    var inst;\n    inst = getAnchorElement($(this)).data(pluginClassName);\n    if (inst) {\n      return inst.run(data, options);\n    } else {\n      return new Notification($(this), data, options);\n    }\n  });\n  return this;\n};\n\n$.extend($[pluginName], {\n  defaults: defaults,\n  addStyle: addStyle,\n  pluginOptions: pluginOptions,\n  getStyle: getStyle,\n  insertCSS: insertCSS\n});\n\n$(function() {\n  insertCSS(coreStyle.css).attr('id', 'core-notify');\n  $(document).on('click', \".\" + pluginClassName + \"-hidable\", function(e) {\n    return $(this).trigger('notify-hide');\n  });\n  return $(document).on('notify-hide', \".\" + pluginClassName + \"-wrapper\", function(e) {\n    var _ref;\n    return (_ref = $(this).data(pluginClassName)) != null ? _ref.show(false) : void 0;\n  });\n});\n\n}(window,document,jQuery));\n\n$.notify.addStyle(\"bootstrap\", {\n  html: \"<div>\\n<span data-notify-text></span>\\n</div>\",\n  classes: {\n    base: {\n      \"font-weight\": \"bold\",\n      \"padding\": \"8px 15px 8px 14px\",\n      \"text-shadow\": \"0 1px 0 rgba(255, 255, 255, 0.5)\",\n      \"background-color\": \"#fcf8e3\",\n      \"border\": \"1px solid #fbeed5\",\n      \"border-radius\": \"4px\",\n      \"white-space\": \"nowrap\",\n      \"padding-left\": \"25px\",\n      \"background-repeat\": \"no-repeat\",\n      \"background-position\": \"3px 7px\"\n    },\n    error: {\n      \"color\": \"#B94A48\",\n      \"background-color\": \"#F2DEDE\",\n      \"border-color\": \"#EED3D7\",\n      \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAtRJREFUeNqkVc1u00AQHq+dOD+0poIQfkIjalW0SEGqRMuRnHos3DjwAH0ArlyQeANOOSMeAA5VjyBxKBQhgSpVUKKQNGloFdw4cWw2jtfMOna6JOUArDTazXi/b3dm55socPqQhFka++aHBsI8GsopRJERNFlY88FCEk9Yiwf8RhgRyaHFQpPHCDmZG5oX2ui2yilkcTT1AcDsbYC1NMAyOi7zTX2Agx7A9luAl88BauiiQ/cJaZQfIpAlngDcvZZMrl8vFPK5+XktrWlx3/ehZ5r9+t6e+WVnp1pxnNIjgBe4/6dAysQc8dsmHwPcW9C0h3fW1hans1ltwJhy0GxK7XZbUlMp5Ww2eyan6+ft/f2FAqXGK4CvQk5HueFz7D6GOZtIrK+srupdx1GRBBqNBtzc2AiMr7nPplRdKhb1q6q6zjFhrklEFOUutoQ50xcX86ZlqaZpQrfbBdu2R6/G19zX6XSgh6RX5ubyHCM8nqSID6ICrGiZjGYYxojEsiw4PDwMSL5VKsC8Yf4VRYFzMzMaxwjlJSlCyAQ9l0CW44PBADzXhe7xMdi9HtTrdYjFYkDQL0cn4Xdq2/EAE+InCnvADTf2eah4Sx9vExQjkqXT6aAERICMewd/UAp/IeYANM2joxt+q5VI+ieq2i0Wg3l6DNzHwTERPgo1ko7XBXj3vdlsT2F+UuhIhYkp7u7CarkcrFOCtR3H5JiwbAIeImjT/YQKKBtGjRFCU5IUgFRe7fF4cCNVIPMYo3VKqxwjyNAXNepuopyqnld602qVsfRpEkkz+GFL1wPj6ySXBpJtWVa5xlhpcyhBNwpZHmtX8AGgfIExo0ZpzkWVTBGiXCSEaHh62/PoR0p/vHaczxXGnj4bSo+G78lELU80h1uogBwWLf5YlsPmgDEd4M236xjm+8nm4IuE/9u+/PH2JXZfbwz4zw1WbO+SQPpXfwG/BBgAhCNZiSb/pOQAAAAASUVORK5CYII=)\"\n    },\n    success: {\n      \"color\": \"#468847\",\n      \"background-color\": \"#DFF0D8\",\n      \"border-color\": \"#D6E9C6\",\n      \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAutJREFUeNq0lctPE0Ecx38zu/RFS1EryqtgJFA08YCiMZIAQQ4eRG8eDGdPJiYeTIwHTfwPiAcvXIwXLwoXPaDxkWgQ6islKlJLSQWLUraPLTv7Gme32zoF9KSTfLO7v53vZ3d/M7/fIth+IO6INt2jjoA7bjHCJoAlzCRw59YwHYjBnfMPqAKWQYKjGkfCJqAF0xwZjipQtA3MxeSG87VhOOYegVrUCy7UZM9S6TLIdAamySTclZdYhFhRHloGYg7mgZv1Zzztvgud7V1tbQ2twYA34LJmF4p5dXF1KTufnE+SxeJtuCZNsLDCQU0+RyKTF27Unw101l8e6hns3u0PBalORVVVkcaEKBJDgV3+cGM4tKKmI+ohlIGnygKX00rSBfszz/n2uXv81wd6+rt1orsZCHRdr1Imk2F2Kob3hutSxW8thsd8AXNaln9D7CTfA6O+0UgkMuwVvEFFUbbAcrkcTA8+AtOk8E6KiQiDmMFSDqZItAzEVQviRkdDdaFgPp8HSZKAEAL5Qh7Sq2lIJBJwv2scUqkUnKoZgNhcDKhKg5aH+1IkcouCAdFGAQsuWZYhOjwFHQ96oagWgRoUov1T9kRBEODAwxM2QtEUl+Wp+Ln9VRo6BcMw4ErHRYjH4/B26AlQoQQTRdHWwcd9AH57+UAXddvDD37DmrBBV34WfqiXPl61g+vr6xA9zsGeM9gOdsNXkgpEtTwVvwOklXLKm6+/p5ezwk4B+j6droBs2CsGa/gNs6RIxazl4Tc25mpTgw/apPR1LYlNRFAzgsOxkyXYLIM1V8NMwyAkJSctD1eGVKiq5wWjSPdjmeTkiKvVW4f2YPHWl3GAVq6ymcyCTgovM3FzyRiDe2TaKcEKsLpJvNHjZgPNqEtyi6mZIm4SRFyLMUsONSSdkPeFtY1n0mczoY3BHTLhwPRy9/lzcziCw9ACI+yql0VLzcGAZbYSM5CCSZg1/9oc/nn7+i8N9p/8An4JMADxhH+xHfuiKwAAAABJRU5ErkJggg==)\"\n    },\n    info: {\n      \"color\": \"#3A87AD\",\n      \"background-color\": \"#D9EDF7\",\n      \"border-color\": \"#BCE8F1\",\n      \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QYFAhkSsdes/QAAA8dJREFUOMvVlGtMW2UYx//POaWHXg6lLaW0ypAtw1UCgbniNOLcVOLmAjHZolOYlxmTGXVZdAnRfXQm+7SoU4mXaOaiZsEpC9FkiQs6Z6bdCnNYruM6KNBw6YWewzl9z+sHImEWv+vz7XmT95f/+3/+7wP814v+efDOV3/SoX3lHAA+6ODeUFfMfjOWMADgdk+eEKz0pF7aQdMAcOKLLjrcVMVX3xdWN29/GhYP7SvnP0cWfS8caSkfHZsPE9Fgnt02JNutQ0QYHB2dDz9/pKX8QjjuO9xUxd/66HdxTeCHZ3rojQObGQBcuNjfplkD3b19Y/6MrimSaKgSMmpGU5WevmE/swa6Oy73tQHA0Rdr2Mmv/6A1n9w9suQ7097Z9lM4FlTgTDrzZTu4StXVfpiI48rVcUDM5cmEksrFnHxfpTtU/3BFQzCQF/2bYVoNbH7zmItbSoMj40JSzmMyX5qDvriA7QdrIIpA+3cdsMpu0nXI8cV0MtKXCPZev+gCEM1S2NHPvWfP/hL+7FSr3+0p5RBEyhEN5JCKYr8XnASMT0xBNyzQGQeI8fjsGD39RMPk7se2bd5ZtTyoFYXftF6y37gx7NeUtJJOTFlAHDZLDuILU3j3+H5oOrD3yWbIztugaAzgnBKJuBLpGfQrS8wO4FZgV+c1IxaLgWVU0tMLEETCos4xMzEIv9cJXQcyagIwigDGwJgOAtHAwAhisQUjy0ORGERiELgG4iakkzo4MYAxcM5hAMi1WWG1yYCJIcMUaBkVRLdGeSU2995TLWzcUAzONJ7J6FBVBYIggMzmFbvdBV44Corg8vjhzC+EJEl8U1kJtgYrhCzgc/vvTwXKSib1paRFVRVORDAJAsw5FuTaJEhWM2SHB3mOAlhkNxwuLzeJsGwqWzf5TFNdKgtY5qHp6ZFf67Y/sAVadCaVY5YACDDb3Oi4NIjLnWMw2QthCBIsVhsUTU9tvXsjeq9+X1d75/KEs4LNOfcdf/+HthMnvwxOD0wmHaXr7ZItn2wuH2SnBzbZAbPJwpPx+VQuzcm7dgRCB57a1uBzUDRL4bfnI0RE0eaXd9W89mpjqHZnUI5Hh2l2dkZZUhOqpi2qSmpOmZ64Tuu9qlz/SEXo6MEHa3wOip46F1n7633eekV8ds8Wxjn37Wl63VVa+ej5oeEZ/82ZBETJjpJ1Rbij2D3Z/1trXUvLsblCK0XfOx0SX2kMsn9dX+d+7Kf6h8o4AIykuffjT8L20LU+w4AZd5VvEPY+XpWqLV327HR7DzXuDnD8r+ovkBehJ8i+y8YAAAAASUVORK5CYII=)\"\n    },\n    warn: {\n      \"color\": \"#C09853\",\n      \"background-color\": \"#FCF8E3\",\n      \"border-color\": \"#FBEED5\",\n      \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABJlBMVEXr6eb/2oD/wi7/xjr/0mP/ykf/tQD/vBj/3o7/uQ//vyL/twebhgD/4pzX1K3z8e349vK6tHCilCWbiQymn0jGworr6dXQza3HxcKkn1vWvV/5uRfk4dXZ1bD18+/52YebiAmyr5S9mhCzrWq5t6ufjRH54aLs0oS+qD751XqPhAybhwXsujG3sm+Zk0PTwG6Shg+PhhObhwOPgQL4zV2nlyrf27uLfgCPhRHu7OmLgAafkyiWkD3l49ibiAfTs0C+lgCniwD4sgDJxqOilzDWowWFfAH08uebig6qpFHBvH/aw26FfQTQzsvy8OyEfz20r3jAvaKbhgG9q0nc2LbZxXanoUu/u5WSggCtp1anpJKdmFz/zlX/1nGJiYmuq5Dx7+sAAADoPUZSAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfdBgUBGhh4aah5AAAAlklEQVQY02NgoBIIE8EUcwn1FkIXM1Tj5dDUQhPU502Mi7XXQxGz5uVIjGOJUUUW81HnYEyMi2HVcUOICQZzMMYmxrEyMylJwgUt5BljWRLjmJm4pI1hYp5SQLGYxDgmLnZOVxuooClIDKgXKMbN5ggV1ACLJcaBxNgcoiGCBiZwdWxOETBDrTyEFey0jYJ4eHjMGWgEAIpRFRCUt08qAAAAAElFTkSuQmCC)\"\n    }\n  }\n});\n"
  },
  {
    "path": "static/assets/plugins/notifyjs/dist/notify.js",
    "content": "/** Notify.js - v0.3.1 - 2014/06/29\n * http://notifyjs.com/\n * Copyright (c) 2014 Jaime Pillora - MIT\n */\n(function(window,document,$,undefined) {\n'use strict';\n\nvar Notification, addStyle, blankFieldName, coreStyle, createElem, defaults, encode, find, findFields, getAnchorElement, getStyle, globalAnchors, hAligns, incr, inherit, insertCSS, mainPositions, opposites, parsePosition, pluginClassName, pluginName, pluginOptions, positions, realign, stylePrefixes, styles, vAligns,\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\npluginName = 'notify';\n\npluginClassName = pluginName + 'js';\n\nblankFieldName = pluginName + \"!blank\";\n\npositions = {\n  t: 'top',\n  m: 'middle',\n  b: 'bottom',\n  l: 'left',\n  c: 'center',\n  r: 'right'\n};\n\nhAligns = ['l', 'c', 'r'];\n\nvAligns = ['t', 'm', 'b'];\n\nmainPositions = ['t', 'b', 'l', 'r'];\n\nopposites = {\n  t: 'b',\n  m: null,\n  b: 't',\n  l: 'r',\n  c: null,\n  r: 'l'\n};\n\nparsePosition = function(str) {\n  var pos;\n  pos = [];\n  $.each(str.split(/\\W+/), function(i, word) {\n    var w;\n    w = word.toLowerCase().charAt(0);\n    if (positions[w]) {\n      return pos.push(w);\n    }\n  });\n  return pos;\n};\n\nstyles = {};\n\ncoreStyle = {\n  name: 'core',\n  html: \"<div class=\\\"\" + pluginClassName + \"-wrapper\\\">\\n  <div class=\\\"\" + pluginClassName + \"-arrow\\\"></div>\\n  <div class=\\\"\" + pluginClassName + \"-container\\\"></div>\\n</div>\",\n  css: \".\" + pluginClassName + \"-corner {\\n  position: fixed;\\n  margin: 5px;\\n  z-index: 1050;\\n}\\n\\n.\" + pluginClassName + \"-corner .\" + pluginClassName + \"-wrapper,\\n.\" + pluginClassName + \"-corner .\" + pluginClassName + \"-container {\\n  position: relative;\\n  display: block;\\n  height: inherit;\\n  width: inherit;\\n  margin: 3px;\\n}\\n\\n.\" + pluginClassName + \"-wrapper {\\n  z-index: 1;\\n  position: absolute;\\n  display: inline-block;\\n  height: 0;\\n  width: 0;\\n}\\n\\n.\" + pluginClassName + \"-container {\\n  display: none;\\n  z-index: 1;\\n  position: absolute;\\n}\\n\\n.\" + pluginClassName + \"-hidable {\\n  cursor: pointer;\\n}\\n\\n[data-notify-text],[data-notify-html] {\\n  position: relative;\\n}\\n\\n.\" + pluginClassName + \"-arrow {\\n  position: absolute;\\n  z-index: 2;\\n  width: 0;\\n  height: 0;\\n}\"\n};\n\nstylePrefixes = {\n  \"border-radius\": [\"-webkit-\", \"-moz-\"]\n};\n\ngetStyle = function(name) {\n  return styles[name];\n};\n\naddStyle = function(name, def) {\n  var cssText, elem, fields, _ref;\n  if (!name) {\n    throw \"Missing Style name\";\n  }\n  if (!def) {\n    throw \"Missing Style definition\";\n  }\n  if (!def.html) {\n    throw \"Missing Style HTML\";\n  }\n  if ((_ref = styles[name]) != null ? _ref.cssElem : void 0) {\n    if (window.console) {\n      console.warn(\"\" + pluginName + \": overwriting style '\" + name + \"'\");\n    }\n    styles[name].cssElem.remove();\n  }\n  def.name = name;\n  styles[name] = def;\n  cssText = \"\";\n  if (def.classes) {\n    $.each(def.classes, function(className, props) {\n      cssText += \".\" + pluginClassName + \"-\" + def.name + \"-\" + className + \" {\\n\";\n      $.each(props, function(name, val) {\n        if (stylePrefixes[name]) {\n          $.each(stylePrefixes[name], function(i, prefix) {\n            return cssText += \"  \" + prefix + name + \": \" + val + \";\\n\";\n          });\n        }\n        return cssText += \"  \" + name + \": \" + val + \";\\n\";\n      });\n      return cssText += \"}\\n\";\n    });\n  }\n  if (def.css) {\n    cssText += \"/* styles for \" + def.name + \" */\\n\" + def.css;\n  }\n  if (cssText) {\n    def.cssElem = insertCSS(cssText);\n    def.cssElem.attr('id', \"notify-\" + def.name);\n  }\n  fields = {};\n  elem = $(def.html);\n  findFields('html', elem, fields);\n  findFields('text', elem, fields);\n  return def.fields = fields;\n};\n\ninsertCSS = function(cssText) {\n  var elem;\n  elem = createElem(\"style\");\n  elem.attr('type', 'text/css');\n  $(\"head\").append(elem);\n  try {\n    elem.html(cssText);\n  } catch (e) {\n    elem[0].styleSheet.cssText = cssText;\n  }\n  return elem;\n};\n\nfindFields = function(type, elem, fields) {\n  var attr;\n  if (type !== 'html') {\n    type = 'text';\n  }\n  attr = \"data-notify-\" + type;\n  return find(elem, \"[\" + attr + \"]\").each(function() {\n    var name;\n    name = $(this).attr(attr);\n    if (!name) {\n      name = blankFieldName;\n    }\n    return fields[name] = type;\n  });\n};\n\nfind = function(elem, selector) {\n  if (elem.is(selector)) {\n    return elem;\n  } else {\n    return elem.find(selector);\n  }\n};\n\npluginOptions = {\n  clickToHide: true,\n  autoHide: true,\n  autoHideDelay: 5000,\n  arrowShow: true,\n  arrowSize: 5,\n  breakNewLines: true,\n  elementPosition: 'bottom',\n  globalPosition: 'top right',\n  style: 'bootstrap',\n  className: 'error',\n  showAnimation: 'slideDown',\n  showDuration: 400,\n  hideAnimation: 'slideUp',\n  hideDuration: 200,\n  gap: 5\n};\n\ninherit = function(a, b) {\n  var F;\n  F = function() {};\n  F.prototype = a;\n  return $.extend(true, new F(), b);\n};\n\ndefaults = function(opts) {\n  return $.extend(pluginOptions, opts);\n};\n\ncreateElem = function(tag) {\n  return $(\"<\" + tag + \"></\" + tag + \">\");\n};\n\nglobalAnchors = {};\n\ngetAnchorElement = function(element) {\n  var radios;\n  if (element.is('[type=radio]')) {\n    radios = element.parents('form:first').find('[type=radio]').filter(function(i, e) {\n      return $(e).attr('name') === element.attr('name');\n    });\n    element = radios.first();\n  }\n  return element;\n};\n\nincr = function(obj, pos, val) {\n  var opp, temp;\n  if (typeof val === 'string') {\n    val = parseInt(val, 10);\n  } else if (typeof val !== 'number') {\n    return;\n  }\n  if (isNaN(val)) {\n    return;\n  }\n  opp = positions[opposites[pos.charAt(0)]];\n  temp = pos;\n  if (obj[opp] !== undefined) {\n    pos = positions[opp.charAt(0)];\n    val = -val;\n  }\n  if (obj[pos] === undefined) {\n    obj[pos] = val;\n  } else {\n    obj[pos] += val;\n  }\n  return null;\n};\n\nrealign = function(alignment, inner, outer) {\n  if (alignment === 'l' || alignment === 't') {\n    return 0;\n  } else if (alignment === 'c' || alignment === 'm') {\n    return outer / 2 - inner / 2;\n  } else if (alignment === 'r' || alignment === 'b') {\n    return outer - inner;\n  }\n  throw \"Invalid alignment\";\n};\n\nencode = function(text) {\n  encode.e = encode.e || createElem(\"div\");\n  return encode.e.text(text).html();\n};\n\nNotification = (function() {\n\n  function Notification(elem, data, options) {\n    if (typeof options === 'string') {\n      options = {\n        className: options\n      };\n    }\n    this.options = inherit(pluginOptions, $.isPlainObject(options) ? options : {});\n    this.loadHTML();\n    this.wrapper = $(coreStyle.html);\n    if (this.options.clickToHide) {\n      this.wrapper.addClass(\"\" + pluginClassName + \"-hidable\");\n    }\n    this.wrapper.data(pluginClassName, this);\n    this.arrow = this.wrapper.find(\".\" + pluginClassName + \"-arrow\");\n    this.container = this.wrapper.find(\".\" + pluginClassName + \"-container\");\n    this.container.append(this.userContainer);\n    if (elem && elem.length) {\n      this.elementType = elem.attr('type');\n      this.originalElement = elem;\n      this.elem = getAnchorElement(elem);\n      this.elem.data(pluginClassName, this);\n      this.elem.before(this.wrapper);\n    }\n    this.container.hide();\n    this.run(data);\n  }\n\n  Notification.prototype.loadHTML = function() {\n    var style;\n    style = this.getStyle();\n    this.userContainer = $(style.html);\n    return this.userFields = style.fields;\n  };\n\n  Notification.prototype.show = function(show, userCallback) {\n    var args, callback, elems, fn, hidden,\n      _this = this;\n    callback = function() {\n      if (!show && !_this.elem) {\n        _this.destroy();\n      }\n      if (userCallback) {\n        return userCallback();\n      }\n    };\n    hidden = this.container.parent().parents(':hidden').length > 0;\n    elems = this.container.add(this.arrow);\n    args = [];\n    if (hidden && show) {\n      fn = 'show';\n    } else if (hidden && !show) {\n      fn = 'hide';\n    } else if (!hidden && show) {\n      fn = this.options.showAnimation;\n      args.push(this.options.showDuration);\n    } else if (!hidden && !show) {\n      fn = this.options.hideAnimation;\n      args.push(this.options.hideDuration);\n    } else {\n      return callback();\n    }\n    args.push(callback);\n    return elems[fn].apply(elems, args);\n  };\n\n  Notification.prototype.setGlobalPosition = function() {\n    var align, anchor, css, key, main, pAlign, pMain, _ref;\n    _ref = this.getPosition(), pMain = _ref[0], pAlign = _ref[1];\n    main = positions[pMain];\n    align = positions[pAlign];\n    key = pMain + \"|\" + pAlign;\n    anchor = globalAnchors[key];\n    if (!anchor) {\n      anchor = globalAnchors[key] = createElem(\"div\");\n      css = {};\n      css[main] = 0;\n      if (align === 'middle') {\n        css.top = '45%';\n      } else if (align === 'center') {\n        css.left = '45%';\n      } else {\n        css[align] = 0;\n      }\n      anchor.css(css).addClass(\"\" + pluginClassName + \"-corner\");\n      $(\"body\").append(anchor);\n    }\n    return anchor.prepend(this.wrapper);\n  };\n\n  Notification.prototype.setElementPosition = function() {\n    var arrowColor, arrowCss, arrowSize, color, contH, contW, css, elemH, elemIH, elemIW, elemPos, elemW, gap, mainFull, margin, opp, oppFull, pAlign, pArrow, pMain, pos, posFull, position, wrapPos, _i, _j, _len, _len1, _ref;\n    position = this.getPosition();\n    pMain = position[0], pAlign = position[1], pArrow = position[2];\n    elemPos = this.elem.position();\n    elemH = this.elem.outerHeight();\n    elemW = this.elem.outerWidth();\n    elemIH = this.elem.innerHeight();\n    elemIW = this.elem.innerWidth();\n    wrapPos = this.wrapper.position();\n    contH = this.container.height();\n    contW = this.container.width();\n    mainFull = positions[pMain];\n    opp = opposites[pMain];\n    oppFull = positions[opp];\n    css = {};\n    css[oppFull] = pMain === 'b' ? elemH : pMain === 'r' ? elemW : 0;\n    incr(css, 'top', elemPos.top - wrapPos.top);\n    incr(css, 'left', elemPos.left - wrapPos.left);\n    _ref = ['top', 'left'];\n    for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n      pos = _ref[_i];\n      margin = parseInt(this.elem.css(\"margin-\" + pos), 10);\n      if (margin) {\n        incr(css, pos, margin);\n      }\n    }\n    gap = Math.max(0, this.options.gap - (this.options.arrowShow ? arrowSize : 0));\n    incr(css, oppFull, gap);\n    if (!this.options.arrowShow) {\n      this.arrow.hide();\n    } else {\n      arrowSize = this.options.arrowSize;\n      arrowCss = $.extend({}, css);\n      arrowColor = this.userContainer.css(\"border-color\") || this.userContainer.css(\"background-color\") || 'white';\n      for (_j = 0, _len1 = mainPositions.length; _j < _len1; _j++) {\n        pos = mainPositions[_j];\n        posFull = positions[pos];\n        if (pos === opp) {\n          continue;\n        }\n        color = posFull === mainFull ? arrowColor : 'transparent';\n        arrowCss[\"border-\" + posFull] = \"\" + arrowSize + \"px solid \" + color;\n      }\n      incr(css, positions[opp], arrowSize);\n      if (__indexOf.call(mainPositions, pAlign) >= 0) {\n        incr(arrowCss, positions[pAlign], arrowSize * 2);\n      }\n    }\n    if (__indexOf.call(vAligns, pMain) >= 0) {\n      incr(css, 'left', realign(pAlign, contW, elemW));\n      if (arrowCss) {\n        incr(arrowCss, 'left', realign(pAlign, arrowSize, elemIW));\n      }\n    } else if (__indexOf.call(hAligns, pMain) >= 0) {\n      incr(css, 'top', realign(pAlign, contH, elemH));\n      if (arrowCss) {\n        incr(arrowCss, 'top', realign(pAlign, arrowSize, elemIH));\n      }\n    }\n    if (this.container.is(\":visible\")) {\n      css.display = 'block';\n    }\n    this.container.removeAttr('style').css(css);\n    if (arrowCss) {\n      return this.arrow.removeAttr('style').css(arrowCss);\n    }\n  };\n\n  Notification.prototype.getPosition = function() {\n    var pos, text, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;\n    text = this.options.position || (this.elem ? this.options.elementPosition : this.options.globalPosition);\n    pos = parsePosition(text);\n    if (pos.length === 0) {\n      pos[0] = 'b';\n    }\n    if (_ref = pos[0], __indexOf.call(mainPositions, _ref) < 0) {\n      throw \"Must be one of [\" + mainPositions + \"]\";\n    }\n    if (pos.length === 1 || ((_ref1 = pos[0], __indexOf.call(vAligns, _ref1) >= 0) && (_ref2 = pos[1], __indexOf.call(hAligns, _ref2) < 0)) || ((_ref3 = pos[0], __indexOf.call(hAligns, _ref3) >= 0) && (_ref4 = pos[1], __indexOf.call(vAligns, _ref4) < 0))) {\n      pos[1] = (_ref5 = pos[0], __indexOf.call(hAligns, _ref5) >= 0) ? 'm' : 'l';\n    }\n    if (pos.length === 2) {\n      pos[2] = pos[1];\n    }\n    return pos;\n  };\n\n  Notification.prototype.getStyle = function(name) {\n    var style;\n    if (!name) {\n      name = this.options.style;\n    }\n    if (!name) {\n      name = 'default';\n    }\n    style = styles[name];\n    if (!style) {\n      throw \"Missing style: \" + name;\n    }\n    return style;\n  };\n\n  Notification.prototype.updateClasses = function() {\n    var classes, style;\n    classes = ['base'];\n    if ($.isArray(this.options.className)) {\n      classes = classes.concat(this.options.className);\n    } else if (this.options.className) {\n      classes.push(this.options.className);\n    }\n    style = this.getStyle();\n    classes = $.map(classes, function(n) {\n      return \"\" + pluginClassName + \"-\" + style.name + \"-\" + n;\n    }).join(' ');\n    return this.userContainer.attr('class', classes);\n  };\n\n  Notification.prototype.run = function(data, options) {\n    var d, datas, name, type, value,\n      _this = this;\n    if ($.isPlainObject(options)) {\n      $.extend(this.options, options);\n    } else if ($.type(options) === 'string') {\n      this.options.className = options;\n    }\n    if (this.container && !data) {\n      this.show(false);\n      return;\n    } else if (!this.container && !data) {\n      return;\n    }\n    datas = {};\n    if ($.isPlainObject(data)) {\n      datas = data;\n    } else {\n      datas[blankFieldName] = data;\n    }\n    for (name in datas) {\n      d = datas[name];\n      type = this.userFields[name];\n      if (!type) {\n        continue;\n      }\n      if (type === 'text') {\n        d = encode(d);\n        if (this.options.breakNewLines) {\n          d = d.replace(/\\n/g, '<br/>');\n        }\n      }\n      value = name === blankFieldName ? '' : '=' + name;\n      find(this.userContainer, \"[data-notify-\" + type + value + \"]\").html(d);\n    }\n    this.updateClasses();\n    if (this.elem) {\n      this.setElementPosition();\n    } else {\n      this.setGlobalPosition();\n    }\n    this.show(true);\n    if (this.options.autoHide) {\n      clearTimeout(this.autohideTimer);\n      return this.autohideTimer = setTimeout(function() {\n        return _this.show(false);\n      }, this.options.autoHideDelay);\n    }\n  };\n\n  Notification.prototype.destroy = function() {\n    return this.wrapper.remove();\n  };\n\n  return Notification;\n\n})();\n\n$[pluginName] = function(elem, data, options) {\n  if ((elem && elem.nodeName) || elem.jquery) {\n    $(elem)[pluginName](data, options);\n  } else {\n    options = data;\n    data = elem;\n    new Notification(null, data, options);\n  }\n  return elem;\n};\n\n$.fn[pluginName] = function(data, options) {\n  $(this).each(function() {\n    var inst;\n    inst = getAnchorElement($(this)).data(pluginClassName);\n    if (inst) {\n      return inst.run(data, options);\n    } else {\n      return new Notification($(this), data, options);\n    }\n  });\n  return this;\n};\n\n$.extend($[pluginName], {\n  defaults: defaults,\n  addStyle: addStyle,\n  pluginOptions: pluginOptions,\n  getStyle: getStyle,\n  insertCSS: insertCSS\n});\n\n$(function() {\n  insertCSS(coreStyle.css).attr('id', 'core-notify');\n  $(document).on('click', \".\" + pluginClassName + \"-hidable\", function(e) {\n    return $(this).trigger('notify-hide');\n  });\n  return $(document).on('notify-hide', \".\" + pluginClassName + \"-wrapper\", function(e) {\n    var _ref;\n    return (_ref = $(this).data(pluginClassName)) != null ? _ref.show(false) : void 0;\n  });\n});\n\n}(window,document,jQuery));"
  },
  {
    "path": "static/assets/plugins/notifyjs/dist/styles/bootstrap/notify-bootstrap.js",
    "content": "\n$.notify.addStyle(\"bootstrap\", {\n  html: \"<div>\\n<span data-notify-text></span>\\n</div>\",\n  classes: {\n    base: {\n      \"font-weight\": \"bold\",\n      \"padding\": \"8px 15px 8px 14px\",\n      \"text-shadow\": \"0 1px 0 rgba(255, 255, 255, 0.5)\",\n      \"background-color\": \"#fcf8e3\",\n      \"border\": \"1px solid #fbeed5\",\n      \"border-radius\": \"4px\",\n      \"white-space\": \"nowrap\",\n      \"padding-left\": \"25px\",\n      \"background-repeat\": \"no-repeat\",\n      \"background-position\": \"3px 7px\"\n    },\n    error: {\n      \"color\": \"#B94A48\",\n      \"background-color\": \"#F2DEDE\",\n      \"border-color\": \"#EED3D7\",\n      \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAtRJREFUeNqkVc1u00AQHq+dOD+0poIQfkIjalW0SEGqRMuRnHos3DjwAH0ArlyQeANOOSMeAA5VjyBxKBQhgSpVUKKQNGloFdw4cWw2jtfMOna6JOUArDTazXi/b3dm55socPqQhFka++aHBsI8GsopRJERNFlY88FCEk9Yiwf8RhgRyaHFQpPHCDmZG5oX2ui2yilkcTT1AcDsbYC1NMAyOi7zTX2Agx7A9luAl88BauiiQ/cJaZQfIpAlngDcvZZMrl8vFPK5+XktrWlx3/ehZ5r9+t6e+WVnp1pxnNIjgBe4/6dAysQc8dsmHwPcW9C0h3fW1hans1ltwJhy0GxK7XZbUlMp5Ww2eyan6+ft/f2FAqXGK4CvQk5HueFz7D6GOZtIrK+srupdx1GRBBqNBtzc2AiMr7nPplRdKhb1q6q6zjFhrklEFOUutoQ50xcX86ZlqaZpQrfbBdu2R6/G19zX6XSgh6RX5ubyHCM8nqSID6ICrGiZjGYYxojEsiw4PDwMSL5VKsC8Yf4VRYFzMzMaxwjlJSlCyAQ9l0CW44PBADzXhe7xMdi9HtTrdYjFYkDQL0cn4Xdq2/EAE+InCnvADTf2eah4Sx9vExQjkqXT6aAERICMewd/UAp/IeYANM2joxt+q5VI+ieq2i0Wg3l6DNzHwTERPgo1ko7XBXj3vdlsT2F+UuhIhYkp7u7CarkcrFOCtR3H5JiwbAIeImjT/YQKKBtGjRFCU5IUgFRe7fF4cCNVIPMYo3VKqxwjyNAXNepuopyqnld602qVsfRpEkkz+GFL1wPj6ySXBpJtWVa5xlhpcyhBNwpZHmtX8AGgfIExo0ZpzkWVTBGiXCSEaHh62/PoR0p/vHaczxXGnj4bSo+G78lELU80h1uogBwWLf5YlsPmgDEd4M236xjm+8nm4IuE/9u+/PH2JXZfbwz4zw1WbO+SQPpXfwG/BBgAhCNZiSb/pOQAAAAASUVORK5CYII=)\"\n    },\n    success: {\n      \"color\": \"#468847\",\n      \"background-color\": \"#DFF0D8\",\n      \"border-color\": \"#D6E9C6\",\n      \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAutJREFUeNq0lctPE0Ecx38zu/RFS1EryqtgJFA08YCiMZIAQQ4eRG8eDGdPJiYeTIwHTfwPiAcvXIwXLwoXPaDxkWgQ6islKlJLSQWLUraPLTv7Gme32zoF9KSTfLO7v53vZ3d/M7/fIth+IO6INt2jjoA7bjHCJoAlzCRw59YwHYjBnfMPqAKWQYKjGkfCJqAF0xwZjipQtA3MxeSG87VhOOYegVrUCy7UZM9S6TLIdAamySTclZdYhFhRHloGYg7mgZv1Zzztvgud7V1tbQ2twYA34LJmF4p5dXF1KTufnE+SxeJtuCZNsLDCQU0+RyKTF27Unw101l8e6hns3u0PBalORVVVkcaEKBJDgV3+cGM4tKKmI+ohlIGnygKX00rSBfszz/n2uXv81wd6+rt1orsZCHRdr1Imk2F2Kob3hutSxW8thsd8AXNaln9D7CTfA6O+0UgkMuwVvEFFUbbAcrkcTA8+AtOk8E6KiQiDmMFSDqZItAzEVQviRkdDdaFgPp8HSZKAEAL5Qh7Sq2lIJBJwv2scUqkUnKoZgNhcDKhKg5aH+1IkcouCAdFGAQsuWZYhOjwFHQ96oagWgRoUov1T9kRBEODAwxM2QtEUl+Wp+Ln9VRo6BcMw4ErHRYjH4/B26AlQoQQTRdHWwcd9AH57+UAXddvDD37DmrBBV34WfqiXPl61g+vr6xA9zsGeM9gOdsNXkgpEtTwVvwOklXLKm6+/p5ezwk4B+j6droBs2CsGa/gNs6RIxazl4Tc25mpTgw/apPR1LYlNRFAzgsOxkyXYLIM1V8NMwyAkJSctD1eGVKiq5wWjSPdjmeTkiKvVW4f2YPHWl3GAVq6ymcyCTgovM3FzyRiDe2TaKcEKsLpJvNHjZgPNqEtyi6mZIm4SRFyLMUsONSSdkPeFtY1n0mczoY3BHTLhwPRy9/lzcziCw9ACI+yql0VLzcGAZbYSM5CCSZg1/9oc/nn7+i8N9p/8An4JMADxhH+xHfuiKwAAAABJRU5ErkJggg==)\"\n    },\n    info: {\n      \"color\": \"#3A87AD\",\n      \"background-color\": \"#D9EDF7\",\n      \"border-color\": \"#BCE8F1\",\n      \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QYFAhkSsdes/QAAA8dJREFUOMvVlGtMW2UYx//POaWHXg6lLaW0ypAtw1UCgbniNOLcVOLmAjHZolOYlxmTGXVZdAnRfXQm+7SoU4mXaOaiZsEpC9FkiQs6Z6bdCnNYruM6KNBw6YWewzl9z+sHImEWv+vz7XmT95f/+3/+7wP814v+efDOV3/SoX3lHAA+6ODeUFfMfjOWMADgdk+eEKz0pF7aQdMAcOKLLjrcVMVX3xdWN29/GhYP7SvnP0cWfS8caSkfHZsPE9Fgnt02JNutQ0QYHB2dDz9/pKX8QjjuO9xUxd/66HdxTeCHZ3rojQObGQBcuNjfplkD3b19Y/6MrimSaKgSMmpGU5WevmE/swa6Oy73tQHA0Rdr2Mmv/6A1n9w9suQ7097Z9lM4FlTgTDrzZTu4StXVfpiI48rVcUDM5cmEksrFnHxfpTtU/3BFQzCQF/2bYVoNbH7zmItbSoMj40JSzmMyX5qDvriA7QdrIIpA+3cdsMpu0nXI8cV0MtKXCPZev+gCEM1S2NHPvWfP/hL+7FSr3+0p5RBEyhEN5JCKYr8XnASMT0xBNyzQGQeI8fjsGD39RMPk7se2bd5ZtTyoFYXftF6y37gx7NeUtJJOTFlAHDZLDuILU3j3+H5oOrD3yWbIztugaAzgnBKJuBLpGfQrS8wO4FZgV+c1IxaLgWVU0tMLEETCos4xMzEIv9cJXQcyagIwigDGwJgOAtHAwAhisQUjy0ORGERiELgG4iakkzo4MYAxcM5hAMi1WWG1yYCJIcMUaBkVRLdGeSU2995TLWzcUAzONJ7J6FBVBYIggMzmFbvdBV44Corg8vjhzC+EJEl8U1kJtgYrhCzgc/vvTwXKSib1paRFVRVORDAJAsw5FuTaJEhWM2SHB3mOAlhkNxwuLzeJsGwqWzf5TFNdKgtY5qHp6ZFf67Y/sAVadCaVY5YACDDb3Oi4NIjLnWMw2QthCBIsVhsUTU9tvXsjeq9+X1d75/KEs4LNOfcdf/+HthMnvwxOD0wmHaXr7ZItn2wuH2SnBzbZAbPJwpPx+VQuzcm7dgRCB57a1uBzUDRL4bfnI0RE0eaXd9W89mpjqHZnUI5Hh2l2dkZZUhOqpi2qSmpOmZ64Tuu9qlz/SEXo6MEHa3wOip46F1n7633eekV8ds8Wxjn37Wl63VVa+ej5oeEZ/82ZBETJjpJ1Rbij2D3Z/1trXUvLsblCK0XfOx0SX2kMsn9dX+d+7Kf6h8o4AIykuffjT8L20LU+w4AZd5VvEPY+XpWqLV327HR7DzXuDnD8r+ovkBehJ8i+y8YAAAAASUVORK5CYII=)\"\n    },\n    warn: {\n      \"color\": \"#C09853\",\n      \"background-color\": \"#FCF8E3\",\n      \"border-color\": \"#FBEED5\",\n      \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABJlBMVEXr6eb/2oD/wi7/xjr/0mP/ykf/tQD/vBj/3o7/uQ//vyL/twebhgD/4pzX1K3z8e349vK6tHCilCWbiQymn0jGworr6dXQza3HxcKkn1vWvV/5uRfk4dXZ1bD18+/52YebiAmyr5S9mhCzrWq5t6ufjRH54aLs0oS+qD751XqPhAybhwXsujG3sm+Zk0PTwG6Shg+PhhObhwOPgQL4zV2nlyrf27uLfgCPhRHu7OmLgAafkyiWkD3l49ibiAfTs0C+lgCniwD4sgDJxqOilzDWowWFfAH08uebig6qpFHBvH/aw26FfQTQzsvy8OyEfz20r3jAvaKbhgG9q0nc2LbZxXanoUu/u5WSggCtp1anpJKdmFz/zlX/1nGJiYmuq5Dx7+sAAADoPUZSAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfdBgUBGhh4aah5AAAAlklEQVQY02NgoBIIE8EUcwn1FkIXM1Tj5dDUQhPU502Mi7XXQxGz5uVIjGOJUUUW81HnYEyMi2HVcUOICQZzMMYmxrEyMylJwgUt5BljWRLjmJm4pI1hYp5SQLGYxDgmLnZOVxuooClIDKgXKMbN5ggV1ACLJcaBxNgcoiGCBiZwdWxOETBDrTyEFey0jYJ4eHjMGWgEAIpRFRCUt08qAAAAAElFTkSuQmCC)\"\n    }\n  }\n});\n"
  },
  {
    "path": "static/assets/plugins/notifyjs/dist/styles/metro/notify-metro.css",
    "content": ".notifyjs-metro-base {\n\tposition: relative;\n    min-height: 52px;\n    color:#444;\n}\n\n    .notifyjs-metro-base .image {\n        display: table;\n        position: absolute;\n        height: auto;\n        width: auto;\n        left: 25px;\n        top: 50%;\n\n        -moz-transform: translate(-50%, -50%);\n        -ms-transform: translate(-50%, -50%);\n        -o-transform: translate(-50%, -50%);\n        -webkit-transform: translate(-50%, -50%);\n        transform: translate(-50%, -50%);\n    }\n\n    .notifyjs-metro-base .text-wrapper {\n        display: inline-block;\n        vertical-align: top;\n        text-align: left;\n        margin: 10px 10px 10px 52px;\n        clear: both;\n        font-family: 'Segoe UI';\n    }\n\n    .notifyjs-metro-base .title {\n        font-size: 15px;\n        font-weight: bold;\n    }\n\n    .notifyjs-metro-base .text {\n        font-size: 12px;\n        font-weight: normal;\n        vertical-align: middle;\n    }"
  },
  {
    "path": "static/assets/plugins/notifyjs/dist/styles/metro/notify-metro.js",
    "content": "$.notify.addStyle(\"metro\", {\n    html:\n        \"<div>\" +\n            \"<div class='image' data-notify-html='image'/>\" +\n            \"<div class='text-wrapper'>\" +\n                \"<div class='title' data-notify-html='title'/>\" +\n                \"<div class='text' data-notify-html='text'/>\" +\n            \"</div>\" +\n        \"</div>\",\n    classes: {\n        error: {\n            \"color\": \"#fafafa !important\",\n            \"background-color\": \"#F71919\",\n            \"border\": \"1px solid #FF0026\"\n        },\n        success: {\n            \"background-color\": \"#32CD32\",\n            \"border\": \"1px solid #4DB149\"\n        },\n        info: {\n            \"color\": \"#fafafa !important\",\n            \"background-color\": \"#1E90FF\",\n            \"border\": \"1px solid #1E90FF\"\n        },\n        warning: {\n            \"background-color\": \"#FAFA47\",\n            \"border\": \"1px solid #EEEE45\"\n        },\n        black: {\n            \"color\": \"#fafafa !important\",\n            \"background-color\": \"#333\",\n            \"border\": \"1px solid #000\"\n        },\n        white: {\n            \"background-color\": \"#f1f1f1\",\n            \"border\": \"1px solid #ddd\"\n        }\n    }\n});"
  },
  {
    "path": "static/assets/plugins/notifyjs/src/notify.coffee",
    "content": "\n'use strict'\n\n#plugin constants\npluginName = 'notify'\npluginClassName = pluginName+'js'\nblankFieldName = pluginName+\"!blank\"\n\n# ================================\n#  POSITIONING\n# ================================\n\npositions =\n  t: 'top'\n  m: 'middle'\n  b: 'bottom'\n  l: 'left'\n  c: 'center'\n  r: 'right'\nhAligns = ['l','c','r']\nvAligns = ['t','m','b']\nmainPositions = ['t','b','l','r']\n#positions mapped to opposites\nopposites =\n  t: 'b'\n  m: null\n  b: 't'\n  l: 'r'\n  c: null\n  r: 'l'\n\nparsePosition = (str) ->\n  pos = []\n  $.each str.split(/\\W+/), (i,word) ->\n    w = word.toLowerCase().charAt(0)\n    pos.push w if positions[w]\n  pos\n\n# ================================\n#  STYLES\n# ================================\nstyles = {}\n\ncoreStyle =\n  name: 'core'\n  html: \"\"\"\n    <div class=\"#{pluginClassName}-wrapper\">\n      <div class=\"#{pluginClassName}-arrow\"></div>\n      <div class=\"#{pluginClassName}-container\"></div>\n    </div>\n  \"\"\"\n    #   <div class=\"#{pluginClassName}-debug\"></div>\n    # .#{pluginClassName}-debug {\n    #   position: absolute;\n    #   border: 3px solid red;\n    #   height: 0;\n    #   width: 0;\n    # }\n  css: \"\"\"\n    .#{pluginClassName}-corner {\n      position: fixed;\n      margin: 5px;\n      z-index: 1050;\n    }\n\n    .#{pluginClassName}-corner .#{pluginClassName}-wrapper,\n    .#{pluginClassName}-corner .#{pluginClassName}-container {\n      position: relative;\n      display: block;\n      height: inherit;\n      width: inherit;\n      margin: 3px;\n    }\n\n    .#{pluginClassName}-wrapper {\n      z-index: 1;\n      position: absolute;\n      display: inline-block;\n      height: 0;\n      width: 0;\n    }\n\n    .#{pluginClassName}-container {\n      display: none;\n      z-index: 1;\n      position: absolute;\n    }\n\n    .#{pluginClassName}-hidable {\n      cursor: pointer;\n    }\n\n    [data-notify-text],[data-notify-html] {\n      position: relative;\n    }\n\n    .#{pluginClassName}-arrow {\n      position: absolute;\n      z-index: 2;\n      width: 0;\n      height: 0;\n    }\n  \"\"\"\n\nstylePrefixes =\n  \"border-radius\": [\"-webkit-\", \"-moz-\"]\n\ngetStyle = (name) ->\n  styles[name]\n\naddStyle = (name, def) ->\n\n  unless name\n    throw \"Missing Style name\"\n  unless def\n    throw \"Missing Style definition\"\n  unless def.html\n    throw \"Missing Style HTML\"\n\n  if styles[name]?.cssElem\n    if window.console\n      console.warn \"#{pluginName}: overwriting style '#{name}'\"\n    styles[name].cssElem.remove()\n\n  def.name = name\n  styles[name] = def\n\n  cssText = \"\"\n  if def.classes\n    $.each def.classes, (className, props) ->\n      cssText += \".#{pluginClassName}-#{def.name}-#{className} {\\n\"\n      $.each props, (name, val) ->\n        #vendor prefixes\n        if stylePrefixes[name]\n          $.each stylePrefixes[name], (i, prefix) ->\n            cssText += \"  #{prefix}#{name}: #{val};\\n\"\n        #add prop\n        cssText += \"  #{name}: #{val};\\n\"\n      cssText += \"}\\n\"\n  if def.css\n    cssText += \"\"\"\n      /* styles for #{def.name} */\n      #{def.css}\n    \"\"\"\n\n  if cssText\n    def.cssElem = insertCSS cssText\n    def.cssElem.attr('id', \"notify-#{def.name}\")\n\n  #precompute usable text fields\n  fields = {}\n  elem = $(def.html)\n  findFields 'html', elem, fields\n  findFields 'text', elem, fields\n  def.fields = fields\n\ninsertCSS = (cssText) ->\n\n  elem = createElem(\"style\")\n  elem.attr 'type', 'text/css'\n  $(\"head\").append elem\n  try\n    elem.html cssText\n  catch e #ie fix\n    elem[0].styleSheet.cssText = cssText\n  elem\n\n# style.html helper\nfindFields = (type, elem, fields) ->\n  type = 'text' if type isnt 'html'\n  attr = \"data-notify-#{type}\"\n  find(elem,\"[#{attr}]\").each ->\n    name = $(@).attr attr\n    name = blankFieldName unless name\n    fields[name] = type\n\nfind = (elem, selector) ->\n  if elem.is(selector) then elem else elem.find selector\n\n# ================================\n#  OPTIONS\n# ================================\n\n#overridable options\npluginOptions =\n  clickToHide: true\n  autoHide: true\n  autoHideDelay: 5000\n  arrowShow: true\n  arrowSize: 5\n  breakNewLines: true\n  # autoReposition: true\n  elementPosition: 'bottom'\n  globalPosition: 'top right'\n  style: 'bootstrap'\n  className: 'error'\n  showAnimation: 'slideDown'\n  showDuration: 400\n  hideAnimation: 'slideUp'\n  hideDuration: 200\n  gap: 5\n\ninherit = (a, b) ->\n  F = () ->\n  F.prototype = a\n  $.extend true, new F(), b\n\ndefaults = (opts) ->\n  $.extend pluginOptions, opts\n\n# ================================\n#  DOM MANIPULATION\n# ================================\n\n# plugin helpers\ncreateElem = (tag) ->\n  $ \"<#{tag}></#{tag}>\"\n\n# references to global anchor positions\nglobalAnchors = {}\n\n#gets first on n radios, and gets the fancy stylised input for hidden inputs\ngetAnchorElement = (element) ->\n  #choose the first of n radios\n  if element.is('[type=radio]')\n    radios = element.parents('form:first').find('[type=radio]').filter (i, e) ->\n      $(e).attr('name') is element.attr('name')\n    element = radios.first()\n  #custom-styled inputs - find thier real element\n  element\n\nincr = (obj, pos, val) ->\n  # console.log \"incr ---- #{pos} #{val} (#{typeof val})\"\n  if typeof val is 'string'\n    val = parseInt val, 10\n  else if typeof val isnt 'number'\n    return\n\n  return if isNaN val\n\n  opp = positions[opposites[pos.charAt(0)]]\n  temp = pos\n\n  #use the opposite if exists\n  if obj[opp] isnt `undefined`\n    pos = positions[opp.charAt(0)]\n    val = -val\n\n  if obj[pos] is `undefined`\n    obj[pos] = val\n  else\n    obj[pos] += val\n  null\n\nrealign = (alignment, inner, outer) ->\n  return if alignment in ['l','t']\n    0\n  else if alignment in ['c','m']\n    outer/2 - inner/2\n  else if alignment in ['r','b']\n    outer - inner\n  throw \"Invalid alignment\"\n\nencode = (text) ->\n  encode.e = encode.e or createElem \"div\"\n  encode.e.text(text).html()\n\n# ================================\n#  NOTIFY CLASS\n# ================================\n\n#define plugin\nclass Notification\n\n  #setup instance variables\n  constructor: (elem, data, options) ->\n    options = {className: options} if typeof options is 'string'\n    @options = inherit pluginOptions, if $.isPlainObject(options) then options else {}\n\n    #load style html into @userContainer\n    @loadHTML()\n\n    @wrapper = $(coreStyle.html)\n    @wrapper.addClass \"#{pluginClassName}-hidable\" if @options.clickToHide\n    @wrapper.data pluginClassName, @\n    @arrow = @wrapper.find \".#{pluginClassName}-arrow\"\n    @container = @wrapper.find \".#{pluginClassName}-container\"\n    @container.append @userContainer\n\n    if elem and elem.length\n      @elementType = elem.attr('type')\n      @originalElement = elem\n      @elem = getAnchorElement(elem)\n      @elem.data pluginClassName, @\n      # add into dom above elem\n      @elem.before @wrapper\n\n    @container.hide()\n    @run(data)\n\n  loadHTML: ->\n    style = @getStyle()\n    @userContainer = $(style.html)\n    @userFields = style.fields\n\n  show: (show, userCallback) ->\n\n    callback = =>\n      @destroy() if not show and not @elem\n      userCallback() if userCallback\n\n    hidden = @container.parent().parents(':hidden').length > 0\n\n    elems = @container.add @arrow\n    args = []\n\n    if hidden and show\n      fn = 'show'\n    else if hidden and not show\n      fn = 'hide'\n    else if not hidden and show\n      fn = @options.showAnimation\n      args.push @options.showDuration\n    else if not hidden and not show\n      fn = @options.hideAnimation\n      args.push @options.hideDuration\n    else\n      return callback()\n\n    args.push callback\n\n    elems[fn].apply elems, args\n\n\n  setGlobalPosition: () ->\n    [pMain, pAlign] = @getPosition()\n\n    main = positions[pMain]\n    align = positions[pAlign]\n\n    key = pMain+\"|\"+pAlign\n    anchor = globalAnchors[key]\n    unless anchor\n      anchor = globalAnchors[key] = createElem(\"div\")\n      css = {}\n      css[main] = 0\n      if align is 'middle'\n        css.top = '45%'\n      else if align is 'center'\n        css.left = '45%'\n      else\n        css[align] = 0\n      anchor.css(css).addClass(\"#{pluginClassName}-corner\")\n      $(\"body\").append anchor\n\n    anchor.prepend @wrapper\n\n  setElementPosition: () ->\n    position = @getPosition()\n\n    [pMain, pAlign, pArrow] = position\n\n    #grab some dimensions\n    elemPos = @elem.position()\n    elemH = @elem.outerHeight()\n    elemW = @elem.outerWidth()\n    elemIH = @elem.innerHeight()\n    elemIW = @elem.innerWidth()\n    wrapPos = @wrapper.position()\n    contH = @container.height()\n    contW = @container.width()\n\n\n    #start calculations\n    mainFull = positions[pMain]\n    opp = opposites[pMain]\n    oppFull = positions[opp]\n    #initial positioning\n    css = {}\n    css[oppFull] = if pMain is 'b'\n      elemH\n    else if pMain is 'r'\n      elemW\n    else\n      0\n\n    #correct for elem-wrapper offset\n    # unless navigator.userAgent.match /MSIE/\n    incr css, 'top', elemPos.top - wrapPos.top\n    incr css, 'left', elemPos.left - wrapPos.left\n\n    #correct for margins\n    for pos in ['top', 'left']\n      margin = parseInt @elem.css(\"margin-#{pos}\"), 10\n      incr css, pos, margin if margin\n      #correct for paddings (only for inline)\n      # if /^inline/.test @elem.css('display')\n      #   padding = parseInt @elem.css(\"padding-#{pos}\"), 10\n      #   incr css, pos, -padding if padding\n\n    #add gap\n    gap = Math.max 0, @options.gap - if @options.arrowShow then arrowSize else 0\n    incr css, oppFull, gap\n\n    #calculate arrow\n    if not @options.arrowShow\n      @arrow.hide()\n    else\n      arrowSize = @options.arrowSize\n      arrowCss = $.extend {}, css\n      arrowColor = @userContainer.css(\"border-color\") or\n                   @userContainer.css(\"background-color\") or\n                   'white'\n      #build arrow\n      for pos in mainPositions\n        posFull = positions[pos]\n        continue if pos is opp\n        color = if posFull is mainFull then arrowColor else 'transparent'\n        arrowCss[\"border-#{posFull}\"] = \"#{arrowSize}px solid #{color}\"\n      #add some room for the arrow\n      incr css, positions[opp], arrowSize\n      incr arrowCss, positions[pAlign], arrowSize*2 if pAlign in mainPositions\n\n    #calculate container alignment\n    if pMain in vAligns\n      incr css, 'left', realign(pAlign, contW, elemW)\n      incr arrowCss, 'left', realign(pAlign, arrowSize, elemIW) if arrowCss\n    else if pMain in hAligns\n      incr css, 'top', realign(pAlign, contH, elemH)\n      incr arrowCss, 'top', realign(pAlign, arrowSize, elemIH) if arrowCss\n\n    css.display = 'block' if @container.is(\":visible\")\n    #apply css\n    @container.removeAttr('style').css css\n    @arrow.removeAttr('style').css(arrowCss) if arrowCss\n\n  getPosition: ->\n\n    text = @options.position or if @elem then @options.elementPosition else @options.globalPosition\n    \n    pos = parsePosition text\n\n    #validate position\n    pos[0] = 'b' if pos.length is 0\n    if pos[0] not in mainPositions\n      throw \"Must be one of [#{mainPositions}]\"\n\n    #validate alignment\n    if pos.length is 1 or\n       (pos[0] in vAligns and pos[1] not in hAligns) or\n       (pos[0] in hAligns and pos[1] not in vAligns)\n      pos[1] = if pos[0] in hAligns then 'm' else 'l'\n\n    if pos.length is 2\n      pos[2] = pos[1]\n\n    return pos\n\n  getStyle: (name) ->\n    name = @options.style unless name\n    name = 'default' unless name\n    style = styles[name]\n    throw \"Missing style: #{name}\"unless style\n    style\n\n  updateClasses: ->\n    classes = ['base']\n\n    if $.isArray @options.className\n      classes = classes.concat @options.className\n    else if @options.className\n      classes.push @options.className\n\n    style = @getStyle()\n    classes = $.map(classes, (n) -> \"#{pluginClassName}-#{style.name}-#{n}\").join ' '\n\n    @userContainer.attr 'class', classes\n\n  #run plugin\n  run: (data, options) ->\n    #update options\n    if $.isPlainObject(options)\n      $.extend @options, options\n    #shortcut special case\n    else if $.type(options) is 'string'\n      @options.className = options\n\n    if @container and not data\n      @show false\n      return\n    else if not @container and not data\n      return\n\n    datas = {}\n    if $.isPlainObject data\n      datas = data\n    else\n      datas[blankFieldName] = data\n\n    for name, d of datas\n      type = @userFields[name]\n      continue unless type\n      if type is 'text'\n        #escape\n        d = encode(d)\n        d = d.replace(/\\n/g,'<br/>') if @options.breakNewLines\n      #update content\n      value = if name is blankFieldName then '' else '='+name\n      find(@userContainer,\"[data-notify-#{type}#{value}]\").html(d)\n\n    #set styles\n    @updateClasses()\n\n    #positioning\n    if @elem\n      @setElementPosition()\n    else\n      @setGlobalPosition()\n\n    @show true\n\n    #autohide\n    if @options.autoHide\n      clearTimeout @autohideTimer\n      @autohideTimer = setTimeout =>\n        @show false\n      , @options.autoHideDelay\n\n  destroy: ->\n    @wrapper.remove()\n\n\n# ================================\n#  API\n# ================================\n\n# $.pluginName( { ...  } ) changes options for all instances\n$[pluginName] = (elem, data, options) ->\n  if (elem and elem.nodeName) or elem.jquery\n    $(elem)[pluginName](data, options)\n  else\n    options = data\n    data = elem\n    new Notification null, data, options\n  elem\n\n# $( ... ).pluginName( { .. } ) creates a cached instance on each\n$.fn[pluginName] = (data, options) ->\n  $(@).each ->\n    inst = getAnchorElement($(@)).data(pluginClassName)\n    if inst\n      inst.run data, options\n    else\n      new Notification $(@), data, options\n  @\n\n#extra methods\n$.extend $[pluginName], { defaults, addStyle, pluginOptions, getStyle, insertCSS }\n\n#when ready\n$ ->\n  #insert default style\n  insertCSS(coreStyle.css).attr('id', 'core-notify')\n\n  #watch all notifications clicks\n  $(document).on 'click', \".#{pluginClassName}-hidable\", (e) ->\n    $(@).trigger 'notify-hide'\n\n  $(document).on 'notify-hide', \".#{pluginClassName}-wrapper\", (e) ->\n    $(@).data(pluginClassName)?.show false\n\n"
  },
  {
    "path": "static/assets/plugins/notifyjs/src/styles/STYLES-README.md",
    "content": "* Styles in CoffeeScript go here, which will be compiled into `dist/styles`\n* Styles in JavaScript can go straight in `dist/styles/`"
  },
  {
    "path": "static/assets/plugins/notifyjs/src/styles/bootstrap/notify-bootstrap.coffee",
    "content": "\n$.notify.addStyle \"bootstrap\",\n  html: \"\"\"\n    <div>\n    <span data-notify-text></span>\n    </div>\n  \"\"\"\n  classes:\n    base:\n      \"font-weight\": \"bold\"\n      \"padding\": \"8px 15px 8px 14px\"\n      \"text-shadow\": \"0 1px 0 rgba(255, 255, 255, 0.5)\"\n      \"background-color\": \"#fcf8e3\"\n      \"border\": \"1px solid #fbeed5\"\n      \"border-radius\": \"4px\"\n      \"white-space\": \"nowrap\"\n      #for background-image\n      \"padding-left\": \"25px\"\n      \"background-repeat\": \"no-repeat\"\n      \"background-position\": \"3px 7px\"\n    error:\n      \"color\": \"#B94A48\"\n      \"background-color\": \"#F2DEDE\"\n      \"border-color\": \"#EED3D7\"\n      \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAtRJREFUeNqkVc1u00AQHq+dOD+0poIQfkIjalW0SEGqRMuRnHos3DjwAH0ArlyQeANOOSMeAA5VjyBxKBQhgSpVUKKQNGloFdw4cWw2jtfMOna6JOUArDTazXi/b3dm55socPqQhFka++aHBsI8GsopRJERNFlY88FCEk9Yiwf8RhgRyaHFQpPHCDmZG5oX2ui2yilkcTT1AcDsbYC1NMAyOi7zTX2Agx7A9luAl88BauiiQ/cJaZQfIpAlngDcvZZMrl8vFPK5+XktrWlx3/ehZ5r9+t6e+WVnp1pxnNIjgBe4/6dAysQc8dsmHwPcW9C0h3fW1hans1ltwJhy0GxK7XZbUlMp5Ww2eyan6+ft/f2FAqXGK4CvQk5HueFz7D6GOZtIrK+srupdx1GRBBqNBtzc2AiMr7nPplRdKhb1q6q6zjFhrklEFOUutoQ50xcX86ZlqaZpQrfbBdu2R6/G19zX6XSgh6RX5ubyHCM8nqSID6ICrGiZjGYYxojEsiw4PDwMSL5VKsC8Yf4VRYFzMzMaxwjlJSlCyAQ9l0CW44PBADzXhe7xMdi9HtTrdYjFYkDQL0cn4Xdq2/EAE+InCnvADTf2eah4Sx9vExQjkqXT6aAERICMewd/UAp/IeYANM2joxt+q5VI+ieq2i0Wg3l6DNzHwTERPgo1ko7XBXj3vdlsT2F+UuhIhYkp7u7CarkcrFOCtR3H5JiwbAIeImjT/YQKKBtGjRFCU5IUgFRe7fF4cCNVIPMYo3VKqxwjyNAXNepuopyqnld602qVsfRpEkkz+GFL1wPj6ySXBpJtWVa5xlhpcyhBNwpZHmtX8AGgfIExo0ZpzkWVTBGiXCSEaHh62/PoR0p/vHaczxXGnj4bSo+G78lELU80h1uogBwWLf5YlsPmgDEd4M236xjm+8nm4IuE/9u+/PH2JXZfbwz4zw1WbO+SQPpXfwG/BBgAhCNZiSb/pOQAAAAASUVORK5CYII=)\"\n    success:\n      \"color\": \"#468847\"\n      \"background-color\": \"#DFF0D8\"\n      \"border-color\": \"#D6E9C6\"\n      \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAutJREFUeNq0lctPE0Ecx38zu/RFS1EryqtgJFA08YCiMZIAQQ4eRG8eDGdPJiYeTIwHTfwPiAcvXIwXLwoXPaDxkWgQ6islKlJLSQWLUraPLTv7Gme32zoF9KSTfLO7v53vZ3d/M7/fIth+IO6INt2jjoA7bjHCJoAlzCRw59YwHYjBnfMPqAKWQYKjGkfCJqAF0xwZjipQtA3MxeSG87VhOOYegVrUCy7UZM9S6TLIdAamySTclZdYhFhRHloGYg7mgZv1Zzztvgud7V1tbQ2twYA34LJmF4p5dXF1KTufnE+SxeJtuCZNsLDCQU0+RyKTF27Unw101l8e6hns3u0PBalORVVVkcaEKBJDgV3+cGM4tKKmI+ohlIGnygKX00rSBfszz/n2uXv81wd6+rt1orsZCHRdr1Imk2F2Kob3hutSxW8thsd8AXNaln9D7CTfA6O+0UgkMuwVvEFFUbbAcrkcTA8+AtOk8E6KiQiDmMFSDqZItAzEVQviRkdDdaFgPp8HSZKAEAL5Qh7Sq2lIJBJwv2scUqkUnKoZgNhcDKhKg5aH+1IkcouCAdFGAQsuWZYhOjwFHQ96oagWgRoUov1T9kRBEODAwxM2QtEUl+Wp+Ln9VRo6BcMw4ErHRYjH4/B26AlQoQQTRdHWwcd9AH57+UAXddvDD37DmrBBV34WfqiXPl61g+vr6xA9zsGeM9gOdsNXkgpEtTwVvwOklXLKm6+/p5ezwk4B+j6droBs2CsGa/gNs6RIxazl4Tc25mpTgw/apPR1LYlNRFAzgsOxkyXYLIM1V8NMwyAkJSctD1eGVKiq5wWjSPdjmeTkiKvVW4f2YPHWl3GAVq6ymcyCTgovM3FzyRiDe2TaKcEKsLpJvNHjZgPNqEtyi6mZIm4SRFyLMUsONSSdkPeFtY1n0mczoY3BHTLhwPRy9/lzcziCw9ACI+yql0VLzcGAZbYSM5CCSZg1/9oc/nn7+i8N9p/8An4JMADxhH+xHfuiKwAAAABJRU5ErkJggg==)\"\n    info:\n      \"color\": \"#3A87AD\"\n      \"background-color\": \"#D9EDF7\"\n      \"border-color\": \"#BCE8F1\"\n      \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QYFAhkSsdes/QAAA8dJREFUOMvVlGtMW2UYx//POaWHXg6lLaW0ypAtw1UCgbniNOLcVOLmAjHZolOYlxmTGXVZdAnRfXQm+7SoU4mXaOaiZsEpC9FkiQs6Z6bdCnNYruM6KNBw6YWewzl9z+sHImEWv+vz7XmT95f/+3/+7wP814v+efDOV3/SoX3lHAA+6ODeUFfMfjOWMADgdk+eEKz0pF7aQdMAcOKLLjrcVMVX3xdWN29/GhYP7SvnP0cWfS8caSkfHZsPE9Fgnt02JNutQ0QYHB2dDz9/pKX8QjjuO9xUxd/66HdxTeCHZ3rojQObGQBcuNjfplkD3b19Y/6MrimSaKgSMmpGU5WevmE/swa6Oy73tQHA0Rdr2Mmv/6A1n9w9suQ7097Z9lM4FlTgTDrzZTu4StXVfpiI48rVcUDM5cmEksrFnHxfpTtU/3BFQzCQF/2bYVoNbH7zmItbSoMj40JSzmMyX5qDvriA7QdrIIpA+3cdsMpu0nXI8cV0MtKXCPZev+gCEM1S2NHPvWfP/hL+7FSr3+0p5RBEyhEN5JCKYr8XnASMT0xBNyzQGQeI8fjsGD39RMPk7se2bd5ZtTyoFYXftF6y37gx7NeUtJJOTFlAHDZLDuILU3j3+H5oOrD3yWbIztugaAzgnBKJuBLpGfQrS8wO4FZgV+c1IxaLgWVU0tMLEETCos4xMzEIv9cJXQcyagIwigDGwJgOAtHAwAhisQUjy0ORGERiELgG4iakkzo4MYAxcM5hAMi1WWG1yYCJIcMUaBkVRLdGeSU2995TLWzcUAzONJ7J6FBVBYIggMzmFbvdBV44Corg8vjhzC+EJEl8U1kJtgYrhCzgc/vvTwXKSib1paRFVRVORDAJAsw5FuTaJEhWM2SHB3mOAlhkNxwuLzeJsGwqWzf5TFNdKgtY5qHp6ZFf67Y/sAVadCaVY5YACDDb3Oi4NIjLnWMw2QthCBIsVhsUTU9tvXsjeq9+X1d75/KEs4LNOfcdf/+HthMnvwxOD0wmHaXr7ZItn2wuH2SnBzbZAbPJwpPx+VQuzcm7dgRCB57a1uBzUDRL4bfnI0RE0eaXd9W89mpjqHZnUI5Hh2l2dkZZUhOqpi2qSmpOmZ64Tuu9qlz/SEXo6MEHa3wOip46F1n7633eekV8ds8Wxjn37Wl63VVa+ej5oeEZ/82ZBETJjpJ1Rbij2D3Z/1trXUvLsblCK0XfOx0SX2kMsn9dX+d+7Kf6h8o4AIykuffjT8L20LU+w4AZd5VvEPY+XpWqLV327HR7DzXuDnD8r+ovkBehJ8i+y8YAAAAASUVORK5CYII=)\"\n    warn:\n      \"color\": \"#C09853\"\n      \"background-color\": \"#FCF8E3\"\n      \"border-color\": \"#FBEED5\"\n      \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABJlBMVEXr6eb/2oD/wi7/xjr/0mP/ykf/tQD/vBj/3o7/uQ//vyL/twebhgD/4pzX1K3z8e349vK6tHCilCWbiQymn0jGworr6dXQza3HxcKkn1vWvV/5uRfk4dXZ1bD18+/52YebiAmyr5S9mhCzrWq5t6ufjRH54aLs0oS+qD751XqPhAybhwXsujG3sm+Zk0PTwG6Shg+PhhObhwOPgQL4zV2nlyrf27uLfgCPhRHu7OmLgAafkyiWkD3l49ibiAfTs0C+lgCniwD4sgDJxqOilzDWowWFfAH08uebig6qpFHBvH/aw26FfQTQzsvy8OyEfz20r3jAvaKbhgG9q0nc2LbZxXanoUu/u5WSggCtp1anpJKdmFz/zlX/1nGJiYmuq5Dx7+sAAADoPUZSAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfdBgUBGhh4aah5AAAAlklEQVQY02NgoBIIE8EUcwn1FkIXM1Tj5dDUQhPU502Mi7XXQxGz5uVIjGOJUUUW81HnYEyMi2HVcUOICQZzMMYmxrEyMylJwgUt5BljWRLjmJm4pI1hYp5SQLGYxDgmLnZOVxuooClIDKgXKMbN5ggV1ACLJcaBxNgcoiGCBiZwdWxOETBDrTyEFey0jYJ4eHjMGWgEAIpRFRCUt08qAAAAAElFTkSuQmCC)\"\n"
  },
  {
    "path": "static/assets/plugins/peity/jquery.peity.js",
    "content": "// Peity jQuery plugin version 3.2.0\n// (c) 2015 Ben Pickles\n//\n// http://benpickles.github.io/peity\n//\n// Released under MIT license.\n(function($, document, Math, undefined) {\n  var peity = $.fn.peity = function(type, options) {\n    if (svgSupported) {\n      this.each(function() {\n        var $this = $(this)\n        var chart = $this.data('_peity')\n\n        if (chart) {\n          if (type) chart.type = type\n          $.extend(chart.opts, options)\n        } else {\n          chart = new Peity(\n            $this,\n            type,\n            $.extend({},\n              peity.defaults[type],\n              $this.data('peity'),\n              options)\n          )\n\n          $this\n            .change(function() { chart.draw() })\n            .data('_peity', chart)\n        }\n\n        chart.draw()\n      });\n    }\n\n    return this;\n  };\n\n  var Peity = function($el, type, opts) {\n    this.$el = $el\n    this.type = type\n    this.opts = opts\n  }\n\n  var PeityPrototype = Peity.prototype\n\n  var svgElement = PeityPrototype.svgElement = function(tag, attrs) {\n    return $(\n      document.createElementNS('http://www.w3.org/2000/svg', tag)\n    ).attr(attrs)\n  }\n\n  // https://gist.github.com/madrobby/3201472\n  var svgSupported = 'createElementNS' in document && svgElement('svg', {})[0].createSVGRect\n\n  PeityPrototype.draw = function() {\n    var opts = this.opts\n    peity.graphers[this.type].call(this, opts)\n    if (opts.after) opts.after.call(this, opts)\n  }\n\n  PeityPrototype.fill = function() {\n    var fill = this.opts.fill\n\n    return $.isFunction(fill)\n      ? fill\n      : function(_, i) { return fill[i % fill.length] }\n  }\n\n  PeityPrototype.prepare = function(width, height) {\n    if (!this.$svg) {\n      this.$el.hide().after(\n        this.$svg = svgElement('svg', {\n          \"class\": \"peity\"\n        })\n      )\n    }\n\n    return this.$svg\n      .empty()\n      .data('peity', this)\n      .attr({\n        height: height,\n        width: width\n      })\n  }\n\n  PeityPrototype.values = function() {\n    return $.map(this.$el.text().split(this.opts.delimiter), function(value) {\n      return parseFloat(value)\n    })\n  }\n\n  peity.defaults = {}\n  peity.graphers = {}\n\n  peity.register = function(type, defaults, grapher) {\n    this.defaults[type] = defaults\n    this.graphers[type] = grapher\n  }\n\n  peity.register(\n    'pie',\n    {\n      fill: ['#ff9900', '#fff4dd', '#ffc66e'],\n      radius: 8\n    },\n    function(opts) {\n      if (!opts.delimiter) {\n        var delimiter = this.$el.text().match(/[^0-9\\.]/)\n        opts.delimiter = delimiter ? delimiter[0] : \",\"\n      }\n\n      var values = $.map(this.values(), function(n) {\n        return n > 0 ? n : 0\n      })\n\n      if (opts.delimiter == \"/\") {\n        var v1 = values[0]\n        var v2 = values[1]\n        values = [v1, Math.max(0, v2 - v1)]\n      }\n\n      var i = 0\n      var length = values.length\n      var sum = 0\n\n      for (; i < length; i++) {\n        sum += values[i]\n      }\n\n      if (!sum) {\n        length = 2\n        sum = 1\n        values = [0, 1]\n      }\n\n      var diameter = opts.radius * 2\n\n      var $svg = this.prepare(\n        opts.width || diameter,\n        opts.height || diameter\n      )\n\n      var width = $svg.width()\n        , height = $svg.height()\n        , cx = width / 2\n        , cy = height / 2\n\n      var radius = Math.min(cx, cy)\n        , innerRadius = opts.innerRadius\n\n      if (this.type == 'donut' && !innerRadius) {\n        innerRadius = radius * 0.5\n      }\n\n      var pi = Math.PI\n      var fill = this.fill()\n\n      var scale = this.scale = function(value, radius) {\n        var radians = value / sum * pi * 2 - pi / 2\n\n        return [\n          radius * Math.cos(radians) + cx,\n          radius * Math.sin(radians) + cy\n        ]\n      }\n\n      var cumulative = 0\n\n      for (i = 0; i < length; i++) {\n        var value = values[i]\n          , portion = value / sum\n          , $node\n\n        if (portion == 0) continue\n\n        if (portion == 1) {\n          if (innerRadius) {\n            var x2 = cx - 0.01\n              , y1 = cy - radius\n              , y2 = cy - innerRadius\n\n            $node = svgElement('path', {\n              d: [\n                'M', cx, y1,\n                'A', radius, radius, 0, 1, 1, x2, y1,\n                'L', x2, y2,\n                'A', innerRadius, innerRadius, 0, 1, 0, cx, y2\n              ].join(' ')\n            })\n          } else {\n            $node = svgElement('circle', {\n              cx: cx,\n              cy: cy,\n              r: radius\n            })\n          }\n        } else {\n          var cumulativePlusValue = cumulative + value\n\n          var d = ['M'].concat(\n            scale(cumulative, radius),\n            'A', radius, radius, 0, portion > 0.5 ? 1 : 0, 1,\n            scale(cumulativePlusValue, radius),\n            'L'\n          )\n\n          if (innerRadius) {\n            d = d.concat(\n              scale(cumulativePlusValue, innerRadius),\n              'A', innerRadius, innerRadius, 0, portion > 0.5 ? 1 : 0, 0,\n              scale(cumulative, innerRadius)\n            )\n          } else {\n            d.push(cx, cy)\n          }\n\n          cumulative += value\n\n          $node = svgElement('path', {\n            d: d.join(\" \")\n          })\n        }\n\n        $node.attr('fill', fill.call(this, value, i, values))\n\n        $svg.append($node)\n      }\n    }\n  )\n\n  peity.register(\n    'donut',\n    $.extend(true, {}, peity.defaults.pie),\n    function(opts) {\n      peity.graphers.pie.call(this, opts)\n    }\n  )\n\n  peity.register(\n    \"line\",\n    {\n      delimiter: \",\",\n      fill: \"#c6d9fd\",\n      height: 16,\n      min: 0,\n      stroke: \"#4d89f9\",\n      strokeWidth: 1,\n      width: 32\n    },\n    function(opts) {\n      var values = this.values()\n      if (values.length == 1) values.push(values[0])\n      var max = Math.max.apply(Math, opts.max == undefined ? values : values.concat(opts.max))\n        , min = Math.min.apply(Math, opts.min == undefined ? values : values.concat(opts.min))\n\n      var $svg = this.prepare(opts.width, opts.height)\n        , strokeWidth = opts.strokeWidth\n        , width = $svg.width()\n        , height = $svg.height() - strokeWidth\n        , diff = max - min\n\n      var xScale = this.x = function(input) {\n        return input * (width / (values.length - 1))\n      }\n\n      var yScale = this.y = function(input) {\n        var y = height\n\n        if (diff) {\n          y -= ((input - min) / diff) * height\n        }\n\n        return y + strokeWidth / 2\n      }\n\n      var zero = yScale(Math.max(min, 0))\n        , coords = [0, zero]\n\n      for (var i = 0; i < values.length; i++) {\n        coords.push(\n          xScale(i),\n          yScale(values[i])\n        )\n      }\n\n      coords.push(width, zero)\n\n      if (opts.fill) {\n        $svg.append(\n          svgElement('polygon', {\n            fill: opts.fill,\n            points: coords.join(' ')\n          })\n        )\n      }\n\n      if (strokeWidth) {\n        $svg.append(\n          svgElement('polyline', {\n            fill: 'none',\n            points: coords.slice(2, coords.length - 2).join(' '),\n            stroke: opts.stroke,\n            'stroke-width': strokeWidth,\n            'stroke-linecap': 'square'\n          })\n        )\n      }\n    }\n  );\n\n  peity.register(\n    'bar',\n    {\n      delimiter: \",\",\n      fill: [\"#4D89F9\"],\n      height: 16,\n      min: 0,\n      padding: 0.1,\n      width: 32\n    },\n    function(opts) {\n      var values = this.values()\n        , max = Math.max.apply(Math, opts.max == undefined ? values : values.concat(opts.max))\n        , min = Math.min.apply(Math, opts.min == undefined ? values : values.concat(opts.min))\n\n      var $svg = this.prepare(opts.width, opts.height)\n        , width = $svg.width()\n        , height = $svg.height()\n        , diff = max - min\n        , padding = opts.padding\n        , fill = this.fill()\n\n      var xScale = this.x = function(input) {\n        return input * width / values.length\n      }\n\n      var yScale = this.y = function(input) {\n        return height - (\n          diff\n            ? ((input - min) / diff) * height\n            : 1\n        )\n      }\n\n      for (var i = 0; i < values.length; i++) {\n        var x = xScale(i + padding)\n          , w = xScale(i + 1 - padding) - x\n          , value = values[i]\n          , valueY = yScale(value)\n          , y1 = valueY\n          , y2 = valueY\n          , h\n\n        if (!diff) {\n          h = 1\n        } else if (value < 0) {\n          y1 = yScale(Math.min(max, 0))\n        } else {\n          y2 = yScale(Math.max(min, 0))\n        }\n\n        h = y2 - y1\n\n        if (h == 0) {\n          h = 1\n          if (max > 0 && diff) y1--\n        }\n\n        $svg.append(\n          svgElement('rect', {\n            fill: fill.call(this, value, i, values),\n            x: x,\n            y: y1,\n            width: w,\n            height: h\n          })\n        )\n      }\n    }\n  );\n})(jQuery, document, Math);\n"
  },
  {
    "path": "static/assets/plugins/raphael/raphael-min.js",
    "content": "// ┌────────────────────────────────────────────────────────────────────┐ \\\\\n// │ Raphaël 2.1.4 - JavaScript Vector Library                          │ \\\\\n// ├────────────────────────────────────────────────────────────────────┤ \\\\\n// │ Copyright © 2008-2012 Dmitry Baranovskiy (http://raphaeljs.com)    │ \\\\\n// │ Copyright © 2008-2012 Sencha Labs (http://sencha.com)              │ \\\\\n// ├────────────────────────────────────────────────────────────────────┤ \\\\\n// │ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\\\\n// └────────────────────────────────────────────────────────────────────┘ \\\\\n!function(a){var b,c,d=\"0.4.2\",e=\"hasOwnProperty\",f=/[\\.\\/]/,g=\"*\",h=function(){},i=function(a,b){return a-b},j={n:{}},k=function(a,d){a=String(a);var e,f=c,g=Array.prototype.slice.call(arguments,2),h=k.listeners(a),j=0,l=[],m={},n=[],o=b;b=a,c=0;for(var p=0,q=h.length;q>p;p++)\"zIndex\"in h[p]&&(l.push(h[p].zIndex),h[p].zIndex<0&&(m[h[p].zIndex]=h[p]));for(l.sort(i);l[j]<0;)if(e=m[l[j++]],n.push(e.apply(d,g)),c)return c=f,n;for(p=0;q>p;p++)if(e=h[p],\"zIndex\"in e)if(e.zIndex==l[j]){if(n.push(e.apply(d,g)),c)break;do if(j++,e=m[l[j]],e&&n.push(e.apply(d,g)),c)break;while(e)}else m[e.zIndex]=e;else if(n.push(e.apply(d,g)),c)break;return c=f,b=o,n.length?n:null};k._events=j,k.listeners=function(a){var b,c,d,e,h,i,k,l,m=a.split(f),n=j,o=[n],p=[];for(e=0,h=m.length;h>e;e++){for(l=[],i=0,k=o.length;k>i;i++)for(n=o[i].n,c=[n[m[e]],n[g]],d=2;d--;)b=c[d],b&&(l.push(b),p=p.concat(b.f||[]));o=l}return p},k.on=function(a,b){if(a=String(a),\"function\"!=typeof b)return function(){};for(var c=a.split(f),d=j,e=0,g=c.length;g>e;e++)d=d.n,d=d.hasOwnProperty(c[e])&&d[c[e]]||(d[c[e]]={n:{}});for(d.f=d.f||[],e=0,g=d.f.length;g>e;e++)if(d.f[e]==b)return h;return d.f.push(b),function(a){+a==+a&&(b.zIndex=+a)}},k.f=function(a){var b=[].slice.call(arguments,1);return function(){k.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},k.stop=function(){c=1},k.nt=function(a){return a?new RegExp(\"(?:\\\\.|\\\\/|^)\"+a+\"(?:\\\\.|\\\\/|$)\").test(b):b},k.nts=function(){return b.split(f)},k.off=k.unbind=function(a,b){if(!a)return void(k._events=j={n:{}});var c,d,h,i,l,m,n,o=a.split(f),p=[j];for(i=0,l=o.length;l>i;i++)for(m=0;m<p.length;m+=h.length-2){if(h=[m,1],c=p[m].n,o[i]!=g)c[o[i]]&&h.push(c[o[i]]);else for(d in c)c[e](d)&&h.push(c[d]);p.splice.apply(p,h)}for(i=0,l=p.length;l>i;i++)for(c=p[i];c.n;){if(b){if(c.f){for(m=0,n=c.f.length;n>m;m++)if(c.f[m]==b){c.f.splice(m,1);break}!c.f.length&&delete c.f}for(d in c.n)if(c.n[e](d)&&c.n[d].f){var q=c.n[d].f;for(m=0,n=q.length;n>m;m++)if(q[m]==b){q.splice(m,1);break}!q.length&&delete c.n[d].f}}else{delete c.f;for(d in c.n)c.n[e](d)&&c.n[d].f&&delete c.n[d].f}c=c.n}},k.once=function(a,b){var c=function(){return k.unbind(a,c),b.apply(this,arguments)};return k.on(a,c)},k.version=d,k.toString=function(){return\"You are running Eve \"+d},\"undefined\"!=typeof module&&module.exports?module.exports=k:\"undefined\"!=typeof define?define(\"eve\",[],function(){return k}):a.eve=k}(window||this),function(a,b){\"function\"==typeof define&&define.amd?define([\"eve\"],function(c){return b(a,c)}):b(a,a.eve||\"function\"==typeof require&&require(\"eve\"))}(this,function(a,b){function c(a){if(c.is(a,\"function\"))return u?a():b.on(\"raphael.DOMload\",a);if(c.is(a,V))return c._engine.create[D](c,a.splice(0,3+c.is(a[0],T))).add(a);var d=Array.prototype.slice.call(arguments,0);if(c.is(d[d.length-1],\"function\")){var e=d.pop();return u?e.call(c._engine.create[D](c,d)):b.on(\"raphael.DOMload\",function(){e.call(c._engine.create[D](c,d))})}return c._engine.create[D](c,arguments)}function d(a){if(\"function\"==typeof a||Object(a)!==a)return a;var b=new a.constructor;for(var c in a)a[z](c)&&(b[c]=d(a[c]));return b}function e(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function f(a,b,c){function d(){var f=Array.prototype.slice.call(arguments,0),g=f.join(\"␀\"),h=d.cache=d.cache||{},i=d.count=d.count||[];return h[z](g)?(e(i,g),c?c(h[g]):h[g]):(i.length>=1e3&&delete h[i.shift()],i.push(g),h[g]=a[D](b,f),c?c(h[g]):h[g])}return d}function g(){return this.hex}function h(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push([\"C\",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}function i(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c}function j(a,b,c,d,e,f,g,h,j){null==j&&(j=1),j=j>1?1:0>j?0:j;for(var k=j/2,l=12,m=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],n=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],o=0,p=0;l>p;p++){var q=k*m[p]+k,r=i(q,a,c,e,g),s=i(q,b,d,f,h),t=r*r+s*s;o+=n[p]*N.sqrt(t)}return k*o}function k(a,b,c,d,e,f,g,h,i){if(!(0>i||j(a,b,c,d,e,f,g,h)<i)){var k,l=1,m=l/2,n=l-m,o=.01;for(k=j(a,b,c,d,e,f,g,h,n);Q(k-i)>o;)m/=2,n+=(i>k?1:-1)*m,k=j(a,b,c,d,e,f,g,h,n);return n}}function l(a,b,c,d,e,f,g,h){if(!(O(a,c)<P(e,g)||P(a,c)>O(e,g)||O(b,d)<P(f,h)||P(b,d)>O(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+P(a,c).toFixed(2)||n>+O(a,c).toFixed(2)||n<+P(e,g).toFixed(2)||n>+O(e,g).toFixed(2)||o<+P(b,d).toFixed(2)||o>+O(b,d).toFixed(2)||o<+P(f,h).toFixed(2)||o>+O(f,h).toFixed(2)))return{x:l,y:m}}}}function m(a,b,d){var e=c.bezierBBox(a),f=c.bezierBBox(b);if(!c.isBBoxIntersect(e,f))return d?0:[];for(var g=j.apply(0,a),h=j.apply(0,b),i=O(~~(g/5),1),k=O(~~(h/5),1),m=[],n=[],o={},p=d?0:[],q=0;i+1>q;q++){var r=c.findDotsAtSegment.apply(c,a.concat(q/i));m.push({x:r.x,y:r.y,t:q/i})}for(q=0;k+1>q;q++)r=c.findDotsAtSegment.apply(c,b.concat(q/k)),n.push({x:r.x,y:r.y,t:q/k});for(q=0;i>q;q++)for(var s=0;k>s;s++){var t=m[q],u=m[q+1],v=n[s],w=n[s+1],x=Q(u.x-t.x)<.001?\"y\":\"x\",y=Q(w.x-v.x)<.001?\"y\":\"x\",z=l(t.x,t.y,u.x,u.y,v.x,v.y,w.x,w.y);if(z){if(o[z.x.toFixed(4)]==z.y.toFixed(4))continue;o[z.x.toFixed(4)]=z.y.toFixed(4);var A=t.t+Q((z[x]-t[x])/(u[x]-t[x]))*(u.t-t.t),B=v.t+Q((z[y]-v[y])/(w[y]-v[y]))*(w.t-v.t);A>=0&&1.001>=A&&B>=0&&1.001>=B&&(d?p++:p.push({x:z.x,y:z.y,t1:P(A,1),t2:P(B,1)}))}}return p}function n(a,b,d){a=c._path2curve(a),b=c._path2curve(b);for(var e,f,g,h,i,j,k,l,n,o,p=d?0:[],q=0,r=a.length;r>q;q++){var s=a[q];if(\"M\"==s[0])e=i=s[1],f=j=s[2];else{\"C\"==s[0]?(n=[e,f].concat(s.slice(1)),e=n[6],f=n[7]):(n=[e,f,e,f,i,j,i,j],e=i,f=j);for(var t=0,u=b.length;u>t;t++){var v=b[t];if(\"M\"==v[0])g=k=v[1],h=l=v[2];else{\"C\"==v[0]?(o=[g,h].concat(v.slice(1)),g=o[6],h=o[7]):(o=[g,h,g,h,k,l,k,l],g=k,h=l);var w=m(n,o,d);if(d)p+=w;else{for(var x=0,y=w.length;y>x;x++)w[x].segment1=q,w[x].segment2=t,w[x].bez1=n,w[x].bez2=o;p=p.concat(w)}}}}}return p}function o(a,b,c,d,e,f){null!=a?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}function p(){return this.x+H+this.y+H+this.width+\" × \"+this.height}function q(a,b,c,d,e,f){function g(a){return((l*a+k)*a+j)*a}function h(a,b){var c=i(a,b);return((o*c+n)*c+m)*c}function i(a,b){var c,d,e,f,h,i;for(e=a,i=0;8>i;i++){if(f=g(e)-a,Q(f)<b)return e;if(h=(3*l*e+2*k)*e+j,Q(h)<1e-6)break;e-=f/h}if(c=0,d=1,e=a,c>e)return c;if(e>d)return d;for(;d>c;){if(f=g(e),Q(f-a)<b)return e;a>f?c=e:d=e,e=(d-c)/2+c}return e}var j=3*b,k=3*(d-b)-j,l=1-j-k,m=3*c,n=3*(e-c)-m,o=1-m-n;return h(a,1/(200*f))}function r(a,b){var c=[],d={};if(this.ms=b,this.times=1,a){for(var e in a)a[z](e)&&(d[_(e)]=a[e],c.push(_(e)));c.sort(lb)}this.anim=d,this.top=c[c.length-1],this.percents=c}function s(a,d,e,f,g,h){e=_(e);var i,j,k,l,m,n,p=a.ms,r={},s={},t={};if(f)for(v=0,x=ic.length;x>v;v++){var u=ic[v];if(u.el.id==d.id&&u.anim==a){u.percent!=e?(ic.splice(v,1),k=1):j=u,d.attr(u.totalOrigin);break}}else f=+s;for(var v=0,x=a.percents.length;x>v;v++){if(a.percents[v]==e||a.percents[v]>f*a.top){e=a.percents[v],m=a.percents[v-1]||0,p=p/a.top*(e-m),l=a.percents[v+1],i=a.anim[e];break}f&&d.attr(a.anim[a.percents[v]])}if(i){if(j)j.initstatus=f,j.start=new Date-j.ms*f;else{for(var y in i)if(i[z](y)&&(db[z](y)||d.paper.customAttributes[z](y)))switch(r[y]=d.attr(y),null==r[y]&&(r[y]=cb[y]),s[y]=i[y],db[y]){case T:t[y]=(s[y]-r[y])/p;break;case\"colour\":r[y]=c.getRGB(r[y]);var A=c.getRGB(s[y]);t[y]={r:(A.r-r[y].r)/p,g:(A.g-r[y].g)/p,b:(A.b-r[y].b)/p};break;case\"path\":var B=Kb(r[y],s[y]),C=B[1];for(r[y]=B[0],t[y]=[],v=0,x=r[y].length;x>v;v++){t[y][v]=[0];for(var D=1,F=r[y][v].length;F>D;D++)t[y][v][D]=(C[v][D]-r[y][v][D])/p}break;case\"transform\":var G=d._,H=Pb(G[y],s[y]);if(H)for(r[y]=H.from,s[y]=H.to,t[y]=[],t[y].real=!0,v=0,x=r[y].length;x>v;v++)for(t[y][v]=[r[y][v][0]],D=1,F=r[y][v].length;F>D;D++)t[y][v][D]=(s[y][v][D]-r[y][v][D])/p;else{var K=d.matrix||new o,L={_:{transform:G.transform},getBBox:function(){return d.getBBox(1)}};r[y]=[K.a,K.b,K.c,K.d,K.e,K.f],Nb(L,s[y]),s[y]=L._.transform,t[y]=[(L.matrix.a-K.a)/p,(L.matrix.b-K.b)/p,(L.matrix.c-K.c)/p,(L.matrix.d-K.d)/p,(L.matrix.e-K.e)/p,(L.matrix.f-K.f)/p]}break;case\"csv\":var M=I(i[y])[J](w),N=I(r[y])[J](w);if(\"clip-rect\"==y)for(r[y]=N,t[y]=[],v=N.length;v--;)t[y][v]=(M[v]-r[y][v])/p;s[y]=M;break;default:for(M=[][E](i[y]),N=[][E](r[y]),t[y]=[],v=d.paper.customAttributes[y].length;v--;)t[y][v]=((M[v]||0)-(N[v]||0))/p}var O=i.easing,P=c.easing_formulas[O];if(!P)if(P=I(O).match(Z),P&&5==P.length){var Q=P;P=function(a){return q(a,+Q[1],+Q[2],+Q[3],+Q[4],p)}}else P=nb;if(n=i.start||a.start||+new Date,u={anim:a,percent:e,timestamp:n,start:n+(a.del||0),status:0,initstatus:f||0,stop:!1,ms:p,easing:P,from:r,diff:t,to:s,el:d,callback:i.callback,prev:m,next:l,repeat:h||a.times,origin:d.attr(),totalOrigin:g},ic.push(u),f&&!j&&!k&&(u.stop=!0,u.start=new Date-p*f,1==ic.length))return kc();k&&(u.start=new Date-u.ms*f),1==ic.length&&jc(kc)}b(\"raphael.anim.start.\"+d.id,d,a)}}function t(a){for(var b=0;b<ic.length;b++)ic[b].el.paper==a&&ic.splice(b--,1)}c.version=\"2.1.2\",c.eve=b;var u,v,w=/[, ]+/,x={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},y=/\\{(\\d+)\\}/g,z=\"hasOwnProperty\",A={doc:document,win:a},B={was:Object.prototype[z].call(A.win,\"Raphael\"),is:A.win.Raphael},C=function(){this.ca=this.customAttributes={}},D=\"apply\",E=\"concat\",F=\"ontouchstart\"in A.win||A.win.DocumentTouch&&A.doc instanceof DocumentTouch,G=\"\",H=\" \",I=String,J=\"split\",K=\"click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel\"[J](H),L={mousedown:\"touchstart\",mousemove:\"touchmove\",mouseup:\"touchend\"},M=I.prototype.toLowerCase,N=Math,O=N.max,P=N.min,Q=N.abs,R=N.pow,S=N.PI,T=\"number\",U=\"string\",V=\"array\",W=Object.prototype.toString,X=(c._ISURL=/^url\\(['\"]?(.+?)['\"]?\\)$/i,/^\\s*((#[a-f\\d]{6})|(#[a-f\\d]{3})|rgba?\\(\\s*([\\d\\.]+%?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+%?(?:\\s*,\\s*[\\d\\.]+%?)?)\\s*\\)|hsba?\\(\\s*([\\d\\.]+(?:deg|\\xb0|%)?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+(?:%?\\s*,\\s*[\\d\\.]+)?)%?\\s*\\)|hsla?\\(\\s*([\\d\\.]+(?:deg|\\xb0|%)?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+(?:%?\\s*,\\s*[\\d\\.]+)?)%?\\s*\\))\\s*$/i),Y={NaN:1,Infinity:1,\"-Infinity\":1},Z=/^(?:cubic-)?bezier\\(([^,]+),([^,]+),([^,]+),([^\\)]+)\\)/,$=N.round,_=parseFloat,ab=parseInt,bb=I.prototype.toUpperCase,cb=c._availableAttrs={\"arrow-end\":\"none\",\"arrow-start\":\"none\",blur:0,\"clip-rect\":\"0 0 1e9 1e9\",cursor:\"default\",cx:0,cy:0,fill:\"#fff\",\"fill-opacity\":1,font:'10px \"Arial\"',\"font-family\":'\"Arial\"',\"font-size\":\"10\",\"font-style\":\"normal\",\"font-weight\":400,gradient:0,height:0,href:\"http://raphaeljs.com/\",\"letter-spacing\":0,opacity:1,path:\"M0,0\",r:0,rx:0,ry:0,src:\"\",stroke:\"#000\",\"stroke-dasharray\":\"\",\"stroke-linecap\":\"butt\",\"stroke-linejoin\":\"butt\",\"stroke-miterlimit\":0,\"stroke-opacity\":1,\"stroke-width\":1,target:\"_blank\",\"text-anchor\":\"middle\",title:\"Raphael\",transform:\"\",width:0,x:0,y:0},db=c._availableAnimAttrs={blur:T,\"clip-rect\":\"csv\",cx:T,cy:T,fill:\"colour\",\"fill-opacity\":T,\"font-size\":T,height:T,opacity:T,path:\"path\",r:T,rx:T,ry:T,stroke:\"colour\",\"stroke-opacity\":T,\"stroke-width\":T,transform:\"transform\",width:T,x:T,y:T},eb=/[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*/,fb={hs:1,rg:1},gb=/,?([achlmqrstvxz]),?/gi,hb=/([achlmrqstvz])[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029,]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*)+)/gi,ib=/([rstm])[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029,]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*)+)/gi,jb=/(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*/gi,kb=(c._radial_gradient=/^r(?:\\(([^,]+?)[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*([^\\)]+?)\\))?/,{}),lb=function(a,b){return _(a)-_(b)},mb=function(){},nb=function(a){return a},ob=c._rectPath=function(a,b,c,d,e){return e?[[\"M\",a+e,b],[\"l\",c-2*e,0],[\"a\",e,e,0,0,1,e,e],[\"l\",0,d-2*e],[\"a\",e,e,0,0,1,-e,e],[\"l\",2*e-c,0],[\"a\",e,e,0,0,1,-e,-e],[\"l\",0,2*e-d],[\"a\",e,e,0,0,1,e,-e],[\"z\"]]:[[\"M\",a,b],[\"l\",c,0],[\"l\",0,d],[\"l\",-c,0],[\"z\"]]},pb=function(a,b,c,d){return null==d&&(d=c),[[\"M\",a,b],[\"m\",0,-d],[\"a\",c,d,0,1,1,0,2*d],[\"a\",c,d,0,1,1,0,-2*d],[\"z\"]]},qb=c._getPath={path:function(a){return a.attr(\"path\")},circle:function(a){var b=a.attrs;return pb(b.cx,b.cy,b.r)},ellipse:function(a){var b=a.attrs;return pb(b.cx,b.cy,b.rx,b.ry)},rect:function(a){var b=a.attrs;return ob(b.x,b.y,b.width,b.height,b.r)},image:function(a){var b=a.attrs;return ob(b.x,b.y,b.width,b.height)},text:function(a){var b=a._getBBox();return ob(b.x,b.y,b.width,b.height)},set:function(a){var b=a._getBBox();return ob(b.x,b.y,b.width,b.height)}},rb=c.mapPath=function(a,b){if(!b)return a;var c,d,e,f,g,h,i;for(a=Kb(a),e=0,g=a.length;g>e;e++)for(i=a[e],f=1,h=i.length;h>f;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a};if(c._g=A,c.type=A.win.SVGAngle||A.doc.implementation.hasFeature(\"http://www.w3.org/TR/SVG11/feature#BasicStructure\",\"1.1\")?\"SVG\":\"VML\",\"VML\"==c.type){var sb,tb=A.doc.createElement(\"div\");if(tb.innerHTML='<v:shape adj=\"1\"/>',sb=tb.firstChild,sb.style.behavior=\"url(#default#VML)\",!sb||\"object\"!=typeof sb.adj)return c.type=G;tb=null}c.svg=!(c.vml=\"VML\"==c.type),c._Paper=C,c.fn=v=C.prototype=c.prototype,c._id=0,c._oid=0,c.is=function(a,b){return b=M.call(b),\"finite\"==b?!Y[z](+a):\"array\"==b?a instanceof Array:\"null\"==b&&null===a||b==typeof a&&null!==a||\"object\"==b&&a===Object(a)||\"array\"==b&&Array.isArray&&Array.isArray(a)||W.call(a).slice(8,-1).toLowerCase()==b},c.angle=function(a,b,d,e,f,g){if(null==f){var h=a-d,i=b-e;return h||i?(180+180*N.atan2(-i,-h)/S+360)%360:0}return c.angle(a,b,f,g)-c.angle(d,e,f,g)},c.rad=function(a){return a%360*S/180},c.deg=function(a){return Math.round(180*a/S%360*1e3)/1e3},c.snapTo=function(a,b,d){if(d=c.is(d,\"finite\")?d:10,c.is(a,V)){for(var e=a.length;e--;)if(Q(a[e]-b)<=d)return a[e]}else{a=+a;var f=b%a;if(d>f)return b-f;if(f>a-d)return b-f+a}return b};c.createUUID=function(a,b){return function(){return\"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(a,b).toUpperCase()}}(/[xy]/g,function(a){var b=16*N.random()|0,c=\"x\"==a?b:3&b|8;return c.toString(16)});c.setWindow=function(a){b(\"raphael.setWindow\",c,A.win,a),A.win=a,A.doc=A.win.document,c._engine.initWin&&c._engine.initWin(A.win)};var ub=function(a){if(c.vml){var b,d=/^\\s+|\\s+$/g;try{var e=new ActiveXObject(\"htmlfile\");e.write(\"<body>\"),e.close(),b=e.body}catch(g){b=createPopup().document.body}var h=b.createTextRange();ub=f(function(a){try{b.style.color=I(a).replace(d,G);var c=h.queryCommandValue(\"ForeColor\");return c=(255&c)<<16|65280&c|(16711680&c)>>>16,\"#\"+(\"000000\"+c.toString(16)).slice(-6)}catch(e){return\"none\"}})}else{var i=A.doc.createElement(\"i\");i.title=\"Raphaël Colour Picker\",i.style.display=\"none\",A.doc.body.appendChild(i),ub=f(function(a){return i.style.color=a,A.doc.defaultView.getComputedStyle(i,G).getPropertyValue(\"color\")})}return ub(a)},vb=function(){return\"hsb(\"+[this.h,this.s,this.b]+\")\"},wb=function(){return\"hsl(\"+[this.h,this.s,this.l]+\")\"},xb=function(){return this.hex},yb=function(a,b,d){if(null==b&&c.is(a,\"object\")&&\"r\"in a&&\"g\"in a&&\"b\"in a&&(d=a.b,b=a.g,a=a.r),null==b&&c.is(a,U)){var e=c.getRGB(a);a=e.r,b=e.g,d=e.b}return(a>1||b>1||d>1)&&(a/=255,b/=255,d/=255),[a,b,d]},zb=function(a,b,d,e){a*=255,b*=255,d*=255;var f={r:a,g:b,b:d,hex:c.rgb(a,b,d),toString:xb};return c.is(e,\"finite\")&&(f.opacity=e),f};c.color=function(a){var b;return c.is(a,\"object\")&&\"h\"in a&&\"s\"in a&&\"b\"in a?(b=c.hsb2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.hex=b.hex):c.is(a,\"object\")&&\"h\"in a&&\"s\"in a&&\"l\"in a?(b=c.hsl2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.hex=b.hex):(c.is(a,\"string\")&&(a=c.getRGB(a)),c.is(a,\"object\")&&\"r\"in a&&\"g\"in a&&\"b\"in a?(b=c.rgb2hsl(a),a.h=b.h,a.s=b.s,a.l=b.l,b=c.rgb2hsb(a),a.v=b.b):(a={hex:\"none\"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1)),a.toString=xb,a},c.hsb2rgb=function(a,b,c,d){this.is(a,\"object\")&&\"h\"in a&&\"s\"in a&&\"b\"in a&&(c=a.b,b=a.s,d=a.o,a=a.h),a*=360;var e,f,g,h,i;return a=a%360/60,i=c*b,h=i*(1-Q(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],zb(e,f,g,d)},c.hsl2rgb=function(a,b,c,d){this.is(a,\"object\")&&\"h\"in a&&\"s\"in a&&\"l\"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var e,f,g,h,i;return a=a%360/60,i=2*b*(.5>c?c:1-c),h=i*(1-Q(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],zb(e,f,g,d)},c.rgb2hsb=function(a,b,c){c=yb(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=O(a,b,c),g=f-P(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:vb}},c.rgb2hsl=function(a,b,c){c=yb(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=O(a,b,c),h=P(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:wb}},c._path2string=function(){return this.join(\",\").replace(gb,\"$1\")};c._preload=function(a,b){var c=A.doc.createElement(\"img\");c.style.cssText=\"position:absolute;left:-9999em;top:-9999em\",c.onload=function(){b.call(this),this.onload=null,A.doc.body.removeChild(this)},c.onerror=function(){A.doc.body.removeChild(this)},A.doc.body.appendChild(c),c.src=a};c.getRGB=f(function(a){if(!a||(a=I(a)).indexOf(\"-\")+1)return{r:-1,g:-1,b:-1,hex:\"none\",error:1,toString:g};if(\"none\"==a)return{r:-1,g:-1,b:-1,hex:\"none\",toString:g};!(fb[z](a.toLowerCase().substring(0,2))||\"#\"==a.charAt())&&(a=ub(a));var b,d,e,f,h,i,j=a.match(X);return j?(j[2]&&(e=ab(j[2].substring(5),16),d=ab(j[2].substring(3,5),16),b=ab(j[2].substring(1,3),16)),j[3]&&(e=ab((h=j[3].charAt(3))+h,16),d=ab((h=j[3].charAt(2))+h,16),b=ab((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4][J](eb),b=_(i[0]),\"%\"==i[0].slice(-1)&&(b*=2.55),d=_(i[1]),\"%\"==i[1].slice(-1)&&(d*=2.55),e=_(i[2]),\"%\"==i[2].slice(-1)&&(e*=2.55),\"rgba\"==j[1].toLowerCase().slice(0,4)&&(f=_(i[3])),i[3]&&\"%\"==i[3].slice(-1)&&(f/=100)),j[5]?(i=j[5][J](eb),b=_(i[0]),\"%\"==i[0].slice(-1)&&(b*=2.55),d=_(i[1]),\"%\"==i[1].slice(-1)&&(d*=2.55),e=_(i[2]),\"%\"==i[2].slice(-1)&&(e*=2.55),(\"deg\"==i[0].slice(-3)||\"°\"==i[0].slice(-1))&&(b/=360),\"hsba\"==j[1].toLowerCase().slice(0,4)&&(f=_(i[3])),i[3]&&\"%\"==i[3].slice(-1)&&(f/=100),c.hsb2rgb(b,d,e,f)):j[6]?(i=j[6][J](eb),b=_(i[0]),\"%\"==i[0].slice(-1)&&(b*=2.55),d=_(i[1]),\"%\"==i[1].slice(-1)&&(d*=2.55),e=_(i[2]),\"%\"==i[2].slice(-1)&&(e*=2.55),(\"deg\"==i[0].slice(-3)||\"°\"==i[0].slice(-1))&&(b/=360),\"hsla\"==j[1].toLowerCase().slice(0,4)&&(f=_(i[3])),i[3]&&\"%\"==i[3].slice(-1)&&(f/=100),c.hsl2rgb(b,d,e,f)):(j={r:b,g:d,b:e,toString:g},j.hex=\"#\"+(16777216|e|d<<8|b<<16).toString(16).slice(1),c.is(f,\"finite\")&&(j.opacity=f),j)):{r:-1,g:-1,b:-1,hex:\"none\",error:1,toString:g}},c),c.hsb=f(function(a,b,d){return c.hsb2rgb(a,b,d).hex}),c.hsl=f(function(a,b,d){return c.hsl2rgb(a,b,d).hex}),c.rgb=f(function(a,b,c){return\"#\"+(16777216|c|b<<8|a<<16).toString(16).slice(1)}),c.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);return b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})),c.hex},c.getColor.reset=function(){delete this.start},c.parsePathString=function(a){if(!a)return null;var b=Ab(a);if(b.arr)return Cb(b.arr);var d={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},e=[];return c.is(a,V)&&c.is(a[0],V)&&(e=Cb(a)),e.length||I(a).replace(hb,function(a,b,c){var f=[],g=b.toLowerCase();if(c.replace(jb,function(a,b){b&&f.push(+b)}),\"m\"==g&&f.length>2&&(e.push([b][E](f.splice(0,2))),g=\"l\",b=\"m\"==b?\"l\":\"L\"),\"r\"==g)e.push([b][E](f));else for(;f.length>=d[g]&&(e.push([b][E](f.splice(0,d[g]))),d[g]););}),e.toString=c._path2string,b.arr=Cb(e),e},c.parseTransformString=f(function(a){if(!a)return null;var b=[];return c.is(a,V)&&c.is(a[0],V)&&(b=Cb(a)),b.length||I(a).replace(ib,function(a,c,d){{var e=[];M.call(c)}d.replace(jb,function(a,b){b&&e.push(+b)}),b.push([c][E](e))}),b.toString=c._path2string,b});var Ab=function(a){var b=Ab.ps=Ab.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[z](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]};c.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=R(j,3),l=R(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*N.atan2(q-s,r-t)/S;return(q>s||t>r)&&(y+=180),{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}},c.bezierBBox=function(a,b,d,e,f,g,h,i){c.is(a,\"array\")||(a=[a,b,d,e,f,g,h,i]);var j=Jb.apply(null,a);return{x:j.min.x,y:j.min.y,x2:j.max.x,y2:j.max.y,width:j.max.x-j.min.x,height:j.max.y-j.min.y}},c.isPointInsideBBox=function(a,b,c){return b>=a.x&&b<=a.x2&&c>=a.y&&c<=a.y2},c.isBBoxIntersect=function(a,b){var d=c.isPointInsideBBox;return d(b,a.x,a.y)||d(b,a.x2,a.y)||d(b,a.x,a.y2)||d(b,a.x2,a.y2)||d(a,b.x,b.y)||d(a,b.x2,b.y)||d(a,b.x,b.y2)||d(a,b.x2,b.y2)||(a.x<b.x2&&a.x>b.x||b.x<a.x2&&b.x>a.x)&&(a.y<b.y2&&a.y>b.y||b.y<a.y2&&b.y>a.y)},c.pathIntersection=function(a,b){return n(a,b)},c.pathIntersectionNumber=function(a,b){return n(a,b,1)},c.isPointInsidePath=function(a,b,d){var e=c.pathBBox(a);return c.isPointInsideBBox(e,b,d)&&n(a,[[\"M\",b,d],[\"H\",e.x2+10]],1)%2==1},c._removedFactory=function(a){return function(){b(\"raphael.log\",null,\"Raphaël: you are calling to method “\"+a+\"” of removed object\",a)}};var Bb=c.pathBBox=function(a){var b=Ab(a);if(b.bbox)return d(b.bbox);if(!a)return{x:0,y:0,width:0,height:0,x2:0,y2:0};a=Kb(a);for(var c,e=0,f=0,g=[],h=[],i=0,j=a.length;j>i;i++)if(c=a[i],\"M\"==c[0])e=c[1],f=c[2],g.push(e),h.push(f);else{var k=Jb(e,f,c[1],c[2],c[3],c[4],c[5],c[6]);g=g[E](k.min.x,k.max.x),h=h[E](k.min.y,k.max.y),e=c[5],f=c[6]}var l=P[D](0,g),m=P[D](0,h),n=O[D](0,g),o=O[D](0,h),p=n-l,q=o-m,r={x:l,y:m,x2:n,y2:o,width:p,height:q,cx:l+p/2,cy:m+q/2};return b.bbox=d(r),r},Cb=function(a){var b=d(a);return b.toString=c._path2string,b},Db=c._pathToRelative=function(a){var b=Ab(a);if(b.rel)return Cb(b.rel);c.is(a,V)&&c.is(a&&a[0],V)||(a=c.parsePathString(a));var d=[],e=0,f=0,g=0,h=0,i=0;\"M\"==a[0][0]&&(e=a[0][1],f=a[0][2],g=e,h=f,i++,d.push([\"M\",e,f]));for(var j=i,k=a.length;k>j;j++){var l=d[j]=[],m=a[j];if(m[0]!=M.call(m[0]))switch(l[0]=M.call(m[0]),l[0]){case\"a\":l[1]=m[1],l[2]=m[2],l[3]=m[3],l[4]=m[4],l[5]=m[5],l[6]=+(m[6]-e).toFixed(3),l[7]=+(m[7]-f).toFixed(3);break;case\"v\":l[1]=+(m[1]-f).toFixed(3);break;case\"m\":g=m[1],h=m[2];default:for(var n=1,o=m.length;o>n;n++)l[n]=+(m[n]-(n%2?e:f)).toFixed(3)}else{l=d[j]=[],\"m\"==m[0]&&(g=m[1]+e,h=m[2]+f);for(var p=0,q=m.length;q>p;p++)d[j][p]=m[p]}var r=d[j].length;switch(d[j][0]){case\"z\":e=g,f=h;break;case\"h\":e+=+d[j][r-1];break;case\"v\":f+=+d[j][r-1];break;default:e+=+d[j][r-2],f+=+d[j][r-1]}}return d.toString=c._path2string,b.rel=Cb(d),d},Eb=c._pathToAbsolute=function(a){var b=Ab(a);if(b.abs)return Cb(b.abs);if(c.is(a,V)&&c.is(a&&a[0],V)||(a=c.parsePathString(a)),!a||!a.length)return[[\"M\",0,0]];var d=[],e=0,f=0,g=0,i=0,j=0;\"M\"==a[0][0]&&(e=+a[0][1],f=+a[0][2],g=e,i=f,j++,d[0]=[\"M\",e,f]);for(var k,l,m=3==a.length&&\"M\"==a[0][0]&&\"R\"==a[1][0].toUpperCase()&&\"Z\"==a[2][0].toUpperCase(),n=j,o=a.length;o>n;n++){if(d.push(k=[]),l=a[n],l[0]!=bb.call(l[0]))switch(k[0]=bb.call(l[0]),k[0]){case\"A\":k[1]=l[1],k[2]=l[2],k[3]=l[3],k[4]=l[4],k[5]=l[5],k[6]=+(l[6]+e),k[7]=+(l[7]+f);break;case\"V\":k[1]=+l[1]+f;break;case\"H\":k[1]=+l[1]+e;break;case\"R\":for(var p=[e,f][E](l.slice(1)),q=2,r=p.length;r>q;q++)p[q]=+p[q]+e,p[++q]=+p[q]+f;d.pop(),d=d[E](h(p,m));break;case\"M\":g=+l[1]+e,i=+l[2]+f;default:for(q=1,r=l.length;r>q;q++)k[q]=+l[q]+(q%2?e:f)}else if(\"R\"==l[0])p=[e,f][E](l.slice(1)),d.pop(),d=d[E](h(p,m)),k=[\"R\"][E](l.slice(-2));else for(var s=0,t=l.length;t>s;s++)k[s]=l[s];switch(k[0]){case\"Z\":e=g,f=i;break;case\"H\":e=k[1];break;case\"V\":f=k[1];break;case\"M\":g=k[k.length-2],i=k[k.length-1];default:e=k[k.length-2],f=k[k.length-1]}}return d.toString=c._path2string,b.abs=Cb(d),d},Fb=function(a,b,c,d){return[a,b,c,d,c,d]},Gb=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},Hb=function(a,b,c,d,e,g,h,i,j,k){var l,m=120*S/180,n=S/180*(+e||0),o=[],p=f(function(a,b,c){var d=a*N.cos(c)-b*N.sin(c),e=a*N.sin(c)+b*N.cos(c);return{x:d,y:e}});if(k)y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(a,b,-n),a=l.x,b=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(N.cos(S/180*e),N.sin(S/180*e),(a-i)/2),r=(b-j)/2,s=q*q/(c*c)+r*r/(d*d);s>1&&(s=N.sqrt(s),c=s*c,d=s*d);var t=c*c,u=d*d,v=(g==h?-1:1)*N.sqrt(Q((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*c*r/d+(a+i)/2,x=v*-d*q/c+(b+j)/2,y=N.asin(((b-x)/d).toFixed(9)),z=N.asin(((j-x)/d).toFixed(9));y=w>a?S-y:y,z=w>i?S-z:z,0>y&&(y=2*S+y),0>z&&(z=2*S+z),h&&y>z&&(y-=2*S),!h&&z>y&&(z-=2*S)}var A=z-y;if(Q(A)>m){var B=z,C=i,D=j;z=y+m*(h&&z>y?1:-1),i=w+c*N.cos(z),j=x+d*N.sin(z),o=Hb(i,j,c,d,e,0,h,C,D,[z,B,w,x])}A=z-y;var F=N.cos(y),G=N.sin(y),H=N.cos(z),I=N.sin(z),K=N.tan(A/4),L=4/3*c*K,M=4/3*d*K,O=[a,b],P=[a+L*G,b-M*F],R=[i+L*I,j-M*H],T=[i,j];if(P[0]=2*O[0]-P[0],P[1]=2*O[1]-P[1],k)return[P,R,T][E](o);o=[P,R,T][E](o).join()[J](\",\");for(var U=[],V=0,W=o.length;W>V;V++)U[V]=V%2?p(o[V-1],o[V],n).y:p(o[V],o[V+1],n).x;return U},Ib=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:R(j,3)*a+3*R(j,2)*i*c+3*j*i*i*e+R(i,3)*g,y:R(j,3)*b+3*R(j,2)*i*d+3*j*i*i*f+R(i,3)*h}},Jb=f(function(a,b,c,d,e,f,g,h){var i,j=e-2*c+a-(g-2*e+c),k=2*(c-a)-2*(e-c),l=a-c,m=(-k+N.sqrt(k*k-4*j*l))/2/j,n=(-k-N.sqrt(k*k-4*j*l))/2/j,o=[b,h],p=[a,g];return Q(m)>\"1e12\"&&(m=.5),Q(n)>\"1e12\"&&(n=.5),m>0&&1>m&&(i=Ib(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ib(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),j=f-2*d+b-(h-2*f+d),k=2*(d-b)-2*(f-d),l=b-d,m=(-k+N.sqrt(k*k-4*j*l))/2/j,n=(-k-N.sqrt(k*k-4*j*l))/2/j,Q(m)>\"1e12\"&&(m=.5),Q(n)>\"1e12\"&&(n=.5),m>0&&1>m&&(i=Ib(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ib(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),{min:{x:P[D](0,p),y:P[D](0,o)},max:{x:O[D](0,p),y:O[D](0,o)}}}),Kb=c._path2curve=f(function(a,b){var c=!b&&Ab(a);if(!b&&c.curve)return Cb(c.curve);for(var d=Eb(a),e=b&&Eb(b),f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},h=(function(a,b,c){var d,e,f={T:1,Q:1};if(!a)return[\"C\",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in f)&&(b.qx=b.qy=null),a[0]){case\"M\":b.X=a[1],b.Y=a[2];break;case\"A\":a=[\"C\"][E](Hb[D](0,[b.x,b.y][E](a.slice(1))));break;case\"S\":\"C\"==c||\"S\"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=[\"C\",d,e][E](a.slice(1));break;case\"T\":\"Q\"==c||\"T\"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=[\"C\"][E](Gb(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case\"Q\":b.qx=a[1],b.qy=a[2],a=[\"C\"][E](Gb(b.x,b.y,a[1],a[2],a[3],a[4]));break;case\"L\":a=[\"C\"][E](Fb(b.x,b.y,a[1],a[2]));break;case\"H\":a=[\"C\"][E](Fb(b.x,b.y,a[1],b.y));break;case\"V\":a=[\"C\"][E](Fb(b.x,b.y,b.x,a[1]));break;case\"Z\":a=[\"C\"][E](Fb(b.x,b.y,b.X,b.Y))}return a}),i=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;)k[b]=\"A\",e&&(l[b]=\"A\"),a.splice(b++,0,[\"C\"][E](c.splice(0,6)));a.splice(b,1),p=O(d.length,e&&e.length||0)}},j=function(a,b,c,f,g){a&&b&&\"M\"==a[g][0]&&\"M\"!=b[g][0]&&(b.splice(g,0,[\"M\",f.x,f.y]),c.bx=0,c.by=0,c.x=a[g][1],c.y=a[g][2],p=O(d.length,e&&e.length||0))},k=[],l=[],m=\"\",n=\"\",o=0,p=O(d.length,e&&e.length||0);p>o;o++){d[o]&&(m=d[o][0]),\"C\"!=m&&(k[o]=m,o&&(n=k[o-1])),d[o]=h(d[o],f,n),\"A\"!=k[o]&&\"C\"==m&&(k[o]=\"C\"),i(d,o),e&&(e[o]&&(m=e[o][0]),\"C\"!=m&&(l[o]=m,o&&(n=l[o-1])),e[o]=h(e[o],g,n),\"A\"!=l[o]&&\"C\"==m&&(l[o]=\"C\"),i(e,o)),j(d,e,f,g,o),j(e,d,g,f,o);var q=d[o],r=e&&e[o],s=q.length,t=e&&r.length;f.x=q[s-2],f.y=q[s-1],f.bx=_(q[s-4])||f.x,f.by=_(q[s-3])||f.y,g.bx=e&&(_(r[t-4])||g.x),g.by=e&&(_(r[t-3])||g.y),g.x=e&&r[t-2],g.y=e&&r[t-1]}return e||(c.curve=Cb(d)),e?[d,e]:d},null,Cb),Lb=(c._parseDots=f(function(a){for(var b=[],d=0,e=a.length;e>d;d++){var f={},g=a[d].match(/^([^:]*):?([\\d\\.]*)/);if(f.color=c.getRGB(g[1]),f.color.error)return null;f.color=f.color.hex,g[2]&&(f.offset=g[2]+\"%\"),b.push(f)}for(d=1,e=b.length-1;e>d;d++)if(!b[d].offset){for(var h=_(b[d-1].offset||0),i=0,j=d+1;e>j;j++)if(b[j].offset){i=b[j].offset;break}i||(i=100,j=e),i=_(i);for(var k=(i-h)/(j-d+1);j>d;d++)h+=k,b[d].offset=h+\"%\"}return b}),c._tear=function(a,b){a==b.top&&(b.top=a.prev),a==b.bottom&&(b.bottom=a.next),a.next&&(a.next.prev=a.prev),a.prev&&(a.prev.next=a.next)}),Mb=(c._tofront=function(a,b){b.top!==a&&(Lb(a,b),a.next=null,a.prev=b.top,b.top.next=a,b.top=a)},c._toback=function(a,b){b.bottom!==a&&(Lb(a,b),a.next=b.bottom,a.prev=null,b.bottom.prev=a,b.bottom=a)},c._insertafter=function(a,b,c){Lb(a,c),b==c.top&&(c.top=a),b.next&&(b.next.prev=a),a.next=b.next,a.prev=b,b.next=a},c._insertbefore=function(a,b,c){Lb(a,c),b==c.bottom&&(c.bottom=a),b.prev&&(b.prev.next=a),a.prev=b.prev,b.prev=a,a.next=b},c.toMatrix=function(a,b){var c=Bb(a),d={_:{transform:G},getBBox:function(){return c}};return Nb(d,b),d.matrix}),Nb=(c.transformPath=function(a,b){return rb(a,Mb(a,b))},c._extractTransform=function(a,b){if(null==b)return a._.transform;b=I(b).replace(/\\.{3}|\\u2026/g,a._.transform||G);var d=c.parseTransformString(b),e=0,f=0,g=0,h=1,i=1,j=a._,k=new o;if(j.transform=d||[],d)for(var l=0,m=d.length;m>l;l++){var n,p,q,r,s,t=d[l],u=t.length,v=I(t[0]).toLowerCase(),w=t[0]!=v,x=w?k.invert():0;\"t\"==v&&3==u?w?(n=x.x(0,0),p=x.y(0,0),q=x.x(t[1],t[2]),r=x.y(t[1],t[2]),k.translate(q-n,r-p)):k.translate(t[1],t[2]):\"r\"==v?2==u?(s=s||a.getBBox(1),k.rotate(t[1],s.x+s.width/2,s.y+s.height/2),e+=t[1]):4==u&&(w?(q=x.x(t[2],t[3]),r=x.y(t[2],t[3]),k.rotate(t[1],q,r)):k.rotate(t[1],t[2],t[3]),e+=t[1]):\"s\"==v?2==u||3==u?(s=s||a.getBBox(1),k.scale(t[1],t[u-1],s.x+s.width/2,s.y+s.height/2),h*=t[1],i*=t[u-1]):5==u&&(w?(q=x.x(t[3],t[4]),r=x.y(t[3],t[4]),k.scale(t[1],t[2],q,r)):k.scale(t[1],t[2],t[3],t[4]),h*=t[1],i*=t[2]):\"m\"==v&&7==u&&k.add(t[1],t[2],t[3],t[4],t[5],t[6]),j.dirtyT=1,a.matrix=k}a.matrix=k,j.sx=h,j.sy=i,j.deg=e,j.dx=f=k.e,j.dy=g=k.f,1==h&&1==i&&!e&&j.bbox?(j.bbox.x+=+f,j.bbox.y+=+g):j.dirtyT=1}),Ob=function(a){var b=a[0];switch(b.toLowerCase()){case\"t\":return[b,0,0];case\"m\":return[b,1,0,0,1,0,0];case\"r\":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case\"s\":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}},Pb=c._equaliseTransform=function(a,b){b=I(b).replace(/\\.{3}|\\u2026/g,a),a=c.parseTransformString(a)||[],b=c.parseTransformString(b)||[];\nfor(var d,e,f,g,h=O(a.length,b.length),i=[],j=[],k=0;h>k;k++){if(f=a[k]||Ob(b[k]),g=b[k]||Ob(f),f[0]!=g[0]||\"r\"==f[0].toLowerCase()&&(f[2]!=g[2]||f[3]!=g[3])||\"s\"==f[0].toLowerCase()&&(f[3]!=g[3]||f[4]!=g[4]))return;for(i[k]=[],j[k]=[],d=0,e=O(f.length,g.length);e>d;d++)d in f&&(i[k][d]=f[d]),d in g&&(j[k][d]=g[d])}return{from:i,to:j}};c._getContainer=function(a,b,d,e){var f;return f=null!=e||c.is(a,\"object\")?a:A.doc.getElementById(a),null!=f?f.tagName?null==b?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:b,height:d}:{container:1,x:a,y:b,width:d,height:e}:void 0},c.pathToRelative=Db,c._engine={},c.path2curve=Kb,c.matrix=function(a,b,c,d,e,f){return new o(a,b,c,d,e,f)},function(a){function b(a){return a[0]*a[0]+a[1]*a[1]}function d(a){var c=N.sqrt(b(a));a[0]&&(a[0]/=c),a[1]&&(a[1]/=c)}a.add=function(a,b,c,d,e,f){var g,h,i,j,k=[[],[],[]],l=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],m=[[a,c,e],[b,d,f],[0,0,1]];for(a&&a instanceof o&&(m=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),g=0;3>g;g++)for(h=0;3>h;h++){for(j=0,i=0;3>i;i++)j+=l[g][i]*m[i][h];k[g][h]=j}this.a=k[0][0],this.b=k[1][0],this.c=k[0][1],this.d=k[1][1],this.e=k[0][2],this.f=k[1][2]},a.invert=function(){var a=this,b=a.a*a.d-a.b*a.c;return new o(a.d/b,-a.b/b,-a.c/b,a.a/b,(a.c*a.f-a.d*a.e)/b,(a.b*a.e-a.a*a.f)/b)},a.clone=function(){return new o(this.a,this.b,this.c,this.d,this.e,this.f)},a.translate=function(a,b){this.add(1,0,0,1,a,b)},a.scale=function(a,b,c,d){null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d)},a.rotate=function(a,b,d){a=c.rad(a),b=b||0,d=d||0;var e=+N.cos(a).toFixed(9),f=+N.sin(a).toFixed(9);this.add(e,f,-f,e,b,d),this.add(1,0,0,1,-b,-d)},a.x=function(a,b){return a*this.a+b*this.c+this.e},a.y=function(a,b){return a*this.b+b*this.d+this.f},a.get=function(a){return+this[I.fromCharCode(97+a)].toFixed(4)},a.toString=function(){return c.svg?\"matrix(\"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+\")\":[this.get(0),this.get(2),this.get(1),this.get(3),0,0].join()},a.toFilter=function(){return\"progid:DXImageTransform.Microsoft.Matrix(M11=\"+this.get(0)+\", M12=\"+this.get(2)+\", M21=\"+this.get(1)+\", M22=\"+this.get(3)+\", Dx=\"+this.get(4)+\", Dy=\"+this.get(5)+\", sizingmethod='auto expand')\"},a.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},a.split=function(){var a={};a.dx=this.e,a.dy=this.f;var e=[[this.a,this.c],[this.b,this.d]];a.scalex=N.sqrt(b(e[0])),d(e[0]),a.shear=e[0][0]*e[1][0]+e[0][1]*e[1][1],e[1]=[e[1][0]-e[0][0]*a.shear,e[1][1]-e[0][1]*a.shear],a.scaley=N.sqrt(b(e[1])),d(e[1]),a.shear/=a.scaley;var f=-e[0][1],g=e[1][1];return 0>g?(a.rotate=c.deg(N.acos(g)),0>f&&(a.rotate=360-a.rotate)):a.rotate=c.deg(N.asin(f)),a.isSimple=!(+a.shear.toFixed(9)||a.scalex.toFixed(9)!=a.scaley.toFixed(9)&&a.rotate),a.isSuperSimple=!+a.shear.toFixed(9)&&a.scalex.toFixed(9)==a.scaley.toFixed(9)&&!a.rotate,a.noRotation=!+a.shear.toFixed(9)&&!a.rotate,a},a.toTransformString=function(a){var b=a||this[J]();return b.isSimple?(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?\"t\"+[b.dx,b.dy]:G)+(1!=b.scalex||1!=b.scaley?\"s\"+[b.scalex,b.scaley,0,0]:G)+(b.rotate?\"r\"+[b.rotate,0,0]:G)):\"m\"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]}}(o.prototype);var Qb=navigator.userAgent.match(/Version\\/(.*?)\\s/)||navigator.userAgent.match(/Chrome\\/(\\d+)/);v.safari=\"Apple Computer, Inc.\"==navigator.vendor&&(Qb&&Qb[1]<4||\"iP\"==navigator.platform.slice(0,2))||\"Google Inc.\"==navigator.vendor&&Qb&&Qb[1]<8?function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:\"none\"});setTimeout(function(){a.remove()})}:mb;for(var Rb=function(){this.returnValue=!1},Sb=function(){return this.originalEvent.preventDefault()},Tb=function(){this.cancelBubble=!0},Ub=function(){return this.originalEvent.stopPropagation()},Vb=function(a){var b=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,c=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft;return{x:a.clientX+c,y:a.clientY+b}},Wb=function(){return A.doc.addEventListener?function(a,b,c,d){var e=function(a){var b=Vb(a);return c.call(d,a,b.x,b.y)};if(a.addEventListener(b,e,!1),F&&L[b]){var f=function(b){for(var e=Vb(b),f=b,g=0,h=b.targetTouches&&b.targetTouches.length;h>g;g++)if(b.targetTouches[g].target==a){b=b.targetTouches[g],b.originalEvent=f,b.preventDefault=Sb,b.stopPropagation=Ub;break}return c.call(d,b,e.x,e.y)};a.addEventListener(L[b],f,!1)}return function(){return a.removeEventListener(b,e,!1),F&&L[b]&&a.removeEventListener(L[b],f,!1),!0}}:A.doc.attachEvent?function(a,b,c,d){var e=function(a){a=a||A.win.event;var b=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,e=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft,f=a.clientX+e,g=a.clientY+b;return a.preventDefault=a.preventDefault||Rb,a.stopPropagation=a.stopPropagation||Tb,c.call(d,a,f,g)};a.attachEvent(\"on\"+b,e);var f=function(){return a.detachEvent(\"on\"+b,e),!0};return f}:void 0}(),Xb=[],Yb=function(a){for(var c,d=a.clientX,e=a.clientY,f=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,g=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft,h=Xb.length;h--;){if(c=Xb[h],F&&a.touches){for(var i,j=a.touches.length;j--;)if(i=a.touches[j],i.identifier==c.el._drag.id){d=i.clientX,e=i.clientY,(a.originalEvent?a.originalEvent:a).preventDefault();break}}else a.preventDefault();var k,l=c.el.node,m=l.nextSibling,n=l.parentNode,o=l.style.display;A.win.opera&&n.removeChild(l),l.style.display=\"none\",k=c.el.paper.getElementByPoint(d,e),l.style.display=o,A.win.opera&&(m?n.insertBefore(l,m):n.appendChild(l)),k&&b(\"raphael.drag.over.\"+c.el.id,c.el,k),d+=g,e+=f,b(\"raphael.drag.move.\"+c.el.id,c.move_scope||c.el,d-c.el._drag.x,e-c.el._drag.y,d,e,a)}},Zb=function(a){c.unmousemove(Yb).unmouseup(Zb);for(var d,e=Xb.length;e--;)d=Xb[e],d.el._drag={},b(\"raphael.drag.end.\"+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,a);Xb=[]},$b=c.el={},_b=K.length;_b--;)!function(a){c[a]=$b[a]=function(b,d){return c.is(b,\"function\")&&(this.events=this.events||[],this.events.push({name:a,f:b,unbind:Wb(this.shape||this.node||A.doc,a,b,d||this)})),this},c[\"un\"+a]=$b[\"un\"+a]=function(b){for(var d=this.events||[],e=d.length;e--;)d[e].name!=a||!c.is(b,\"undefined\")&&d[e].f!=b||(d[e].unbind(),d.splice(e,1),!d.length&&delete this.events);return this}}(K[_b]);$b.data=function(a,d){var e=kb[this.id]=kb[this.id]||{};if(0==arguments.length)return e;if(1==arguments.length){if(c.is(a,\"object\")){for(var f in a)a[z](f)&&this.data(f,a[f]);return this}return b(\"raphael.data.get.\"+this.id,this,e[a],a),e[a]}return e[a]=d,b(\"raphael.data.set.\"+this.id,this,d,a),this},$b.removeData=function(a){return null==a?kb[this.id]={}:kb[this.id]&&delete kb[this.id][a],this},$b.getData=function(){return d(kb[this.id]||{})},$b.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},$b.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var ac=[];$b.drag=function(a,d,e,f,g,h){function i(i){(i.originalEvent||i).preventDefault();var j=i.clientX,k=i.clientY,l=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,m=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft;if(this._drag.id=i.identifier,F&&i.touches)for(var n,o=i.touches.length;o--;)if(n=i.touches[o],this._drag.id=n.identifier,n.identifier==this._drag.id){j=n.clientX,k=n.clientY;break}this._drag.x=j+m,this._drag.y=k+l,!Xb.length&&c.mousemove(Yb).mouseup(Zb),Xb.push({el:this,move_scope:f,start_scope:g,end_scope:h}),d&&b.on(\"raphael.drag.start.\"+this.id,d),a&&b.on(\"raphael.drag.move.\"+this.id,a),e&&b.on(\"raphael.drag.end.\"+this.id,e),b(\"raphael.drag.start.\"+this.id,g||f||this,i.clientX+m,i.clientY+l,i)}return this._drag={},ac.push({el:this,start:i}),this.mousedown(i),this},$b.onDragOver=function(a){a?b.on(\"raphael.drag.over.\"+this.id,a):b.unbind(\"raphael.drag.over.\"+this.id)},$b.undrag=function(){for(var a=ac.length;a--;)ac[a].el==this&&(this.unmousedown(ac[a].start),ac.splice(a,1),b.unbind(\"raphael.drag.*.\"+this.id));!ac.length&&c.unmousemove(Yb).unmouseup(Zb),Xb=[]},v.circle=function(a,b,d){var e=c._engine.circle(this,a||0,b||0,d||0);return this.__set__&&this.__set__.push(e),e},v.rect=function(a,b,d,e,f){var g=c._engine.rect(this,a||0,b||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},v.ellipse=function(a,b,d,e){var f=c._engine.ellipse(this,a||0,b||0,d||0,e||0);return this.__set__&&this.__set__.push(f),f},v.path=function(a){a&&!c.is(a,U)&&!c.is(a[0],V)&&(a+=G);var b=c._engine.path(c.format[D](c,arguments),this);return this.__set__&&this.__set__.push(b),b},v.image=function(a,b,d,e,f){var g=c._engine.image(this,a||\"about:blank\",b||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},v.text=function(a,b,d){var e=c._engine.text(this,a||0,b||0,I(d));return this.__set__&&this.__set__.push(e),e},v.set=function(a){!c.is(a,\"array\")&&(a=Array.prototype.splice.call(arguments,0,arguments.length));var b=new mc(a);return this.__set__&&this.__set__.push(b),b.paper=this,b.type=\"set\",b},v.setStart=function(a){this.__set__=a||this.set()},v.setFinish=function(){var a=this.__set__;return delete this.__set__,a},v.getSize=function(){var a=this.canvas.parentNode;return{width:a.offsetWidth,height:a.offsetHeight}},v.setSize=function(a,b){return c._engine.setSize.call(this,a,b)},v.setViewBox=function(a,b,d,e,f){return c._engine.setViewBox.call(this,a,b,d,e,f)},v.top=v.bottom=null,v.raphael=c;var bc=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,g=e.clientLeft||d.clientLeft||0,h=b.top+(A.win.pageYOffset||e.scrollTop||d.scrollTop)-f,i=b.left+(A.win.pageXOffset||e.scrollLeft||d.scrollLeft)-g;return{y:h,x:i}};v.getElementByPoint=function(a,b){var c=this,d=c.canvas,e=A.doc.elementFromPoint(a,b);if(A.win.opera&&\"svg\"==e.tagName){var f=bc(d),g=d.createSVGRect();g.x=a-f.x,g.y=b-f.y,g.width=g.height=1;var h=d.getIntersectionList(g,null);h.length&&(e=h[h.length-1])}if(!e)return null;for(;e.parentNode&&e!=d.parentNode&&!e.raphael;)e=e.parentNode;return e==c.canvas.parentNode&&(e=d),e=e&&e.raphael?c.getById(e.raphaelid):null},v.getElementsByBBox=function(a){var b=this.set();return this.forEach(function(d){c.isBBoxIntersect(d.getBBox(),a)&&b.push(d)}),b},v.getById=function(a){for(var b=this.bottom;b;){if(b.id==a)return b;b=b.next}return null},v.forEach=function(a,b){for(var c=this.bottom;c;){if(a.call(b,c)===!1)return this;c=c.next}return this},v.getElementsByPoint=function(a,b){var c=this.set();return this.forEach(function(d){d.isPointInside(a,b)&&c.push(d)}),c},$b.isPointInside=function(a,b){var d=this.realPath=qb[this.type](this);return this.attr(\"transform\")&&this.attr(\"transform\").length&&(d=c.transformPath(d,this.attr(\"transform\"))),c.isPointInsidePath(d,a,b)},$b.getBBox=function(a){if(this.removed)return{};var b=this._;return a?((b.dirty||!b.bboxwt)&&(this.realPath=qb[this.type](this),b.bboxwt=Bb(this.realPath),b.bboxwt.toString=p,b.dirty=0),b.bboxwt):((b.dirty||b.dirtyT||!b.bbox)&&((b.dirty||!this.realPath)&&(b.bboxwt=0,this.realPath=qb[this.type](this)),b.bbox=Bb(rb(this.realPath,this.matrix)),b.bbox.toString=p,b.dirty=b.dirtyT=0),b.bbox)},$b.clone=function(){if(this.removed)return null;var a=this.paper[this.type]().attr(this.attr());return this.__set__&&this.__set__.push(a),a},$b.glow=function(a){if(\"text\"==this.type)return null;a=a||{};var b={width:(a.width||10)+(+this.attr(\"stroke-width\")||1),fill:a.fill||!1,opacity:a.opacity||.5,offsetx:a.offsetx||0,offsety:a.offsety||0,color:a.color||\"#000\"},c=b.width/2,d=this.paper,e=d.set(),f=this.realPath||qb[this.type](this);f=this.matrix?rb(f,this.matrix):f;for(var g=1;c+1>g;g++)e.push(d.path(f).attr({stroke:b.color,fill:b.fill?b.color:\"none\",\"stroke-linejoin\":\"round\",\"stroke-linecap\":\"round\",\"stroke-width\":+(b.width/c*g).toFixed(3),opacity:+(b.opacity/c).toFixed(3)}));return e.insertBefore(this).translate(b.offsetx,b.offsety)};var cc=function(a,b,d,e,f,g,h,i,l){return null==l?j(a,b,d,e,f,g,h,i):c.findDotsAtSegment(a,b,d,e,f,g,h,i,k(a,b,d,e,f,g,h,i,l))},dc=function(a,b){return function(d,e,f){d=Kb(d);for(var g,h,i,j,k,l=\"\",m={},n=0,o=0,p=d.length;p>o;o++){if(i=d[o],\"M\"==i[0])g=+i[1],h=+i[2];else{if(j=cc(g,h,i[1],i[2],i[3],i[4],i[5],i[6]),n+j>e){if(b&&!m.start){if(k=cc(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),l+=[\"C\"+k.start.x,k.start.y,k.m.x,k.m.y,k.x,k.y],f)return l;m.start=l,l=[\"M\"+k.x,k.y+\"C\"+k.n.x,k.n.y,k.end.x,k.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue}if(!a&&!b)return k=cc(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),{x:k.x,y:k.y,alpha:k.alpha}}n+=j,g=+i[5],h=+i[6]}l+=i.shift()+i}return m.end=l,k=a?n:b?m:c.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),k.alpha&&(k={x:k.x,y:k.y,alpha:k.alpha}),k}},ec=dc(1),fc=dc(),gc=dc(0,1);c.getTotalLength=ec,c.getPointAtLength=fc,c.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return gc(a,b).end;var d=gc(a,c,1);return b?gc(d,b).end:d},$b.getTotalLength=function(){var a=this.getPath();if(a)return this.node.getTotalLength?this.node.getTotalLength():ec(a)},$b.getPointAtLength=function(a){var b=this.getPath();if(b)return fc(b,a)},$b.getPath=function(){var a,b=c._getPath[this.type];if(\"text\"!=this.type&&\"set\"!=this.type)return b&&(a=b(this)),a},$b.getSubpath=function(a,b){var d=this.getPath();if(d)return c.getSubpath(d,a,b)};var hc=c.easing_formulas={linear:function(a){return a},\"<\":function(a){return R(a,1.7)},\">\":function(a){return R(a,.48)},\"<>\":function(a){var b=.48-a/1.04,c=N.sqrt(.1734+b*b),d=c-b,e=R(Q(d),1/3)*(0>d?-1:1),f=-c-b,g=R(Q(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){return a==!!a?a:R(2,-10*a)*N.sin(2*(a-.075)*S/.3)+1},bounce:function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b}};hc.easeIn=hc[\"ease-in\"]=hc[\"<\"],hc.easeOut=hc[\"ease-out\"]=hc[\">\"],hc.easeInOut=hc[\"ease-in-out\"]=hc[\"<>\"],hc[\"back-in\"]=hc.backIn,hc[\"back-out\"]=hc.backOut;var ic=[],jc=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||function(a){setTimeout(a,16)},kc=function(){for(var a=+new Date,d=0;d<ic.length;d++){var e=ic[d];if(!e.el.removed&&!e.paused){var f,g,h=a-e.start,i=e.ms,j=e.easing,k=e.from,l=e.diff,m=e.to,n=(e.t,e.el),o={},p={};if(e.initstatus?(h=(e.initstatus*e.anim.top-e.prev)/(e.percent-e.prev)*i,e.status=e.initstatus,delete e.initstatus,e.stop&&ic.splice(d--,1)):e.status=(e.prev+(e.percent-e.prev)*(h/i))/e.anim.top,!(0>h))if(i>h){var q=j(h/i);for(var r in k)if(k[z](r)){switch(db[r]){case T:f=+k[r]+q*i*l[r];break;case\"colour\":f=\"rgb(\"+[lc($(k[r].r+q*i*l[r].r)),lc($(k[r].g+q*i*l[r].g)),lc($(k[r].b+q*i*l[r].b))].join(\",\")+\")\";break;case\"path\":f=[];for(var t=0,u=k[r].length;u>t;t++){f[t]=[k[r][t][0]];for(var v=1,w=k[r][t].length;w>v;v++)f[t][v]=+k[r][t][v]+q*i*l[r][t][v];f[t]=f[t].join(H)}f=f.join(H);break;case\"transform\":if(l[r].real)for(f=[],t=0,u=k[r].length;u>t;t++)for(f[t]=[k[r][t][0]],v=1,w=k[r][t].length;w>v;v++)f[t][v]=k[r][t][v]+q*i*l[r][t][v];else{var x=function(a){return+k[r][a]+q*i*l[r][a]};f=[[\"m\",x(0),x(1),x(2),x(3),x(4),x(5)]]}break;case\"csv\":if(\"clip-rect\"==r)for(f=[],t=4;t--;)f[t]=+k[r][t]+q*i*l[r][t];break;default:var y=[][E](k[r]);for(f=[],t=n.paper.customAttributes[r].length;t--;)f[t]=+y[t]+q*i*l[r][t]}o[r]=f}n.attr(o),function(a,c,d){setTimeout(function(){b(\"raphael.anim.frame.\"+a,c,d)})}(n.id,n,e.anim)}else{if(function(a,d,e){setTimeout(function(){b(\"raphael.anim.frame.\"+d.id,d,e),b(\"raphael.anim.finish.\"+d.id,d,e),c.is(a,\"function\")&&a.call(d)})}(e.callback,n,e.anim),n.attr(m),ic.splice(d--,1),e.repeat>1&&!e.next){for(g in m)m[z](g)&&(p[g]=e.totalOrigin[g]);e.el.attr(p),s(e.anim,e.el,e.anim.percents[0],null,e.totalOrigin,e.repeat-1)}e.next&&!e.stop&&s(e.anim,e.el,e.next,null,e.totalOrigin,e.repeat)}}}c.svg&&n&&n.paper&&n.paper.safari(),ic.length&&jc(kc)},lc=function(a){return a>255?255:0>a?0:a};$b.animateWith=function(a,b,d,e,f,g){var h=this;if(h.removed)return g&&g.call(h),h;var i=d instanceof r?d:c.animation(d,e,f,g);s(i,h,i.percents[0],null,h.attr());for(var j=0,k=ic.length;k>j;j++)if(ic[j].anim==b&&ic[j].el==a){ic[k-1].start=ic[j].start;break}return h},$b.onAnimation=function(a){return a?b.on(\"raphael.anim.frame.\"+this.id,a):b.unbind(\"raphael.anim.frame.\"+this.id),this},r.prototype.delay=function(a){var b=new r(this.anim,this.ms);return b.times=this.times,b.del=+a||0,b},r.prototype.repeat=function(a){var b=new r(this.anim,this.ms);return b.del=this.del,b.times=N.floor(O(a,0))||1,b},c.animation=function(a,b,d,e){if(a instanceof r)return a;(c.is(d,\"function\")||!d)&&(e=e||d||null,d=null),a=Object(a),b=+b||0;var f,g,h={};for(g in a)a[z](g)&&_(g)!=g&&_(g)+\"%\"!=g&&(f=!0,h[g]=a[g]);if(f)return d&&(h.easing=d),e&&(h.callback=e),new r({100:h},b);if(e){var i=0;for(var j in a){var k=ab(j);a[z](j)&&k>i&&(i=k)}i+=\"%\",!a[i].callback&&(a[i].callback=e)}return new r(a,b)},$b.animate=function(a,b,d,e){var f=this;if(f.removed)return e&&e.call(f),f;var g=a instanceof r?a:c.animation(a,b,d,e);return s(g,f,g.percents[0],null,f.attr()),f},$b.setTime=function(a,b){return a&&null!=b&&this.status(a,P(b,a.ms)/a.ms),this},$b.status=function(a,b){var c,d,e=[],f=0;if(null!=b)return s(a,this,-1,P(b,1)),this;for(c=ic.length;c>f;f++)if(d=ic[f],d.el.id==this.id&&(!a||d.anim==a)){if(a)return d.status;e.push({anim:d.anim,status:d.status})}return a?0:e},$b.pause=function(a){for(var c=0;c<ic.length;c++)ic[c].el.id!=this.id||a&&ic[c].anim!=a||b(\"raphael.anim.pause.\"+this.id,this,ic[c].anim)!==!1&&(ic[c].paused=!0);return this},$b.resume=function(a){for(var c=0;c<ic.length;c++)if(ic[c].el.id==this.id&&(!a||ic[c].anim==a)){var d=ic[c];b(\"raphael.anim.resume.\"+this.id,this,d.anim)!==!1&&(delete d.paused,this.status(d.anim,d.status))}return this},$b.stop=function(a){for(var c=0;c<ic.length;c++)ic[c].el.id!=this.id||a&&ic[c].anim!=a||b(\"raphael.anim.stop.\"+this.id,this,ic[c].anim)!==!1&&ic.splice(c--,1);return this},b.on(\"raphael.remove\",t),b.on(\"raphael.clear\",t),$b.toString=function(){return\"Raphaël’s object\"};var mc=function(a){if(this.items=[],this.length=0,this.type=\"set\",a)for(var b=0,c=a.length;c>b;b++)!a[b]||a[b].constructor!=$b.constructor&&a[b].constructor!=mc||(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},nc=mc.prototype;nc.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++)a=arguments[c],!a||a.constructor!=$b.constructor&&a.constructor!=mc||(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},nc.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},nc.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++)if(a.call(b,this.items[c],c)===!1)return this;return this};for(var oc in $b)$b[z](oc)&&(nc[oc]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a][D](c,b)})}}(oc));return nc.attr=function(a,b){if(a&&c.is(a,V)&&c.is(a[0],\"object\"))for(var d=0,e=a.length;e>d;d++)this.items[d].attr(a[d]);else for(var f=0,g=this.items.length;g>f;f++)this.items[f].attr(a,b);return this},nc.clear=function(){for(;this.length;)this.pop()},nc.splice=function(a,b){a=0>a?O(this.length+a,0):a,b=O(0,P(this.length-a,b));var c,d=[],e=[],f=[];for(c=2;c<arguments.length;c++)f.push(arguments[c]);for(c=0;b>c;c++)e.push(this[a+c]);for(;c<this.length-a;c++)d.push(this[a+c]);var g=f.length;for(c=0;c<g+d.length;c++)this.items[a+c]=this[a+c]=g>c?f[c]:d[c-g];for(c=this.items.length=this.length-=b-g;this[c];)delete this[c++];return new mc(e)},nc.exclude=function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]==a)return this.splice(b,1),!0},nc.animate=function(a,b,d,e){(c.is(d,\"function\")||!d)&&(e=d||null);var f,g,h=this.items.length,i=h,j=this;if(!h)return this;e&&(g=function(){!--h&&e.call(j)}),d=c.is(d,U)?d:g;var k=c.animation(a,b,d,g);for(f=this.items[--i].animate(k);i--;)this.items[i]&&!this.items[i].removed&&this.items[i].animateWith(f,k,k),this.items[i]&&!this.items[i].removed||h--;return this},nc.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},nc.getBBox=function(){for(var a=[],b=[],c=[],d=[],e=this.items.length;e--;)if(!this.items[e].removed){var f=this.items[e].getBBox();a.push(f.x),b.push(f.y),c.push(f.x+f.width),d.push(f.y+f.height)}return a=P[D](0,a),b=P[D](0,b),c=O[D](0,c),d=O[D](0,d),{x:a,y:b,x2:c,y2:d,width:c-a,height:d-b}},nc.clone=function(a){a=this.paper.set();for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},nc.toString=function(){return\"Raphaël‘s set\"},nc.glow=function(a){var b=this.paper.set();return this.forEach(function(c){var d=c.glow(a);null!=d&&d.forEach(function(a){b.push(a)})}),b},nc.isPointInside=function(a,b){var c=!1;return this.forEach(function(d){return d.isPointInside(a,b)?(c=!0,!1):void 0}),c},c.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face[\"font-family\"];for(var d in a.face)a.face[z](d)&&(b.face[d]=a.face[d]);if(this.fonts[c]?this.fonts[c].push(b):this.fonts[c]=[b],!a.svg){b.face[\"units-per-em\"]=ab(a.face[\"units-per-em\"],10);for(var e in a.glyphs)if(a.glyphs[z](e)){var f=a.glyphs[e];if(b.glyphs[e]={w:f.w,k:{},d:f.d&&\"M\"+f.d.replace(/[mlcxtrv]/g,function(a){return{l:\"L\",c:\"C\",x:\"z\",t:\"m\",r:\"l\",v:\"c\"}[a]||\"M\"})+\"z\"},f.k)for(var g in f.k)f[z](g)&&(b.glyphs[e].k[g]=f.k[g])}}return a},v.getFont=function(a,b,d,e){if(e=e||\"normal\",d=d||\"normal\",b=+b||{normal:400,bold:700,lighter:300,bolder:800}[b]||400,c.fonts){var f=c.fonts[a];if(!f){var g=new RegExp(\"(^|\\\\s)\"+a.replace(/[^\\w\\d\\s+!~.:_-]/g,G)+\"(\\\\s|$)\",\"i\");for(var h in c.fonts)if(c.fonts[z](h)&&g.test(h)){f=c.fonts[h];break}}var i;if(f)for(var j=0,k=f.length;k>j&&(i=f[j],i.face[\"font-weight\"]!=b||i.face[\"font-style\"]!=d&&i.face[\"font-style\"]||i.face[\"font-stretch\"]!=e);j++);return i}},v.print=function(a,b,d,e,f,g,h,i){g=g||\"middle\",h=O(P(h||0,1),-1),i=O(P(i||1,3),1);var j,k=I(d)[J](G),l=0,m=0,n=G;if(c.is(e,\"string\")&&(e=this.getFont(e)),e){j=(f||16)/e.face[\"units-per-em\"];for(var o=e.face.bbox[J](w),p=+o[0],q=o[3]-o[1],r=0,s=+o[1]+(\"baseline\"==g?q+ +e.face.descent:q/2),t=0,u=k.length;u>t;t++){if(\"\\n\"==k[t])l=0,x=0,m=0,r+=q*i;else{var v=m&&e.glyphs[k[t-1]]||{},x=e.glyphs[k[t]];l+=m?(v.w||e.w)+(v.k&&v.k[k[t]]||0)+e.w*h:0,m=1}x&&x.d&&(n+=c.transformPath(x.d,[\"t\",l*j,r*j,\"s\",j,j,p,s,\"t\",(a-p)/j,(b-s)/j]))}}return this.path(n).attr({fill:\"#000\",stroke:\"none\"})},v.add=function(a){if(c.is(a,\"array\"))for(var b,d=this.set(),e=0,f=a.length;f>e;e++)b=a[e]||{},x[z](b.type)&&d.push(this[b.type]().attr(b));return d},c.format=function(a,b){var d=c.is(b,V)?[0][E](b):arguments;return a&&c.is(a,U)&&d.length-1&&(a=a.replace(y,function(a,b){return null==d[++b]?G:d[b]})),a||G},c.fullfill=function(){var a=/\\{([^\\}]+)\\}/g,b=/(?:(?:^|\\.)(.+?)(?=\\[|\\.|$|\\()|\\[('|\")(.+?)\\2\\])(\\(\\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),\"function\"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+\"\"};return function(b,d){return String(b).replace(a,function(a,b){return c(a,b,d)})}}(),c.ninja=function(){return B.was?A.win.Raphael=B.is:delete Raphael,c},c.st=nc,b.on(\"raphael.DOMload\",function(){u=!0}),function(a,b,d){function e(){/in/.test(a.readyState)?setTimeout(e,9):c.eve(\"raphael.DOMload\")}null==a.readyState&&a.addEventListener&&(a.addEventListener(b,d=function(){a.removeEventListener(b,d,!1),a.readyState=\"complete\"},!1),a.readyState=\"loading\"),e()}(document,\"DOMContentLoaded\"),function(){if(c.svg){var a=\"hasOwnProperty\",b=String,d=parseFloat,e=parseInt,f=Math,g=f.max,h=f.abs,i=f.pow,j=/[, ]+/,k=c.eve,l=\"\",m=\" \",n=\"http://www.w3.org/1999/xlink\",o={block:\"M5,0 0,2.5 5,5z\",classic:\"M5,0 0,2.5 5,5 3.5,3 3.5,2z\",diamond:\"M2.5,0 5,2.5 2.5,5 0,2.5z\",open:\"M6,1 1,3.5 6,6\",oval:\"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z\"},p={};c.toString=function(){return\"Your browser supports SVG.\\nYou are running Raphaël \"+this.version};var q=function(d,e){if(e){\"string\"==typeof d&&(d=q(d));for(var f in e)e[a](f)&&(\"xlink:\"==f.substring(0,6)?d.setAttributeNS(n,f.substring(6),b(e[f])):d.setAttribute(f,b(e[f])))}else d=c._g.doc.createElementNS(\"http://www.w3.org/2000/svg\",d),d.style&&(d.style.webkitTapHighlightColor=\"rgba(0,0,0,0)\");return d},r=function(a,e){var j=\"linear\",k=a.id+e,m=.5,n=.5,o=a.node,p=a.paper,r=o.style,s=c._g.doc.getElementById(k);if(!s){if(e=b(e).replace(c._radial_gradient,function(a,b,c){if(j=\"radial\",b&&c){m=d(b),n=d(c);var e=2*(n>.5)-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&.5!=n&&(n=n.toFixed(5)-1e-5*e)}return l}),e=e.split(/\\s*\\-\\s*/),\"linear\"==j){var t=e.shift();if(t=-d(t),isNaN(t))return null;var u=[0,0,f.cos(c.rad(t)),f.sin(c.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)}var w=c._parseDots(e);if(!w)return null;if(k=k.replace(/[\\(\\)\\s,\\xb0#]/g,\"_\"),a.gradient&&k!=a.gradient.id&&(p.defs.removeChild(a.gradient),delete a.gradient),!a.gradient){s=q(j+\"Gradient\",{id:k}),a.gradient=s,q(s,\"radial\"==j?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:a.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;y>x;x++)s.appendChild(q(\"stop\",{offset:w[x].offset?w[x].offset:x?\"100%\":\"0%\",\"stop-color\":w[x].color||\"#fff\"}))}}return q(o,{fill:\"url('\"+document.location+\"#\"+k+\"')\",opacity:1,\"fill-opacity\":1}),r.fill=l,r.opacity=1,r.fillOpacity=1,1},s=function(a){var b=a.getBBox(1);q(a.pattern,{patternTransform:a.matrix.invert()+\" translate(\"+b.x+\",\"+b.y+\")\"})},t=function(d,e,f){if(\"path\"==d.type){for(var g,h,i,j,k,m=b(e).toLowerCase().split(\"-\"),n=d.paper,r=f?\"end\":\"start\",s=d.node,t=d.attrs,u=t[\"stroke-width\"],v=m.length,w=\"classic\",x=3,y=3,z=5;v--;)switch(m[v]){case\"block\":case\"classic\":case\"oval\":case\"diamond\":case\"open\":case\"none\":w=m[v];break;case\"wide\":y=5;break;case\"narrow\":y=2;break;case\"long\":x=5;break;case\"short\":x=2}if(\"open\"==w?(x+=2,y+=2,z+=2,i=1,j=f?4:1,k={fill:\"none\",stroke:t.stroke}):(j=i=x/2,k={fill:t.stroke,stroke:\"none\"}),d._.arrows?f?(d._.arrows.endPath&&p[d._.arrows.endPath]--,d._.arrows.endMarker&&p[d._.arrows.endMarker]--):(d._.arrows.startPath&&p[d._.arrows.startPath]--,d._.arrows.startMarker&&p[d._.arrows.startMarker]--):d._.arrows={},\"none\"!=w){var A=\"raphael-marker-\"+w,B=\"raphael-marker-\"+r+w+x+y+\"-obj\"+d.id;c._g.doc.getElementById(A)?p[A]++:(n.defs.appendChild(q(q(\"path\"),{\"stroke-linecap\":\"round\",d:o[w],id:A})),p[A]=1);var C,D=c._g.doc.getElementById(B);D?(p[B]++,C=D.getElementsByTagName(\"use\")[0]):(D=q(q(\"marker\"),{id:B,markerHeight:y,markerWidth:x,orient:\"auto\",refX:j,refY:y/2}),C=q(q(\"use\"),{\"xlink:href\":\"#\"+A,transform:(f?\"rotate(180 \"+x/2+\" \"+y/2+\") \":l)+\"scale(\"+x/z+\",\"+y/z+\")\",\"stroke-width\":(1/((x/z+y/z)/2)).toFixed(4)}),D.appendChild(C),n.defs.appendChild(D),p[B]=1),q(C,k);var E=i*(\"diamond\"!=w&&\"oval\"!=w);f?(g=d._.arrows.startdx*u||0,h=c.getTotalLength(t.path)-E*u):(g=E*u,h=c.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),k={},k[\"marker-\"+r]=\"url(#\"+B+\")\",(h||g)&&(k.d=c.getSubpath(t.path,g,h)),q(s,k),d._.arrows[r+\"Path\"]=A,d._.arrows[r+\"Marker\"]=B,d._.arrows[r+\"dx\"]=E,d._.arrows[r+\"Type\"]=w,d._.arrows[r+\"String\"]=e}else f?(g=d._.arrows.startdx*u||0,h=c.getTotalLength(t.path)-g):(g=0,h=c.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),d._.arrows[r+\"Path\"]&&q(s,{d:c.getSubpath(t.path,g,h)}),delete d._.arrows[r+\"Path\"],delete d._.arrows[r+\"Marker\"],delete d._.arrows[r+\"dx\"],delete d._.arrows[r+\"Type\"],delete d._.arrows[r+\"String\"];for(k in p)if(p[a](k)&&!p[k]){var F=c._g.doc.getElementById(k);F&&F.parentNode.removeChild(F)}}},u={\"\":[0],none:[0],\"-\":[3,1],\".\":[1,1],\"-.\":[3,1,1,1],\"-..\":[3,1,1,1,1,1],\". \":[1,3],\"- \":[4,3],\"--\":[8,3],\"- .\":[4,3,1,3],\"--.\":[8,3,1,3],\"--..\":[8,3,1,3,1,3]},v=function(a,c,d){if(c=u[b(c).toLowerCase()]){for(var e=a.attrs[\"stroke-width\"]||\"1\",f={round:e,square:e,butt:0}[a.attrs[\"stroke-linecap\"]||d[\"stroke-linecap\"]]||0,g=[],h=c.length;h--;)g[h]=c[h]*e+(h%2?1:-1)*f;q(a.node,{\"stroke-dasharray\":g.join(\",\")})}},w=function(d,f){var i=d.node,k=d.attrs,m=i.style.visibility;i.style.visibility=\"hidden\";for(var o in f)if(f[a](o)){if(!c._availableAttrs[a](o))continue;var p=f[o];switch(k[o]=p,o){case\"blur\":d.blur(p);break;case\"title\":var u=i.getElementsByTagName(\"title\");if(u.length&&(u=u[0]))u.firstChild.nodeValue=p;else{u=q(\"title\");var w=c._g.doc.createTextNode(p);u.appendChild(w),i.appendChild(u)}break;case\"href\":case\"target\":var x=i.parentNode;if(\"a\"!=x.tagName.toLowerCase()){var z=q(\"a\");x.insertBefore(z,i),z.appendChild(i),x=z}\"target\"==o?x.setAttributeNS(n,\"show\",\"blank\"==p?\"new\":p):x.setAttributeNS(n,o,p);break;case\"cursor\":i.style.cursor=p;break;case\"transform\":d.transform(p);break;case\"arrow-start\":t(d,p);break;case\"arrow-end\":t(d,p,1);break;case\"clip-rect\":var A=b(p).split(j);if(4==A.length){d.clip&&d.clip.parentNode.parentNode.removeChild(d.clip.parentNode);var B=q(\"clipPath\"),C=q(\"rect\");B.id=c.createUUID(),q(C,{x:A[0],y:A[1],width:A[2],height:A[3]}),B.appendChild(C),d.paper.defs.appendChild(B),q(i,{\"clip-path\":\"url(#\"+B.id+\")\"}),d.clip=C}if(!p){var D=i.getAttribute(\"clip-path\");if(D){var E=c._g.doc.getElementById(D.replace(/(^url\\(#|\\)$)/g,l));E&&E.parentNode.removeChild(E),q(i,{\"clip-path\":l}),delete d.clip}}break;case\"path\":\"path\"==d.type&&(q(i,{d:p?k.path=c._pathToAbsolute(p):\"M0,0\"}),d._.dirty=1,d._.arrows&&(\"startString\"in d._.arrows&&t(d,d._.arrows.startString),\"endString\"in d._.arrows&&t(d,d._.arrows.endString,1)));break;case\"width\":if(i.setAttribute(o,p),d._.dirty=1,!k.fx)break;o=\"x\",p=k.x;case\"x\":k.fx&&(p=-k.x-(k.width||0));case\"rx\":if(\"rx\"==o&&\"rect\"==d.type)break;case\"cx\":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case\"height\":if(i.setAttribute(o,p),d._.dirty=1,!k.fy)break;o=\"y\",p=k.y;case\"y\":k.fy&&(p=-k.y-(k.height||0));case\"ry\":if(\"ry\"==o&&\"rect\"==d.type)break;case\"cy\":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case\"r\":\"rect\"==d.type?q(i,{rx:p,ry:p}):i.setAttribute(o,p),d._.dirty=1;break;case\"src\":\"image\"==d.type&&i.setAttributeNS(n,\"href\",p);break;case\"stroke-width\":(1!=d._.sx||1!=d._.sy)&&(p/=g(h(d._.sx),h(d._.sy))||1),i.setAttribute(o,p),k[\"stroke-dasharray\"]&&v(d,k[\"stroke-dasharray\"],f),d._.arrows&&(\"startString\"in d._.arrows&&t(d,d._.arrows.startString),\"endString\"in d._.arrows&&t(d,d._.arrows.endString,1));break;case\"stroke-dasharray\":v(d,p,f);break;case\"fill\":var F=b(p).match(c._ISURL);if(F){B=q(\"pattern\");var G=q(\"image\");B.id=c.createUUID(),q(B,{x:0,y:0,patternUnits:\"userSpaceOnUse\",height:1,width:1}),q(G,{x:0,y:0,\"xlink:href\":F[1]}),B.appendChild(G),function(a){c._preload(F[1],function(){var b=this.offsetWidth,c=this.offsetHeight;q(a,{width:b,height:c}),q(G,{width:b,height:c}),d.paper.safari()})}(B),d.paper.defs.appendChild(B),q(i,{fill:\"url(#\"+B.id+\")\"}),d.pattern=B,d.pattern&&s(d);break}var H=c.getRGB(p);if(H.error){if((\"circle\"==d.type||\"ellipse\"==d.type||\"r\"!=b(p).charAt())&&r(d,p)){if(\"opacity\"in k||\"fill-opacity\"in k){var I=c._g.doc.getElementById(i.getAttribute(\"fill\").replace(/^url\\(#|\\)$/g,l));if(I){var J=I.getElementsByTagName(\"stop\");q(J[J.length-1],{\"stop-opacity\":(\"opacity\"in k?k.opacity:1)*(\"fill-opacity\"in k?k[\"fill-opacity\"]:1)})}}k.gradient=p,k.fill=\"none\";break}}else delete f.gradient,delete k.gradient,!c.is(k.opacity,\"undefined\")&&c.is(f.opacity,\"undefined\")&&q(i,{opacity:k.opacity}),!c.is(k[\"fill-opacity\"],\"undefined\")&&c.is(f[\"fill-opacity\"],\"undefined\")&&q(i,{\"fill-opacity\":k[\"fill-opacity\"]});H[a](\"opacity\")&&q(i,{\"fill-opacity\":H.opacity>1?H.opacity/100:H.opacity});case\"stroke\":H=c.getRGB(p),i.setAttribute(o,H.hex),\"stroke\"==o&&H[a](\"opacity\")&&q(i,{\"stroke-opacity\":H.opacity>1?H.opacity/100:H.opacity}),\"stroke\"==o&&d._.arrows&&(\"startString\"in d._.arrows&&t(d,d._.arrows.startString),\"endString\"in d._.arrows&&t(d,d._.arrows.endString,1));break;case\"gradient\":(\"circle\"==d.type||\"ellipse\"==d.type||\"r\"!=b(p).charAt())&&r(d,p);break;\ncase\"opacity\":k.gradient&&!k[a](\"stroke-opacity\")&&q(i,{\"stroke-opacity\":p>1?p/100:p});case\"fill-opacity\":if(k.gradient){I=c._g.doc.getElementById(i.getAttribute(\"fill\").replace(/^url\\(#|\\)$/g,l)),I&&(J=I.getElementsByTagName(\"stop\"),q(J[J.length-1],{\"stop-opacity\":p}));break}default:\"font-size\"==o&&(p=e(p,10)+\"px\");var K=o.replace(/(\\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[K]=p,d._.dirty=1,i.setAttribute(o,p)}}y(d,f),i.style.visibility=m},x=1.2,y=function(d,f){if(\"text\"==d.type&&(f[a](\"text\")||f[a](\"font\")||f[a](\"font-size\")||f[a](\"x\")||f[a](\"y\"))){var g=d.attrs,h=d.node,i=h.firstChild?e(c._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue(\"font-size\"),10):10;if(f[a](\"text\")){for(g.text=f.text;h.firstChild;)h.removeChild(h.firstChild);for(var j,k=b(f.text).split(\"\\n\"),m=[],n=0,o=k.length;o>n;n++)j=q(\"tspan\"),n&&q(j,{dy:i*x,x:g.x}),j.appendChild(c._g.doc.createTextNode(k[n])),h.appendChild(j),m[n]=j}else for(m=h.getElementsByTagName(\"tspan\"),n=0,o=m.length;o>n;n++)n?q(m[n],{dy:i*x,x:g.x}):q(m[0],{dy:0});q(h,{x:g.x,y:g.y}),d._.dirty=1;var p=d._getBBox(),r=g.y-(p.y+p.height/2);r&&c.is(r,\"finite\")&&q(m[0],{dy:r})}},z=function(a){return a.parentNode&&\"a\"===a.parentNode.tagName.toLowerCase()?a.parentNode:a},A=function(a,b){this[0]=this.node=a,a.raphael=!0,this.id=c._oid++,a.raphaelid=this.id,this.matrix=c.matrix(),this.realPath=null,this.paper=b,this.attrs=this.attrs||{},this._={transform:[],sx:1,sy:1,deg:0,dx:0,dy:0,dirty:1},!b.bottom&&(b.bottom=this),this.prev=b.top,b.top&&(b.top.next=this),b.top=this,this.next=null},B=c.el;A.prototype=B,B.constructor=A,c._engine.path=function(a,b){var c=q(\"path\");b.canvas&&b.canvas.appendChild(c);var d=new A(c,b);return d.type=\"path\",w(d,{fill:\"none\",stroke:\"#000\",path:a}),d},B.rotate=function(a,c,e){if(this.removed)return this;if(a=b(a).split(j),a.length-1&&(c=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(c=e),null==c||null==e){var f=this.getBBox(1);c=f.x+f.width/2,e=f.y+f.height/2}return this.transform(this._.transform.concat([[\"r\",a,c,e]])),this},B.scale=function(a,c,e,f){if(this.removed)return this;if(a=b(a).split(j),a.length-1&&(c=d(a[1]),e=d(a[2]),f=d(a[3])),a=d(a[0]),null==c&&(c=a),null==f&&(e=f),null==e||null==f)var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([[\"s\",a,c,e,f]])),this},B.translate=function(a,c){return this.removed?this:(a=b(a).split(j),a.length-1&&(c=d(a[1])),a=d(a[0])||0,c=+c||0,this.transform(this._.transform.concat([[\"t\",a,c]])),this)},B.transform=function(b){var d=this._;if(null==b)return d.transform;if(c._extractTransform(this,b),this.clip&&q(this.clip,{transform:this.matrix.invert()}),this.pattern&&s(this),this.node&&q(this.node,{transform:this.matrix}),1!=d.sx||1!=d.sy){var e=this.attrs[a](\"stroke-width\")?this.attrs[\"stroke-width\"]:1;this.attr({\"stroke-width\":e})}return this},B.hide=function(){return!this.removed&&this.paper.safari(this.node.style.display=\"none\"),this},B.show=function(){return!this.removed&&this.paper.safari(this.node.style.display=\"\"),this},B.remove=function(){var a=z(this.node);if(!this.removed&&a.parentNode){var b=this.paper;b.__set__&&b.__set__.exclude(this),k.unbind(\"raphael.*.*.\"+this.id),this.gradient&&b.defs.removeChild(this.gradient),c._tear(this,b),a.parentNode.removeChild(a),this.removeData();for(var d in this)this[d]=\"function\"==typeof this[d]?c._removedFactory(d):null;this.removed=!0}},B._getBBox=function(){if(\"none\"==this.node.style.display){this.show();var a=!0}var b,c=!1;this.paper.canvas.parentElement?b=this.paper.canvas.parentElement.style:this.paper.canvas.parentNode&&(b=this.paper.canvas.parentNode.style),b&&\"none\"==b.display&&(c=!0,b.display=\"\");var d={};try{d=this.node.getBBox()}catch(e){d={x:this.node.clientLeft,y:this.node.clientTop,width:this.node.clientWidth,height:this.node.clientHeight}}finally{d=d||{},c&&(b.display=\"none\")}return a&&this.hide(),d},B.attr=function(b,d){if(this.removed)return this;if(null==b){var e={};for(var f in this.attrs)this.attrs[a](f)&&(e[f]=this.attrs[f]);return e.gradient&&\"none\"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e}if(null==d&&c.is(b,\"string\")){if(\"fill\"==b&&\"none\"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;if(\"transform\"==b)return this._.transform;for(var g=b.split(j),h={},i=0,l=g.length;l>i;i++)b=g[i],h[b]=b in this.attrs?this.attrs[b]:c.is(this.paper.customAttributes[b],\"function\")?this.paper.customAttributes[b].def:c._availableAttrs[b];return l-1?h:h[g[0]]}if(null==d&&c.is(b,\"array\")){for(h={},i=0,l=b.length;l>i;i++)h[b[i]]=this.attr(b[i]);return h}if(null!=d){var m={};m[b]=d}else null!=b&&c.is(b,\"object\")&&(m=b);for(var n in m)k(\"raphael.attr.\"+n+\".\"+this.id,this,m[n]);for(n in this.paper.customAttributes)if(this.paper.customAttributes[a](n)&&m[a](n)&&c.is(this.paper.customAttributes[n],\"function\")){var o=this.paper.customAttributes[n].apply(this,[].concat(m[n]));this.attrs[n]=m[n];for(var p in o)o[a](p)&&(m[p]=o[p])}return w(this,m),this},B.toFront=function(){if(this.removed)return this;var a=z(this.node);a.parentNode.appendChild(a);var b=this.paper;return b.top!=this&&c._tofront(this,b),this},B.toBack=function(){if(this.removed)return this;var a=z(this.node),b=a.parentNode;b.insertBefore(a,b.firstChild),c._toback(this,this.paper);this.paper;return this},B.insertAfter=function(a){if(this.removed||!a)return this;var b=z(this.node),d=z(a.node||a[a.length-1].node);return d.nextSibling?d.parentNode.insertBefore(b,d.nextSibling):d.parentNode.appendChild(b),c._insertafter(this,a,this.paper),this},B.insertBefore=function(a){if(this.removed||!a)return this;var b=z(this.node),d=z(a.node||a[0].node);return d.parentNode.insertBefore(b,d),c._insertbefore(this,a,this.paper),this},B.blur=function(a){var b=this;if(0!==+a){var d=q(\"filter\"),e=q(\"feGaussianBlur\");b.attrs.blur=a,d.id=c.createUUID(),q(e,{stdDeviation:+a||1.5}),d.appendChild(e),b.paper.defs.appendChild(d),b._blur=d,q(b.node,{filter:\"url(#\"+d.id+\")\"})}else b._blur&&(b._blur.parentNode.removeChild(b._blur),delete b._blur,delete b.attrs.blur),b.node.removeAttribute(\"filter\");return b},c._engine.circle=function(a,b,c,d){var e=q(\"circle\");a.canvas&&a.canvas.appendChild(e);var f=new A(e,a);return f.attrs={cx:b,cy:c,r:d,fill:\"none\",stroke:\"#000\"},f.type=\"circle\",q(e,f.attrs),f},c._engine.rect=function(a,b,c,d,e,f){var g=q(\"rect\");a.canvas&&a.canvas.appendChild(g);var h=new A(g,a);return h.attrs={x:b,y:c,width:d,height:e,rx:f||0,ry:f||0,fill:\"none\",stroke:\"#000\"},h.type=\"rect\",q(g,h.attrs),h},c._engine.ellipse=function(a,b,c,d,e){var f=q(\"ellipse\");a.canvas&&a.canvas.appendChild(f);var g=new A(f,a);return g.attrs={cx:b,cy:c,rx:d,ry:e,fill:\"none\",stroke:\"#000\"},g.type=\"ellipse\",q(f,g.attrs),g},c._engine.image=function(a,b,c,d,e,f){var g=q(\"image\");q(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:\"none\"}),g.setAttributeNS(n,\"href\",b),a.canvas&&a.canvas.appendChild(g);var h=new A(g,a);return h.attrs={x:c,y:d,width:e,height:f,src:b},h.type=\"image\",h},c._engine.text=function(a,b,d,e){var f=q(\"text\");a.canvas&&a.canvas.appendChild(f);var g=new A(f,a);return g.attrs={x:b,y:d,\"text-anchor\":\"middle\",text:e,\"font-family\":c._availableAttrs[\"font-family\"],\"font-size\":c._availableAttrs[\"font-size\"],stroke:\"none\",fill:\"#000\"},g.type=\"text\",w(g,g.attrs),g},c._engine.setSize=function(a,b){return this.width=a||this.width,this.height=b||this.height,this.canvas.setAttribute(\"width\",this.width),this.canvas.setAttribute(\"height\",this.height),this._viewBox&&this.setViewBox.apply(this,this._viewBox),this},c._engine.create=function(){var a=c._getContainer.apply(0,arguments),b=a&&a.container,d=a.x,e=a.y,f=a.width,g=a.height;if(!b)throw new Error(\"SVG container not found.\");var h,i=q(\"svg\"),j=\"overflow:hidden;\";return d=d||0,e=e||0,f=f||512,g=g||342,q(i,{height:g,version:1.1,width:f,xmlns:\"http://www.w3.org/2000/svg\",\"xmlns:xlink\":\"http://www.w3.org/1999/xlink\"}),1==b?(i.style.cssText=j+\"position:absolute;left:\"+d+\"px;top:\"+e+\"px\",c._g.doc.body.appendChild(i),h=1):(i.style.cssText=j+\"position:relative\",b.firstChild?b.insertBefore(i,b.firstChild):b.appendChild(i)),b=new c._Paper,b.width=f,b.height=g,b.canvas=i,b.clear(),b._left=b._top=0,h&&(b.renderfix=function(){}),b.renderfix(),b},c._engine.setViewBox=function(a,b,c,d,e){k(\"raphael.setViewBox\",this,this._viewBox,[a,b,c,d,e]);var f,h,i=this.getSize(),j=g(c/i.width,d/i.height),l=this.top,n=e?\"xMidYMid meet\":\"xMinYMin\";for(null==a?(this._vbSize&&(j=1),delete this._vbSize,f=\"0 0 \"+this.width+m+this.height):(this._vbSize=j,f=a+m+b+m+c+m+d),q(this.canvas,{viewBox:f,preserveAspectRatio:n});j&&l;)h=\"stroke-width\"in l.attrs?l.attrs[\"stroke-width\"]:1,l.attr({\"stroke-width\":h}),l._.dirty=1,l._.dirtyT=1,l=l.prev;return this._viewBox=[a,b,c,d,!!e],this},c.prototype.renderfix=function(){var a,b=this.canvas,c=b.style;try{a=b.getScreenCTM()||b.createSVGMatrix()}catch(d){a=b.createSVGMatrix()}var e=-a.e%1,f=-a.f%1;(e||f)&&(e&&(this._left=(this._left+e)%1,c.left=this._left+\"px\"),f&&(this._top=(this._top+f)%1,c.top=this._top+\"px\"))},c.prototype.clear=function(){c.eve(\"raphael.clear\",this);for(var a=this.canvas;a.firstChild;)a.removeChild(a.firstChild);this.bottom=this.top=null,(this.desc=q(\"desc\")).appendChild(c._g.doc.createTextNode(\"Created with Raphaël \"+c.version)),a.appendChild(this.desc),a.appendChild(this.defs=q(\"defs\"))},c.prototype.remove=function(){k(\"raphael.remove\",this),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=\"function\"==typeof this[a]?c._removedFactory(a):null};var C=c.st;for(var D in B)B[a](D)&&!C[a](D)&&(C[D]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(D))}}(),function(){if(c.vml){var a=\"hasOwnProperty\",b=String,d=parseFloat,e=Math,f=e.round,g=e.max,h=e.min,i=e.abs,j=\"fill\",k=/[, ]+/,l=c.eve,m=\" progid:DXImageTransform.Microsoft\",n=\" \",o=\"\",p={M:\"m\",L:\"l\",C:\"c\",Z:\"x\",m:\"t\",l:\"r\",c:\"v\",z:\"x\"},q=/([clmz]),?([^clmz]*)/gi,r=/ progid:\\S+Blur\\([^\\)]+\\)/g,s=/-?[^,\\s-]+/g,t=\"position:absolute;left:0;top:0;width:1px;height:1px;behavior:url(#default#VML)\",u=21600,v={path:1,rect:1,image:1},w={circle:1,ellipse:1},x=function(a){var d=/[ahqstv]/gi,e=c._pathToAbsolute;if(b(a).match(d)&&(e=c._path2curve),d=/[clmz]/g,e==c._pathToAbsolute&&!b(a).match(d)){var g=b(a).replace(q,function(a,b,c){var d=[],e=\"m\"==b.toLowerCase(),g=p[b];return c.replace(s,function(a){e&&2==d.length&&(g+=d+p[\"m\"==b?\"l\":\"L\"],d=[]),d.push(f(a*u))}),g+d});return g}var h,i,j=e(a);g=[];for(var k=0,l=j.length;l>k;k++){h=j[k],i=j[k][0].toLowerCase(),\"z\"==i&&(i=\"x\");for(var m=1,r=h.length;r>m;m++)i+=f(h[m]*u)+(m!=r-1?\",\":o);g.push(i)}return g.join(n)},y=function(a,b,d){var e=c.matrix();return e.rotate(-a,.5,.5),{dx:e.x(b,d),dy:e.y(b,d)}},z=function(a,b,c,d,e,f){var g=a._,h=a.matrix,k=g.fillpos,l=a.node,m=l.style,o=1,p=\"\",q=u/b,r=u/c;if(m.visibility=\"hidden\",b&&c){if(l.coordsize=i(q)+n+i(r),m.rotation=f*(0>b*c?-1:1),f){var s=y(f,d,e);d=s.dx,e=s.dy}if(0>b&&(p+=\"x\"),0>c&&(p+=\" y\")&&(o=-1),m.flip=p,l.coordorigin=d*-q+n+e*-r,k||g.fillsize){var t=l.getElementsByTagName(j);t=t&&t[0],l.removeChild(t),k&&(s=y(f,h.x(k[0],k[1]),h.y(k[0],k[1])),t.position=s.dx*o+n+s.dy*o),g.fillsize&&(t.size=g.fillsize[0]*i(b)+n+g.fillsize[1]*i(c)),l.appendChild(t)}m.visibility=\"visible\"}};c.toString=function(){return\"Your browser doesn’t support SVG. Falling down to VML.\\nYou are running Raphaël \"+this.version};var A=function(a,c,d){for(var e=b(c).toLowerCase().split(\"-\"),f=d?\"end\":\"start\",g=e.length,h=\"classic\",i=\"medium\",j=\"medium\";g--;)switch(e[g]){case\"block\":case\"classic\":case\"oval\":case\"diamond\":case\"open\":case\"none\":h=e[g];break;case\"wide\":case\"narrow\":j=e[g];break;case\"long\":case\"short\":i=e[g]}var k=a.node.getElementsByTagName(\"stroke\")[0];k[f+\"arrow\"]=h,k[f+\"arrowlength\"]=i,k[f+\"arrowwidth\"]=j},B=function(e,i){e.attrs=e.attrs||{};var l=e.node,m=e.attrs,p=l.style,q=v[e.type]&&(i.x!=m.x||i.y!=m.y||i.width!=m.width||i.height!=m.height||i.cx!=m.cx||i.cy!=m.cy||i.rx!=m.rx||i.ry!=m.ry||i.r!=m.r),r=w[e.type]&&(m.cx!=i.cx||m.cy!=i.cy||m.r!=i.r||m.rx!=i.rx||m.ry!=i.ry),s=e;for(var t in i)i[a](t)&&(m[t]=i[t]);if(q&&(m.path=c._getPath[e.type](e),e._.dirty=1),i.href&&(l.href=i.href),i.title&&(l.title=i.title),i.target&&(l.target=i.target),i.cursor&&(p.cursor=i.cursor),\"blur\"in i&&e.blur(i.blur),(i.path&&\"path\"==e.type||q)&&(l.path=x(~b(m.path).toLowerCase().indexOf(\"r\")?c._pathToAbsolute(m.path):m.path),e._.dirty=1,\"image\"==e.type&&(e._.fillpos=[m.x,m.y],e._.fillsize=[m.width,m.height],z(e,1,1,0,0,0))),\"transform\"in i&&e.transform(i.transform),r){var y=+m.cx,B=+m.cy,D=+m.rx||+m.r||0,E=+m.ry||+m.r||0;l.path=c.format(\"ar{0},{1},{2},{3},{4},{1},{4},{1}x\",f((y-D)*u),f((B-E)*u),f((y+D)*u),f((B+E)*u),f(y*u)),e._.dirty=1}if(\"clip-rect\"in i){var G=b(i[\"clip-rect\"]).split(k);if(4==G.length){G[2]=+G[2]+ +G[0],G[3]=+G[3]+ +G[1];var H=l.clipRect||c._g.doc.createElement(\"div\"),I=H.style;I.clip=c.format(\"rect({1}px {2}px {3}px {0}px)\",G),l.clipRect||(I.position=\"absolute\",I.top=0,I.left=0,I.width=e.paper.width+\"px\",I.height=e.paper.height+\"px\",l.parentNode.insertBefore(H,l),H.appendChild(l),l.clipRect=H)}i[\"clip-rect\"]||l.clipRect&&(l.clipRect.style.clip=\"auto\")}if(e.textpath){var J=e.textpath.style;i.font&&(J.font=i.font),i[\"font-family\"]&&(J.fontFamily='\"'+i[\"font-family\"].split(\",\")[0].replace(/^['\"]+|['\"]+$/g,o)+'\"'),i[\"font-size\"]&&(J.fontSize=i[\"font-size\"]),i[\"font-weight\"]&&(J.fontWeight=i[\"font-weight\"]),i[\"font-style\"]&&(J.fontStyle=i[\"font-style\"])}if(\"arrow-start\"in i&&A(s,i[\"arrow-start\"]),\"arrow-end\"in i&&A(s,i[\"arrow-end\"],1),null!=i.opacity||null!=i[\"stroke-width\"]||null!=i.fill||null!=i.src||null!=i.stroke||null!=i[\"stroke-width\"]||null!=i[\"stroke-opacity\"]||null!=i[\"fill-opacity\"]||null!=i[\"stroke-dasharray\"]||null!=i[\"stroke-miterlimit\"]||null!=i[\"stroke-linejoin\"]||null!=i[\"stroke-linecap\"]){var K=l.getElementsByTagName(j),L=!1;if(K=K&&K[0],!K&&(L=K=F(j)),\"image\"==e.type&&i.src&&(K.src=i.src),i.fill&&(K.on=!0),(null==K.on||\"none\"==i.fill||null===i.fill)&&(K.on=!1),K.on&&i.fill){var M=b(i.fill).match(c._ISURL);if(M){K.parentNode==l&&l.removeChild(K),K.rotate=!0,K.src=M[1],K.type=\"tile\";var N=e.getBBox(1);K.position=N.x+n+N.y,e._.fillpos=[N.x,N.y],c._preload(M[1],function(){e._.fillsize=[this.offsetWidth,this.offsetHeight]})}else K.color=c.getRGB(i.fill).hex,K.src=o,K.type=\"solid\",c.getRGB(i.fill).error&&(s.type in{circle:1,ellipse:1}||\"r\"!=b(i.fill).charAt())&&C(s,i.fill,K)&&(m.fill=\"none\",m.gradient=i.fill,K.rotate=!1)}if(\"fill-opacity\"in i||\"opacity\"in i){var O=((+m[\"fill-opacity\"]+1||2)-1)*((+m.opacity+1||2)-1)*((+c.getRGB(i.fill).o+1||2)-1);O=h(g(O,0),1),K.opacity=O,K.src&&(K.color=\"none\")}l.appendChild(K);var P=l.getElementsByTagName(\"stroke\")&&l.getElementsByTagName(\"stroke\")[0],Q=!1;!P&&(Q=P=F(\"stroke\")),(i.stroke&&\"none\"!=i.stroke||i[\"stroke-width\"]||null!=i[\"stroke-opacity\"]||i[\"stroke-dasharray\"]||i[\"stroke-miterlimit\"]||i[\"stroke-linejoin\"]||i[\"stroke-linecap\"])&&(P.on=!0),(\"none\"==i.stroke||null===i.stroke||null==P.on||0==i.stroke||0==i[\"stroke-width\"])&&(P.on=!1);var R=c.getRGB(i.stroke);P.on&&i.stroke&&(P.color=R.hex),O=((+m[\"stroke-opacity\"]+1||2)-1)*((+m.opacity+1||2)-1)*((+R.o+1||2)-1);var S=.75*(d(i[\"stroke-width\"])||1);if(O=h(g(O,0),1),null==i[\"stroke-width\"]&&(S=m[\"stroke-width\"]),i[\"stroke-width\"]&&(P.weight=S),S&&1>S&&(O*=S)&&(P.weight=1),P.opacity=O,i[\"stroke-linejoin\"]&&(P.joinstyle=i[\"stroke-linejoin\"]||\"miter\"),P.miterlimit=i[\"stroke-miterlimit\"]||8,i[\"stroke-linecap\"]&&(P.endcap=\"butt\"==i[\"stroke-linecap\"]?\"flat\":\"square\"==i[\"stroke-linecap\"]?\"square\":\"round\"),\"stroke-dasharray\"in i){var T={\"-\":\"shortdash\",\".\":\"shortdot\",\"-.\":\"shortdashdot\",\"-..\":\"shortdashdotdot\",\". \":\"dot\",\"- \":\"dash\",\"--\":\"longdash\",\"- .\":\"dashdot\",\"--.\":\"longdashdot\",\"--..\":\"longdashdotdot\"};P.dashstyle=T[a](i[\"stroke-dasharray\"])?T[i[\"stroke-dasharray\"]]:o}Q&&l.appendChild(P)}if(\"text\"==s.type){s.paper.canvas.style.display=o;var U=s.paper.span,V=100,W=m.font&&m.font.match(/\\d+(?:\\.\\d*)?(?=px)/);p=U.style,m.font&&(p.font=m.font),m[\"font-family\"]&&(p.fontFamily=m[\"font-family\"]),m[\"font-weight\"]&&(p.fontWeight=m[\"font-weight\"]),m[\"font-style\"]&&(p.fontStyle=m[\"font-style\"]),W=d(m[\"font-size\"]||W&&W[0])||10,p.fontSize=W*V+\"px\",s.textpath.string&&(U.innerHTML=b(s.textpath.string).replace(/</g,\"&#60;\").replace(/&/g,\"&#38;\").replace(/\\n/g,\"<br>\"));var X=U.getBoundingClientRect();s.W=m.w=(X.right-X.left)/V,s.H=m.h=(X.bottom-X.top)/V,s.X=m.x,s.Y=m.y+s.H/2,(\"x\"in i||\"y\"in i)&&(s.path.v=c.format(\"m{0},{1}l{2},{1}\",f(m.x*u),f(m.y*u),f(m.x*u)+1));for(var Y=[\"x\",\"y\",\"text\",\"font\",\"font-family\",\"font-weight\",\"font-style\",\"font-size\"],Z=0,$=Y.length;$>Z;Z++)if(Y[Z]in i){s._.dirty=1;break}switch(m[\"text-anchor\"]){case\"start\":s.textpath.style[\"v-text-align\"]=\"left\",s.bbx=s.W/2;break;case\"end\":s.textpath.style[\"v-text-align\"]=\"right\",s.bbx=-s.W/2;break;default:s.textpath.style[\"v-text-align\"]=\"center\",s.bbx=0}s.textpath.style[\"v-text-kern\"]=!0}},C=function(a,f,g){a.attrs=a.attrs||{};var h=(a.attrs,Math.pow),i=\"linear\",j=\".5 .5\";if(a.attrs.gradient=f,f=b(f).replace(c._radial_gradient,function(a,b,c){return i=\"radial\",b&&c&&(b=d(b),c=d(c),h(b-.5,2)+h(c-.5,2)>.25&&(c=e.sqrt(.25-h(b-.5,2))*(2*(c>.5)-1)+.5),j=b+n+c),o}),f=f.split(/\\s*\\-\\s*/),\"linear\"==i){var k=f.shift();if(k=-d(k),isNaN(k))return null}var l=c._parseDots(f);if(!l)return null;if(a=a.shape||a.node,l.length){a.removeChild(g),g.on=!0,g.method=\"none\",g.color=l[0].color,g.color2=l[l.length-1].color;for(var m=[],p=0,q=l.length;q>p;p++)l[p].offset&&m.push(l[p].offset+n+l[p].color);g.colors=m.length?m.join():\"0% \"+g.color,\"radial\"==i?(g.type=\"gradientTitle\",g.focus=\"100%\",g.focussize=\"0 0\",g.focusposition=j,g.angle=0):(g.type=\"gradient\",g.angle=(270-k)%360),a.appendChild(g)}return 1},D=function(a,b){this[0]=this.node=a,a.raphael=!0,this.id=c._oid++,a.raphaelid=this.id,this.X=0,this.Y=0,this.attrs={},this.paper=b,this.matrix=c.matrix(),this._={transform:[],sx:1,sy:1,dx:0,dy:0,deg:0,dirty:1,dirtyT:1},!b.bottom&&(b.bottom=this),this.prev=b.top,b.top&&(b.top.next=this),b.top=this,this.next=null},E=c.el;D.prototype=E,E.constructor=D,E.transform=function(a){if(null==a)return this._.transform;var d,e=this.paper._viewBoxShift,f=e?\"s\"+[e.scale,e.scale]+\"-1-1t\"+[e.dx,e.dy]:o;e&&(d=a=b(a).replace(/\\.{3}|\\u2026/g,this._.transform||o)),c._extractTransform(this,f+a);var g,h=this.matrix.clone(),i=this.skew,j=this.node,k=~b(this.attrs.fill).indexOf(\"-\"),l=!b(this.attrs.fill).indexOf(\"url(\");if(h.translate(1,1),l||k||\"image\"==this.type)if(i.matrix=\"1 0 0 1\",i.offset=\"0 0\",g=h.split(),k&&g.noRotation||!g.isSimple){j.style.filter=h.toFilter();var m=this.getBBox(),p=this.getBBox(1),q=m.x-p.x,r=m.y-p.y;j.coordorigin=q*-u+n+r*-u,z(this,1,1,q,r,0)}else j.style.filter=o,z(this,g.scalex,g.scaley,g.dx,g.dy,g.rotate);else j.style.filter=o,i.matrix=b(h),i.offset=h.offset();return null!==d&&(this._.transform=d,c._extractTransform(this,d)),this},E.rotate=function(a,c,e){if(this.removed)return this;if(null!=a){if(a=b(a).split(k),a.length-1&&(c=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(c=e),null==c||null==e){var f=this.getBBox(1);c=f.x+f.width/2,e=f.y+f.height/2}return this._.dirtyT=1,this.transform(this._.transform.concat([[\"r\",a,c,e]])),this}},E.translate=function(a,c){return this.removed?this:(a=b(a).split(k),a.length-1&&(c=d(a[1])),a=d(a[0])||0,c=+c||0,this._.bbox&&(this._.bbox.x+=a,this._.bbox.y+=c),this.transform(this._.transform.concat([[\"t\",a,c]])),this)},E.scale=function(a,c,e,f){if(this.removed)return this;if(a=b(a).split(k),a.length-1&&(c=d(a[1]),e=d(a[2]),f=d(a[3]),isNaN(e)&&(e=null),isNaN(f)&&(f=null)),a=d(a[0]),null==c&&(c=a),null==f&&(e=f),null==e||null==f)var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([[\"s\",a,c,e,f]])),this._.dirtyT=1,this},E.hide=function(){return!this.removed&&(this.node.style.display=\"none\"),this},E.show=function(){return!this.removed&&(this.node.style.display=o),this},E.auxGetBBox=c.el.getBBox,E.getBBox=function(){var a=this.auxGetBBox();if(this.paper&&this.paper._viewBoxShift){var b={},c=1/this.paper._viewBoxShift.scale;return b.x=a.x-this.paper._viewBoxShift.dx,b.x*=c,b.y=a.y-this.paper._viewBoxShift.dy,b.y*=c,b.width=a.width*c,b.height=a.height*c,b.x2=b.x+b.width,b.y2=b.y+b.height,b}return a},E._getBBox=function(){return this.removed?{}:{x:this.X+(this.bbx||0)-this.W/2,y:this.Y-this.H,width:this.W,height:this.H}},E.remove=function(){if(!this.removed&&this.node.parentNode){this.paper.__set__&&this.paper.__set__.exclude(this),c.eve.unbind(\"raphael.*.*.\"+this.id),c._tear(this,this.paper),this.node.parentNode.removeChild(this.node),this.shape&&this.shape.parentNode.removeChild(this.shape);for(var a in this)this[a]=\"function\"==typeof this[a]?c._removedFactory(a):null;this.removed=!0}},E.attr=function(b,d){if(this.removed)return this;if(null==b){var e={};for(var f in this.attrs)this.attrs[a](f)&&(e[f]=this.attrs[f]);return e.gradient&&\"none\"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e}if(null==d&&c.is(b,\"string\")){if(b==j&&\"none\"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;for(var g=b.split(k),h={},i=0,m=g.length;m>i;i++)b=g[i],h[b]=b in this.attrs?this.attrs[b]:c.is(this.paper.customAttributes[b],\"function\")?this.paper.customAttributes[b].def:c._availableAttrs[b];return m-1?h:h[g[0]]}if(this.attrs&&null==d&&c.is(b,\"array\")){for(h={},i=0,m=b.length;m>i;i++)h[b[i]]=this.attr(b[i]);return h}var n;null!=d&&(n={},n[b]=d),null==d&&c.is(b,\"object\")&&(n=b);for(var o in n)l(\"raphael.attr.\"+o+\".\"+this.id,this,n[o]);if(n){for(o in this.paper.customAttributes)if(this.paper.customAttributes[a](o)&&n[a](o)&&c.is(this.paper.customAttributes[o],\"function\")){var p=this.paper.customAttributes[o].apply(this,[].concat(n[o]));this.attrs[o]=n[o];for(var q in p)p[a](q)&&(n[q]=p[q])}n.text&&\"text\"==this.type&&(this.textpath.string=n.text),B(this,n)}return this},E.toFront=function(){return!this.removed&&this.node.parentNode.appendChild(this.node),this.paper&&this.paper.top!=this&&c._tofront(this,this.paper),this},E.toBack=function(){return this.removed?this:(this.node.parentNode.firstChild!=this.node&&(this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),c._toback(this,this.paper)),this)},E.insertAfter=function(a){return this.removed?this:(a.constructor==c.st.constructor&&(a=a[a.length-1]),a.node.nextSibling?a.node.parentNode.insertBefore(this.node,a.node.nextSibling):a.node.parentNode.appendChild(this.node),c._insertafter(this,a,this.paper),this)},E.insertBefore=function(a){return this.removed?this:(a.constructor==c.st.constructor&&(a=a[0]),a.node.parentNode.insertBefore(this.node,a.node),c._insertbefore(this,a,this.paper),this)},E.blur=function(a){var b=this.node.runtimeStyle,d=b.filter;return d=d.replace(r,o),0!==+a?(this.attrs.blur=a,b.filter=d+n+m+\".Blur(pixelradius=\"+(+a||1.5)+\")\",b.margin=c.format(\"-{0}px 0 0 -{0}px\",f(+a||1.5))):(b.filter=d,b.margin=0,delete this.attrs.blur),this},c._engine.path=function(a,b){var c=F(\"shape\");c.style.cssText=t,c.coordsize=u+n+u,c.coordorigin=b.coordorigin;var d=new D(c,b),e={fill:\"none\",stroke:\"#000\"};a&&(e.path=a),d.type=\"path\",d.path=[],d.Path=o,B(d,e),b.canvas.appendChild(c);var f=F(\"skew\");return f.on=!0,c.appendChild(f),d.skew=f,d.transform(o),d},c._engine.rect=function(a,b,d,e,f,g){var h=c._rectPath(b,d,e,f,g),i=a.path(h),j=i.attrs;return i.X=j.x=b,i.Y=j.y=d,i.W=j.width=e,i.H=j.height=f,j.r=g,j.path=h,i.type=\"rect\",i},c._engine.ellipse=function(a,b,c,d,e){{var f=a.path();f.attrs}return f.X=b-d,f.Y=c-e,f.W=2*d,f.H=2*e,f.type=\"ellipse\",B(f,{cx:b,cy:c,rx:d,ry:e}),f},c._engine.circle=function(a,b,c,d){{var e=a.path();e.attrs}return e.X=b-d,e.Y=c-d,e.W=e.H=2*d,e.type=\"circle\",B(e,{cx:b,cy:c,r:d}),e},c._engine.image=function(a,b,d,e,f,g){var h=c._rectPath(d,e,f,g),i=a.path(h).attr({stroke:\"none\"}),k=i.attrs,l=i.node,m=l.getElementsByTagName(j)[0];return k.src=b,i.X=k.x=d,i.Y=k.y=e,i.W=k.width=f,i.H=k.height=g,k.path=h,i.type=\"image\",m.parentNode==l&&l.removeChild(m),m.rotate=!0,m.src=b,m.type=\"tile\",i._.fillpos=[d,e],i._.fillsize=[f,g],l.appendChild(m),z(i,1,1,0,0,0),i},c._engine.text=function(a,d,e,g){var h=F(\"shape\"),i=F(\"path\"),j=F(\"textpath\");d=d||0,e=e||0,g=g||\"\",i.v=c.format(\"m{0},{1}l{2},{1}\",f(d*u),f(e*u),f(d*u)+1),i.textpathok=!0,j.string=b(g),j.on=!0,h.style.cssText=t,h.coordsize=u+n+u,h.coordorigin=\"0 0\";var k=new D(h,a),l={fill:\"#000\",stroke:\"none\",font:c._availableAttrs.font,text:g};k.shape=h,k.path=i,k.textpath=j,k.type=\"text\",k.attrs.text=b(g),k.attrs.x=d,k.attrs.y=e,k.attrs.w=1,k.attrs.h=1,B(k,l),h.appendChild(j),h.appendChild(i),a.canvas.appendChild(h);var m=F(\"skew\");return m.on=!0,h.appendChild(m),k.skew=m,k.transform(o),k},c._engine.setSize=function(a,b){var d=this.canvas.style;return this.width=a,this.height=b,a==+a&&(a+=\"px\"),b==+b&&(b+=\"px\"),d.width=a,d.height=b,d.clip=\"rect(0 \"+a+\" \"+b+\" 0)\",this._viewBox&&c._engine.setViewBox.apply(this,this._viewBox),this},c._engine.setViewBox=function(a,b,d,e,f){c.eve(\"raphael.setViewBox\",this,this._viewBox,[a,b,d,e,f]);var g,h,i=this.getSize(),j=i.width,k=i.height;return f&&(g=k/e,h=j/d,j>d*g&&(a-=(j-d*g)/2/g),k>e*h&&(b-=(k-e*h)/2/h)),this._viewBox=[a,b,d,e,!!f],this._viewBoxShift={dx:-a,dy:-b,scale:i},this.forEach(function(a){a.transform(\"...\")}),this};var F;c._engine.initWin=function(a){var b=a.document;b.styleSheets.length<31?b.createStyleSheet().addRule(\".rvml\",\"behavior:url(#default#VML)\"):b.styleSheets[0].addRule(\".rvml\",\"behavior:url(#default#VML)\");try{!b.namespaces.rvml&&b.namespaces.add(\"rvml\",\"urn:schemas-microsoft-com:vml\"),F=function(a){return b.createElement(\"<rvml:\"+a+' class=\"rvml\">')}}catch(c){F=function(a){return b.createElement(\"<\"+a+' xmlns=\"urn:schemas-microsoft.com:vml\" class=\"rvml\">')}}},c._engine.initWin(c._g.win),c._engine.create=function(){var a=c._getContainer.apply(0,arguments),b=a.container,d=a.height,e=a.width,f=a.x,g=a.y;if(!b)throw new Error(\"VML container not found.\");var h=new c._Paper,i=h.canvas=c._g.doc.createElement(\"div\"),j=i.style;return f=f||0,g=g||0,e=e||512,d=d||342,h.width=e,h.height=d,e==+e&&(e+=\"px\"),d==+d&&(d+=\"px\"),h.coordsize=1e3*u+n+1e3*u,h.coordorigin=\"0 0\",h.span=c._g.doc.createElement(\"span\"),h.span.style.cssText=\"position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;\",i.appendChild(h.span),j.cssText=c.format(\"top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden\",e,d),1==b?(c._g.doc.body.appendChild(i),j.left=f+\"px\",j.top=g+\"px\",j.position=\"absolute\"):b.firstChild?b.insertBefore(i,b.firstChild):b.appendChild(i),h.renderfix=function(){},h},c.prototype.clear=function(){c.eve(\"raphael.clear\",this),this.canvas.innerHTML=o,this.span=c._g.doc.createElement(\"span\"),this.span.style.cssText=\"position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;\",this.canvas.appendChild(this.span),this.bottom=this.top=null},c.prototype.remove=function(){c.eve(\"raphael.remove\",this),this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=\"function\"==typeof this[a]?c._removedFactory(a):null;return!0};var G=c.st;for(var H in E)E[a](H)&&!G[a](H)&&(G[H]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(H))}}(),B.was?A.win.Raphael=c:Raphael=c,\"object\"==typeof exports&&(module.exports=c),c});"
  },
  {
    "path": "static/assets/plugins/select2/.bower.json",
    "content": "{\n  \"name\": \"select2\",\n  \"version\": \"3.5.2\",\n  \"main\": [\n    \"select2.js\",\n    \"select2.css\",\n    \"select2.png\",\n    \"select2x2.png\",\n    \"select2-spinner.gif\"\n  ],\n  \"dependencies\": {\n    \"jquery\": \">= 1.7.1\"\n  },\n  \"homepage\": \"https://github.com/ivaynberg/select2\",\n  \"_release\": \"3.5.2\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"3.5.2\",\n    \"commit\": \"0a7ed096f05155bf2a901cf289602cb3aef2f651\"\n  },\n  \"_source\": \"git://github.com/ivaynberg/select2.git\",\n  \"_target\": \"3.5.2\",\n  \"_originalSource\": \"select2\"\n}"
  },
  {
    "path": "static/assets/plugins/select2/.gitignore",
    "content": ".idea\n\n"
  },
  {
    "path": "static/assets/plugins/select2/CONTRIBUTING.md",
    "content": "Contributing to Select2\n=======================\nLooking to contribute something to Select2? **Here's how you can help.**\n\nPlease take a moment to review this document in order to make the contribution\nprocess easy and effective for everyone involved.\n\nFollowing these guidelines helps to communicate that you respect the time of\nthe developers managing and developing this open source project. In return,\nthey should reciprocate that respect in addressing your issue or assessing\npatches and features.\n\nUsing the issue tracker\n-----------------------\nWhen [reporting bugs][reporting-bugs] or\n[requesting features][requesting-features], the\n[issue tracker on GitHub][issue-tracker] is the recommended channel to use.\n\nThe issue tracker **is not** a place for support requests. The\n[mailing list][mailing-list] or [IRC channel][irc-channel] are better places to\nget help.\n\nReporting bugs with Select2\n---------------------------\nWe really appreciate clear bug reports that _consistently_ show an issue\n_within Select2_.\n\nThe ideal bug report follows these guidelines:\n\n1. **Use the [GitHub issue search][issue-search]**  &mdash; Check if the issue\n   has already been reported.\n2. **Check if the issue has been fixed**  &mdash; Try to reproduce the problem\n   using the code in the `master` branch.\n3. **Isolate the problem**  &mdash; Try to create an\n   [isolated test case][isolated-case] that consistently reproduces the problem.\n\nPlease try to be as detailed as possible in your bug report, especially if an\nisolated test case cannot be made. Some useful questions to include the answer\nto are:\n\n- What steps can be used to reproduce the issue?\n- What is the bug and what is the expected outcome?\n- What browser(s) and Operating System have you tested with?\n- Does the bug happen consistently across all tested browsers?\n- What version of jQuery are you using? And what version of Select2?\n- Are you using Select2 with other plugins?\n\nAll of these questions will help people fix and identify any potential bugs.\n\nRequesting features in Select2\n------------------------------\nSelect2 is a large library that carries with it a lot of functionality. Because\nof this, many feature requests will not be implemented in the core library.\n\nBefore starting work on a major feature for Select2, **contact the\n[community][community] first** or you may risk spending a considerable amount of\ntime on something which the project developers are not interested in bringing\ninto the project.\n\n### Select2 4.0\n\nMany feature requests will be closed off until 4.0, where Select2 plans to adopt\na more flexible API.  If you are interested in helping with the development of\nthe next major Select2 release, please send a message to the\n[mailing list][mailing-list] or [irc channel][irc-channel] for more information.\n\nTriaging issues and pull requests\n---------------------------------\nAnyone can help the project maintainers triage issues and review pull requests.\n\n### Handling new issues\n\nSelect2 regularly receives new issues which need to be tested and organized.\n\nWhen a new issue that comes in that is similar to another existing issue, it\nshould be checked to make sure it is not a duplicate.  Duplicates issues should\nbe marked by replying to the issue with \"Duplicate of #[issue number]\" where\n`[issue number]` is the url or issue number for the existing issue.  This will\nallow the project maintainers to quickly close off additional issues and keep\nthe discussion focused within a single issue.\n\nIf you can test issues that are reported to Select2 that contain test cases and\nconfirm under what conditions bugs happen, that will allow others to identify\nwhat causes a bug quicker.\n\n### Reviewing pull requests\n\nIt is very common for pull requests to be opened for issues that contain a clear\nsolution to the problem.  These pull requests should be rigorously reviewed by\nthe community before being accepted.  If you are not sure about a piece of\nsubmitted code, or know of a better way to do something, do not hesitate to make\na comment on the pull request.\n\nIt should also be made clear that **all code contributed to Select** must be\nlicensable under the [Apache 2 or GPL 2 licenses][licensing].  Code that cannot\nbe released under either of these licenses **cannot be accepted** into the\nproject.\n\n[community]: https://github.com/ivaynberg/select2#community\n[reporting-bugs]: #reporting-bugs-with-select2\n[requesting-features]: #requesting-features-in-select2\n[issue-tracker]: https://github.com/ivaynberg/select2/issues\n[mailing-list]: https://github.com/ivaynberg/select2#mailing-list\n[irc-channel]: https://github.com/ivaynberg/select2#irc-channel\n[issue-search]: https://github.com/ivaynberg/select2/search?q=&type=Issues\n[isolated-case]: http://css-tricks.com/6263-reduced-test-cases/\n[licensing]: https://github.com/ivaynberg/select2#copyright-and-license\n"
  },
  {
    "path": "static/assets/plugins/select2/LICENSE",
    "content": "Copyright 2014 Igor Vaynberg\n\nVersion: @@ver@@ Timestamp: @@timestamp@@\n\nThis software is licensed under the Apache License, Version 2.0 (the \"Apache License\") or the GNU\nGeneral Public License version 2 (the \"GPL License\"). You may choose either license to govern your\nuse of this software only upon the condition that you accept all of the terms of either the Apache\nLicense or the GPL License.\n\nYou may obtain a copy of the Apache License and the GPL License at:\n\nhttp://www.apache.org/licenses/LICENSE-2.0\nhttp://www.gnu.org/licenses/gpl-2.0.html\n\nUnless required by applicable law or agreed to in writing, software distributed under the Apache License\nor the GPL Licesnse is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\neither express or implied. See the Apache License and the GPL License for the specific language governing\npermissions and limitations under the Apache License and the GPL License.\n"
  },
  {
    "path": "static/assets/plugins/select2/README.md",
    "content": "Select2\n=======\n\nSelect2 is a jQuery-based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.\n\nTo get started, checkout examples and documentation at http://ivaynberg.github.com/select2\n\nUse cases\n---------\n\n* Enhancing native selects with search.\n* Enhancing native selects with a better multi-select interface.\n* Loading data from JavaScript: easily load items via ajax and have them searchable.\n* Nesting optgroups: native selects only support one level of nested. Select2 does not have this restriction.\n* Tagging: ability to add new items on the fly.\n* Working with large, remote datasets: ability to partially load a dataset based on the search term.\n* Paging of large datasets: easy support for loading more pages when the results are scrolled to the end.\n* Templating: support for custom rendering of results and selections.\n\nBrowser compatibility\n---------------------\n* IE 8+\n* Chrome 8+\n* Firefox 10+\n* Safari 3+\n* Opera 10.6+\n\nUsage\n-----\nYou can source Select2 directly from a CDN like [JSDliver](http://www.jsdelivr.com/#!select2) or [CDNJS](http://www.cdnjs.com/libraries/select2), [download it from this GitHub repo](https://github.com/ivaynberg/select2/tags), or use one of the integrations below.\n\nIntegrations\n------------\n\n* [Wicket-Select2](https://github.com/ivaynberg/wicket-select2) (Java / [Apache Wicket](http://wicket.apache.org))\n* [select2-rails](https://github.com/argerim/select2-rails) (Ruby on Rails)\n* [AngularUI](http://angular-ui.github.io/#ui-select) ([AngularJS](https://angularjs.org/))\n* [Django](https://github.com/applegrew/django-select2)\n* [Symfony](https://github.com/19Gerhard85/sfSelect2WidgetsPlugin)\n* [Symfony2](https://github.com/avocode/FormExtensions)\n* [Bootstrap 2](https://github.com/t0m/select2-bootstrap-css) and [Bootstrap 3](https://github.com/t0m/select2-bootstrap-css/tree/bootstrap3) (CSS skins)\n* [Meteor](https://github.com/nate-strauser/meteor-select2) (modern reactive JavaScript framework; + [Bootstrap 3 skin](https://github.com/esperadomedia/meteor-select2-bootstrap3-css/))\n* [Meteor](https://jquery-select2.meteor.com)\n* [Yii 2.x](http://demos.krajee.com/widgets#select2)\n* [Yii 1.x](https://github.com/tonybolzan/yii-select2)\n* [AtmosphereJS](https://atmospherejs.com/package/jquery-select2)\n\n### Example Integrations\n\n* [Knockout.js](https://github.com/ivaynberg/select2/wiki/Knockout.js-Integration)\n* [Socket.IO](https://github.com/ivaynberg/select2/wiki/Socket.IO-Integration)\n* [PHP](https://github.com/ivaynberg/select2/wiki/PHP-Example)\n* [.Net MVC] (https://github.com/ivaynberg/select2/wiki/.Net-MVC-Example)\n\nInternationalization (i18n)\n---------------------------\n\nSelect2 supports multiple languages by simply including the right language JS\nfile (`select2_locale_it.js`, `select2_locale_nl.js`, etc.) after `select2.js`.\n\nMissing a language? Just copy `select2_locale_en.js.template`, translate\nit, and make a pull request back to Select2 here on GitHub.\n\nDocumentation\n-------------\n\nThe documentation for Select2 is available [through GitHub Pages](https://ivaynberg.github.io/select2/) and is located within this repository in the [`gh-pages` branch](https://github.com/ivaynberg/select2/tree/gh-pages).\n\nCommunity\n---------\n\n### Bug tracker\n\nHave a bug? Please create an issue here on GitHub!\n\nhttps://github.com/ivaynberg/select2/issues\n\n### Mailing list\n\nHave a question? Ask on our mailing list!\n\nselect2@googlegroups.com\n\nhttps://groups.google.com/d/forum/select2\n\n### IRC channel\n\nNeed help implementing Select2 in your project? Ask in our IRC channel!\n\n**Network:** [Freenode](https://freenode.net/) (`chat.freenode.net`)\n\n**Channel:** `#select2`\n\n**Web access:** https://webchat.freenode.net/?channels=select2\n\nCopyright and license\n---------------------\n\nCopyright 2012 Igor Vaynberg\n\nThis software is licensed under the Apache License, Version 2.0 (the \"Apache License\") or the GNU\nGeneral Public License version 2 (the \"GPL License\"). You may choose either license to govern your\nuse of this software only upon the condition that you accept all of the terms of either the Apache\nLicense or the GPL License.\n\nYou may obtain a copy of the Apache License and the GPL License in the LICENSE file, or at:\n\nhttp://www.apache.org/licenses/LICENSE-2.0\nhttp://www.gnu.org/licenses/gpl-2.0.html\n\nUnless required by applicable law or agreed to in writing, software distributed under the Apache License\nor the GPL License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\neither express or implied. See the Apache License and the GPL License for the specific language governing\npermissions and limitations under the Apache License and the GPL License.\n"
  },
  {
    "path": "static/assets/plugins/select2/bower.json",
    "content": "{\n    \"name\": \"select2\",\n    \"version\": \"3.5.2\",\n    \"main\": [\"select2.js\", \"select2.css\", \"select2.png\", \"select2x2.png\", \"select2-spinner.gif\"],\n    \"dependencies\": {\n        \"jquery\": \">= 1.7.1\"\n    }\n}\n"
  },
  {
    "path": "static/assets/plugins/select2/component.json",
    "content": "{\n  \"name\": \"select2\",\n  \"repo\": \"ivaynberg/select2\",\n  \"description\": \"Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.\",\n  \"version\": \"3.5.2\",\n  \"demo\": \"http://ivaynberg.github.io/select2/\",\n  \"keywords\": [\n    \"jquery\"\n  ],\n  \"main\": \"select2.js\",\n  \"styles\": [\n    \"select2.css\",\n    \"select2-bootstrap.css\"\n  ],\n  \"scripts\": [\n    \"select2.js\",\n    \"select2_locale_ar.js\",\n    \"select2_locale_bg.js\",\n    \"select2_locale_ca.js\",\n    \"select2_locale_cs.js\",\n    \"select2_locale_da.js\",\n    \"select2_locale_de.js\",\n    \"select2_locale_el.js\",\n    \"select2_locale_es.js\",\n    \"select2_locale_et.js\",\n    \"select2_locale_eu.js\",\n    \"select2_locale_fa.js\",\n    \"select2_locale_fi.js\",\n    \"select2_locale_fr.js\",\n    \"select2_locale_gl.js\",\n    \"select2_locale_he.js\",\n    \"select2_locale_hr.js\",\n    \"select2_locale_hu.js\",\n    \"select2_locale_id.js\",\n    \"select2_locale_is.js\",\n    \"select2_locale_it.js\",\n    \"select2_locale_ja.js\",\n    \"select2_locale_ka.js\",\n    \"select2_locale_ko.js\",\n    \"select2_locale_lt.js\",\n    \"select2_locale_lv.js\",\n    \"select2_locale_mk.js\",\n    \"select2_locale_ms.js\",\n    \"select2_locale_nl.js\",\n    \"select2_locale_no.js\",\n    \"select2_locale_pl.js\",\n    \"select2_locale_pt-BR.js\",\n    \"select2_locale_pt-PT.js\",\n    \"select2_locale_ro.js\",\n    \"select2_locale_ru.js\",\n    \"select2_locale_sk.js\",\n    \"select2_locale_sv.js\",\n    \"select2_locale_th.js\",\n    \"select2_locale_tr.js\",\n    \"select2_locale_uk.js\",\n    \"select2_locale_vi.js\",\n    \"select2_locale_zh-CN.js\",\n    \"select2_locale_zh-TW.js\"\n  ],\n  \"images\": [\n    \"select2-spinner.gif\",\n    \"select2.png\",\n    \"select2x2.png\"\n  ],\n  \"license\": \"MIT\"\n}\n"
  },
  {
    "path": "static/assets/plugins/select2/composer.json",
    "content": "{\n  \"name\":\n  \"ivaynberg/select2\",\n  \"description\": \"Select2 is a jQuery based replacement for select boxes.\",\n  \"version\": \"3.5.2\",\n  \"type\": \"component\",\n  \"homepage\": \"http://ivaynberg.github.io/select2/\",\n  \"license\": \"Apache-2.0\",\n  \"require\": {\n    \"robloach/component-installer\": \"*\",\n    \"components/jquery\": \">=1.7.1\"\n  },\n  \"extra\": {\n    \"component\": {\n      \"scripts\": [\n        \"select2.js\"\n      ],\n      \"files\": [\n        \"select2.js\",\n        \"select2_locale_*.js\",\n        \"select2.css\",\n        \"select2-bootstrap.css\",\n        \"select2-spinner.gif\",\n        \"select2.png\",\n        \"select2x2.png\"\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "static/assets/plugins/select2/package.json",
    "content": "{\n  \"name\" : \"Select2\",\n  \"description\": \"Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.\",\n  \"homepage\": \"http://ivaynberg.github.io/select2\",\n  \"author\": \"Igor Vaynberg\",\n  \"repository\": {\"type\": \"git\", \"url\": \"git://github.com/ivaynberg/select2.git\"},\n  \"main\": \"select2.js\",\n  \"version\": \"3.5.2\",\n  \"jspm\": {\n    \"main\": \"select2\",\n    \"files\": [\"select2.js\", \"select2.png\", \"select2.css\", \"select2-spinner.gif\"],\n    \"shim\": {\n        \"select2\": {\n            \"imports\": [\"jquery\", \"./select2.css!\"],\n            \"exports\": \"$\"\n        }\n    },\n    \"buildConfig\": { \"uglify\": true }\n  }\n}\n"
  },
  {
    "path": "static/assets/plugins/select2/release.sh",
    "content": "#!/bin/bash\nset -e\n\necho -n \"Enter the version for this release: \"\n\nread ver\n\nif [ ! $ver ]; then\n\techo \"Invalid version.\"\n\texit\nfi\n\nname=\"select2\"\njs=\"$name.js\"\nmini=\"$name.min.js\"\ncss=\"$name.css\"\nrelease=\"$name-$ver\"\ntag=\"$ver\"\nbranch=\"build-$ver\"\ncurbranch=`git branch | grep \"*\" | sed \"s/* //\"`\ntimestamp=$(date)\ntokens=\"s/@@ver@@/$ver/g;s/\\@@timestamp@@/$timestamp/g\"\nremote=\"origin\"\n\necho \"Pulling from origin\"\n\ngit pull\n\necho \"Updating Version Identifiers\"\n\nsed -E -e \"s/\\\"version\\\": \\\"([0-9\\.]+)\\\",/\\\"version\\\": \\\"$ver\\\",/g\" -i -- bower.json select2.jquery.json component.json composer.json package.json\n\ngit add bower.json\ngit add select2.jquery.json\ngit add component.json\ngit add composer.json\ngit add package.json\n\ngit commit -m \"modified version identifiers in descriptors for release $ver\"\ngit push\n\ngit branch \"$branch\"\ngit checkout \"$branch\"\n\necho \"Tokenizing...\"\n\nfind . -name \"$js\" | xargs -I{} sed -e \"$tokens\" -i -- {}\nfind . -name \"$css\" | xargs -I{} sed -e \"$tokens\" -i -- {}\n\nsed -e \"s/latest/$ver/g\" -i -- bower.json\n\ngit add \"$js\"\ngit add \"$css\"\n\necho \"Minifying...\"\n\necho \"/*\" > \"$mini\"\ncat LICENSE | sed \"$tokens\" >> \"$mini\"\necho \"*/\" >> \"$mini\"\n\ncurl -s \\\n\t--data-urlencode \"js_code@$js\" \\\n\thttp://marijnhaverbeke.nl/uglifyjs \\\n\t>> \"$mini\"\n\ngit add \"$mini\"\n\ngit commit -m \"release $ver\"\n\necho \"Tagging...\"\ngit tag -a \"$tag\" -m \"tagged version $ver\"\ngit push \"$remote\" --tags\n\necho \"Cleaning Up...\"\n\ngit checkout \"$curbranch\"\ngit branch -D \"$branch\"\n\necho \"Done\"\n"
  },
  {
    "path": "static/assets/plugins/select2/select2-bootstrap.css",
    "content": ".form-control .select2-choice {\n    border: 0;\n    border-radius: 2px;\n}\n\n.form-control .select2-choice .select2-arrow {\n    border-radius: 0 2px 2px 0;   \n}\n\n.form-control.select2-container {\n    height: auto !important;\n    padding: 0;\n}\n\n.form-control.select2-container.select2-dropdown-open {\n    border-color: #5897FB;\n    border-radius: 3px 3px 0 0;\n}\n\n.form-control .select2-container.select2-dropdown-open .select2-choices {\n    border-radius: 3px 3px 0 0;\n}\n\n.form-control.select2-container .select2-choices {\n    border: 0 !important;\n    border-radius: 3px;\n}\n\n.control-group.warning .select2-container .select2-choice,\n.control-group.warning .select2-container .select2-choices,\n.control-group.warning .select2-container-active .select2-choice,\n.control-group.warning .select2-container-active .select2-choices,\n.control-group.warning .select2-dropdown-open.select2-drop-above .select2-choice,\n.control-group.warning .select2-dropdown-open.select2-drop-above .select2-choices,\n.control-group.warning .select2-container-multi.select2-container-active .select2-choices {\n    border: 1px solid #C09853 !important;\n}\n\n.control-group.warning .select2-container .select2-choice div {\n    border-left: 1px solid #C09853 !important;\n    background: #FCF8E3 !important;\n}\n\n.control-group.error .select2-container .select2-choice,\n.control-group.error .select2-container .select2-choices,\n.control-group.error .select2-container-active .select2-choice,\n.control-group.error .select2-container-active .select2-choices,\n.control-group.error .select2-dropdown-open.select2-drop-above .select2-choice,\n.control-group.error .select2-dropdown-open.select2-drop-above .select2-choices,\n.control-group.error .select2-container-multi.select2-container-active .select2-choices {\n    border: 1px solid #B94A48 !important;\n}\n\n.control-group.error .select2-container .select2-choice div {\n    border-left: 1px solid #B94A48 !important;\n    background: #F2DEDE !important;\n}\n\n.control-group.info .select2-container .select2-choice,\n.control-group.info .select2-container .select2-choices,\n.control-group.info .select2-container-active .select2-choice,\n.control-group.info .select2-container-active .select2-choices,\n.control-group.info .select2-dropdown-open.select2-drop-above .select2-choice,\n.control-group.info .select2-dropdown-open.select2-drop-above .select2-choices,\n.control-group.info .select2-container-multi.select2-container-active .select2-choices {\n    border: 1px solid #3A87AD !important;\n}\n\n.control-group.info .select2-container .select2-choice div {\n    border-left: 1px solid #3A87AD !important;\n    background: #D9EDF7 !important;\n}\n\n.control-group.success .select2-container .select2-choice,\n.control-group.success .select2-container .select2-choices,\n.control-group.success .select2-container-active .select2-choice,\n.control-group.success .select2-container-active .select2-choices,\n.control-group.success .select2-dropdown-open.select2-drop-above .select2-choice,\n.control-group.success .select2-dropdown-open.select2-drop-above .select2-choices,\n.control-group.success .select2-container-multi.select2-container-active .select2-choices {\n    border: 1px solid #468847 !important;\n}\n\n.control-group.success .select2-container .select2-choice div {\n    border-left: 1px solid #468847 !important;\n    background: #DFF0D8 !important;\n}\n"
  },
  {
    "path": "static/assets/plugins/select2/select2.css",
    "content": "/*\nVersion: 3.5.2 Timestamp: Sat Nov  1 14:43:36 EDT 2014\n*/\n.select2-container {\n    margin: 0;\n    position: relative;\n    display: inline-block;\n    /* inline-block for ie7 */\n    zoom: 1;\n    *display: inline;\n    vertical-align: middle;\n}\n\n.select2-container,\n.select2-drop,\n.select2-search,\n.select2-search input {\n  /*\n    Force border-box so that % widths fit the parent\n    container without overlap because of margin/padding.\n    More Info : http://www.quirksmode.org/css/box.html\n  */\n  -webkit-box-sizing: border-box; /* webkit */\n     -moz-box-sizing: border-box; /* firefox */\n          box-sizing: border-box; /* css3 */\n}\n\n.select2-container .select2-choice {\n    display: block;\n    height: 26px;\n    padding: 0 0 0 8px;\n    overflow: hidden;\n    position: relative;\n\n    border: 1px solid #aaa;\n    white-space: nowrap;\n    line-height: 26px;\n    color: #444;\n    text-decoration: none;\n\n    border-radius: 4px;\n\n    background-clip: padding-box;\n\n    -webkit-touch-callout: none;\n      -webkit-user-select: none;\n         -moz-user-select: none;\n          -ms-user-select: none;\n              user-select: none;\n\n    background-color: #fff;\n    background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.5, #fff));\n    background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 50%);\n    background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 50%);\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff', endColorstr = '#eeeeee', GradientType = 0);\n    background-image: linear-gradient(to top, #eee 0%, #fff 50%);\n}\n\nhtml[dir=\"rtl\"] .select2-container .select2-choice {\n    padding: 0 8px 0 0;\n}\n\n.select2-container.select2-drop-above .select2-choice {\n    border-bottom-color: #aaa;\n\n    border-radius: 0 0 4px 4px;\n\n    background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.9, #fff));\n    background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 90%);\n    background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 90%);\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);\n    background-image: linear-gradient(to bottom, #eee 0%, #fff 90%);\n}\n\n.select2-container.select2-allowclear .select2-choice .select2-chosen {\n    margin-right: 42px;\n}\n\n.select2-container .select2-choice > .select2-chosen {\n    margin-right: 26px;\n    display: block;\n    overflow: hidden;\n\n    white-space: nowrap;\n\n    text-overflow: ellipsis;\n    float: none;\n    width: auto;\n}\n\nhtml[dir=\"rtl\"] .select2-container .select2-choice > .select2-chosen {\n    margin-left: 26px;\n    margin-right: 0;\n}\n\n.select2-container .select2-choice abbr {\n    display: none;\n    width: 12px;\n    height: 12px;\n    position: absolute;\n    right: 24px;\n    top: 8px;\n\n    font-size: 1px;\n    text-decoration: none;\n\n    border: 0;\n    background: url('select2.png') right top no-repeat;\n    cursor: pointer;\n    outline: 0;\n}\n\n.select2-container.select2-allowclear .select2-choice abbr {\n    display: inline-block;\n}\n\n.select2-container .select2-choice abbr:hover {\n    background-position: right -11px;\n    cursor: pointer;\n}\n\n.select2-drop-mask {\n    border: 0;\n    margin: 0;\n    padding: 0;\n    position: fixed;\n    left: 0;\n    top: 0;\n    min-height: 100%;\n    min-width: 100%;\n    height: auto;\n    width: auto;\n    opacity: 0;\n    z-index: 9998;\n    /* styles required for IE to work */\n    background-color: #fff;\n    filter: alpha(opacity=0);\n}\n\n.select2-drop {\n    width: 100%;\n    margin-top: -1px;\n    position: absolute;\n    z-index: 9999;\n    top: 100%;\n\n    background: #fff;\n    color: #000;\n    border: 1px solid #aaa;\n    border-top: 0;\n\n    border-radius: 0 0 4px 4px;\n\n    -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);\n            box-shadow: 0 4px 5px rgba(0, 0, 0, .15);\n}\n\n.select2-drop.select2-drop-above {\n    margin-top: 1px;\n    border-top: 1px solid #aaa;\n    border-bottom: 0;\n\n    border-radius: 4px 4px 0 0;\n\n    -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);\n            box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);\n}\n\n.select2-drop-active {\n    border: 1px solid #5897fb;\n    border-top: none;\n}\n\n.select2-drop.select2-drop-above.select2-drop-active {\n    border-top: 1px solid #5897fb;\n}\n\n.select2-drop-auto-width {\n    border-top: 1px solid #aaa;\n    width: auto;\n}\n\n.select2-drop-auto-width .select2-search {\n    padding-top: 4px;\n}\n\n.select2-container .select2-choice .select2-arrow {\n    display: inline-block;\n    width: 18px;\n    height: 100%;\n    position: absolute;\n    right: 0;\n    top: 0;\n\n    border-left: 1px solid #aaa;\n    border-radius: 0 4px 4px 0;\n\n    background-clip: padding-box;\n\n    background: #ccc;\n    background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));\n    background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);\n    background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#cccccc', GradientType = 0);\n    background-image: linear-gradient(to top, #ccc 0%, #eee 60%);\n}\n\nhtml[dir=\"rtl\"] .select2-container .select2-choice .select2-arrow {\n    left: 0;\n    right: auto;\n\n    border-left: none;\n    border-right: 1px solid #aaa;\n    border-radius: 4px 0 0 4px;\n}\n\n.select2-container .select2-choice .select2-arrow b {\n    display: block;\n    width: 100%;\n    height: 100%;\n    background: url('select2.png') no-repeat 0 1px;\n}\n\nhtml[dir=\"rtl\"] .select2-container .select2-choice .select2-arrow b {\n    background-position: 2px 1px;\n}\n\n.select2-search {\n    display: inline-block;\n    width: 100%;\n    min-height: 26px;\n    margin: 0;\n    padding-left: 4px;\n    padding-right: 4px;\n\n    position: relative;\n    z-index: 10000;\n\n    white-space: nowrap;\n}\n\n.select2-search input {\n    width: 100%;\n    height: auto !important;\n    min-height: 26px;\n    padding: 4px 20px 4px 5px;\n    margin: 0;\n\n    outline: 0;\n    font-family: sans-serif;\n    font-size: 1em;\n\n    border: 1px solid #aaa;\n    border-radius: 0;\n\n    -webkit-box-shadow: none;\n            box-shadow: none;\n\n    background: #fff url('select2.png') no-repeat 100% -22px;\n    background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));\n    background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);\n    background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);\n    background: url('select2.png') no-repeat 100% -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;\n}\n\nhtml[dir=\"rtl\"] .select2-search input {\n    padding: 4px 5px 4px 20px;\n\n    background: #fff url('select2.png') no-repeat -37px -22px;\n    background: url('select2.png') no-repeat -37px -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));\n    background: url('select2.png') no-repeat -37px -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);\n    background: url('select2.png') no-repeat -37px -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);\n    background: url('select2.png') no-repeat -37px -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;\n}\n\n.select2-drop.select2-drop-above .select2-search input {\n    margin-top: 4px;\n}\n\n.select2-search input.select2-active {\n    background: #fff url('select2-spinner.gif') no-repeat 100%;\n    background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));\n    background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);\n    background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);\n    background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;\n}\n\n.select2-container-active .select2-choice,\n.select2-container-active .select2-choices {\n    border: 1px solid #5897fb;\n    outline: none;\n\n    -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);\n            box-shadow: 0 0 5px rgba(0, 0, 0, .3);\n}\n\n.select2-dropdown-open .select2-choice {\n    border-bottom-color: transparent;\n    -webkit-box-shadow: 0 1px 0 #fff inset;\n            box-shadow: 0 1px 0 #fff inset;\n\n    border-bottom-left-radius: 0;\n    border-bottom-right-radius: 0;\n\n    background-color: #eee;\n    background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #fff), color-stop(0.5, #eee));\n    background-image: -webkit-linear-gradient(center bottom, #fff 0%, #eee 50%);\n    background-image: -moz-linear-gradient(center bottom, #fff 0%, #eee 50%);\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);\n    background-image: linear-gradient(to top, #fff 0%, #eee 50%);\n}\n\n.select2-dropdown-open.select2-drop-above .select2-choice,\n.select2-dropdown-open.select2-drop-above .select2-choices {\n    border: 1px solid #5897fb;\n    border-top-color: transparent;\n\n    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(0.5, #eee));\n    background-image: -webkit-linear-gradient(center top, #fff 0%, #eee 50%);\n    background-image: -moz-linear-gradient(center top, #fff 0%, #eee 50%);\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);\n    background-image: linear-gradient(to bottom, #fff 0%, #eee 50%);\n}\n\n.select2-dropdown-open .select2-choice .select2-arrow {\n    background: transparent;\n    border-left: none;\n    filter: none;\n}\nhtml[dir=\"rtl\"] .select2-dropdown-open .select2-choice .select2-arrow {\n    border-right: none;\n}\n\n.select2-dropdown-open .select2-choice .select2-arrow b {\n    background-position: -18px 1px;\n}\n\nhtml[dir=\"rtl\"] .select2-dropdown-open .select2-choice .select2-arrow b {\n    background-position: -16px 1px;\n}\n\n.select2-hidden-accessible {\n    border: 0;\n    clip: rect(0 0 0 0);\n    height: 1px;\n    margin: -1px;\n    overflow: hidden;\n    padding: 0;\n    position: absolute;\n    width: 1px;\n}\n\n/* results */\n.select2-results {\n    max-height: 200px;\n    padding: 0 0 0 4px;\n    margin: 4px 4px 4px 0;\n    position: relative;\n    overflow-x: hidden;\n    overflow-y: auto;\n    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nhtml[dir=\"rtl\"] .select2-results {\n    padding: 0 4px 0 0;\n    margin: 4px 0 4px 4px;\n}\n\n.select2-results ul.select2-result-sub {\n    margin: 0;\n    padding-left: 0;\n}\n\n.select2-results li {\n    list-style: none;\n    display: list-item;\n    background-image: none;\n}\n\n.select2-results li.select2-result-with-children > .select2-result-label {\n    font-weight: bold;\n}\n\n.select2-results .select2-result-label {\n    padding: 3px 7px 4px;\n    margin: 0;\n    cursor: pointer;\n\n    min-height: 1em;\n\n    -webkit-touch-callout: none;\n      -webkit-user-select: none;\n         -moz-user-select: none;\n          -ms-user-select: none;\n              user-select: none;\n}\n\n.select2-results-dept-1 .select2-result-label { padding-left: 20px }\n.select2-results-dept-2 .select2-result-label { padding-left: 40px }\n.select2-results-dept-3 .select2-result-label { padding-left: 60px }\n.select2-results-dept-4 .select2-result-label { padding-left: 80px }\n.select2-results-dept-5 .select2-result-label { padding-left: 100px }\n.select2-results-dept-6 .select2-result-label { padding-left: 110px }\n.select2-results-dept-7 .select2-result-label { padding-left: 120px }\n\n.select2-results .select2-highlighted {\n    background: #3875d7;\n    color: #fff;\n}\n\n.select2-results li em {\n    background: #feffde;\n    font-style: normal;\n}\n\n.select2-results .select2-highlighted em {\n    background: transparent;\n}\n\n.select2-results .select2-highlighted ul {\n    background: #fff;\n    color: #000;\n}\n\n.select2-results .select2-no-results,\n.select2-results .select2-searching,\n.select2-results .select2-ajax-error,\n.select2-results .select2-selection-limit {\n    background: #f4f4f4;\n    display: list-item;\n    padding-left: 5px;\n}\n\n/*\ndisabled look for disabled choices in the results dropdown\n*/\n.select2-results .select2-disabled.select2-highlighted {\n    color: #666;\n    background: #f4f4f4;\n    display: list-item;\n    cursor: default;\n}\n.select2-results .select2-disabled {\n  background: #f4f4f4;\n  display: list-item;\n  cursor: default;\n}\n\n.select2-results .select2-selected {\n    display: none;\n}\n\n.select2-more-results.select2-active {\n    background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%;\n}\n\n.select2-results .select2-ajax-error {\n    background: rgba(255, 50, 50, .2);\n}\n\n.select2-more-results {\n    background: #f4f4f4;\n    display: list-item;\n}\n\n/* disabled styles */\n\n.select2-container.select2-container-disabled .select2-choice {\n    background-color: #f4f4f4;\n    background-image: none;\n    border: 1px solid #ddd;\n    cursor: default;\n}\n\n.select2-container.select2-container-disabled .select2-choice .select2-arrow {\n    background-color: #f4f4f4;\n    background-image: none;\n    border-left: 0;\n}\n\n.select2-container.select2-container-disabled .select2-choice abbr {\n    display: none;\n}\n\n\n/* multiselect */\n\n.select2-container-multi .select2-choices {\n    height: auto !important;\n    height: 1%;\n    margin: 0;\n    padding: 0 5px 0 0;\n    position: relative;\n\n    border: 1px solid #aaa;\n    cursor: text;\n    overflow: hidden;\n\n    background-color: #fff;\n    background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eee), color-stop(15%, #fff));\n    background-image: -webkit-linear-gradient(top, #eee 1%, #fff 15%);\n    background-image: -moz-linear-gradient(top, #eee 1%, #fff 15%);\n    background-image: linear-gradient(to bottom, #eee 1%, #fff 15%);\n}\n\nhtml[dir=\"rtl\"] .select2-container-multi .select2-choices {\n    padding: 0 0 0 5px;\n}\n\n.select2-locked {\n  padding: 3px 5px 3px 5px !important;\n}\n\n.select2-container-multi .select2-choices {\n    min-height: 26px;\n}\n\n.select2-container-multi.select2-container-active .select2-choices {\n    border: 1px solid #5897fb;\n    outline: none;\n\n    -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);\n            box-shadow: 0 0 5px rgba(0, 0, 0, .3);\n}\n.select2-container-multi .select2-choices li {\n    float: left;\n    list-style: none;\n}\nhtml[dir=\"rtl\"] .select2-container-multi .select2-choices li\n{\n    float: right;\n}\n.select2-container-multi .select2-choices .select2-search-field {\n    margin: 0;\n    padding: 0;\n    white-space: nowrap;\n}\n\n.select2-container-multi .select2-choices .select2-search-field input {\n    padding: 5px;\n    margin: 1px 0;\n\n    font-family: sans-serif;\n    font-size: 100%;\n    color: #666;\n    outline: 0;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n    background: transparent !important;\n}\n\n.select2-container-multi .select2-choices .select2-search-field input.select2-active {\n    background: #fff url('select2-spinner.gif') no-repeat 100% !important;\n}\n\n.select2-default {\n    color: #999 !important;\n}\n\n.select2-container-multi .select2-choices .select2-search-choice {\n    padding: 3px 5px 3px 18px;\n    margin: 3px 0 3px 5px;\n    position: relative;\n\n    line-height: 13px;\n    color: #333;\n    cursor: default;\n    border: 1px solid #aaaaaa;\n\n    border-radius: 3px;\n\n    -webkit-box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);\n            box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);\n\n    background-clip: padding-box;\n\n    -webkit-touch-callout: none;\n      -webkit-user-select: none;\n         -moz-user-select: none;\n          -ms-user-select: none;\n              user-select: none;\n\n    background-color: #e4e4e4;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0);\n    background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee));\n    background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);\n    background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);\n    background-image: linear-gradient(to bottom, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);\n}\nhtml[dir=\"rtl\"] .select2-container-multi .select2-choices .select2-search-choice\n{\n    margin: 3px 5px 3px 0;\n    padding: 3px 18px 3px 5px;\n}\n.select2-container-multi .select2-choices .select2-search-choice .select2-chosen {\n    cursor: default;\n}\n.select2-container-multi .select2-choices .select2-search-choice-focus {\n    background: #d4d4d4;\n}\n\n.select2-search-choice-close {\n    display: block;\n    width: 12px;\n    height: 13px;\n    position: absolute;\n    right: 3px;\n    top: 4px;\n\n    font-size: 1px;\n    outline: none;\n    background: url('select2.png') right top no-repeat;\n}\nhtml[dir=\"rtl\"] .select2-search-choice-close {\n    right: auto;\n    left: 3px;\n}\n\n.select2-container-multi .select2-search-choice-close {\n    left: 3px;\n}\n\nhtml[dir=\"rtl\"] .select2-container-multi .select2-search-choice-close {\n    left: auto;\n    right: 2px;\n}\n\n.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {\n  background-position: right -11px;\n}\n.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {\n    background-position: right -11px;\n}\n\n/* disabled styles */\n.select2-container-multi.select2-container-disabled .select2-choices {\n    background-color: #f4f4f4;\n    background-image: none;\n    border: 1px solid #ddd;\n    cursor: default;\n}\n\n.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {\n    padding: 3px 5px 3px 5px;\n    border: 1px solid #ddd;\n    background-image: none;\n    background-color: #f4f4f4;\n}\n\n.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close {    display: none;\n    background: none;\n}\n/* end multiselect */\n\n\n.select2-result-selectable .select2-match,\n.select2-result-unselectable .select2-match {\n    text-decoration: underline;\n}\n\n.select2-offscreen, .select2-offscreen:focus {\n    clip: rect(0 0 0 0) !important;\n    width: 1px !important;\n    height: 1px !important;\n    border: 0 !important;\n    margin: 0 !important;\n    padding: 0 !important;\n    overflow: hidden !important;\n    position: absolute !important;\n    outline: 0 !important;\n    left: 0px !important;\n    top: 0px !important;\n}\n\n.select2-display-none {\n    display: none;\n}\n\n.select2-measure-scrollbar {\n    position: absolute;\n    top: -10000px;\n    left: -10000px;\n    width: 100px;\n    height: 100px;\n    overflow: scroll;\n}\n\n/* Retina-ize icons */\n\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 2dppx)  {\n    .select2-search input,\n    .select2-search-choice-close,\n    .select2-container .select2-choice abbr,\n    .select2-container .select2-choice .select2-arrow b {\n        background-image: url('select2x2.png') !important;\n        background-repeat: no-repeat !important;\n        background-size: 60px 40px !important;\n    }\n\n    .select2-search input {\n        background-position: 100% -21px !important;\n    }\n}\n"
  },
  {
    "path": "static/assets/plugins/select2/select2.jquery.json",
    "content": "{\n    \"name\": \"select2\",\n    \"title\": \"Select2\",\n    \"description\": \"Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.\",\n    \"keywords\": [\n        \"select\",\n        \"autocomplete\",\n        \"typeahead\",\n        \"dropdown\",\n        \"multiselect\",\n        \"tag\",\n        \"tagging\"\n    ],\n    \"version\": \"3.5.2\",\n    \"author\": {\n        \"name\": \"Igor Vaynberg\",\n        \"url\": \"https://github.com/ivaynberg\"\n    },\n    \"licenses\": [\n        {\n            \"type\": \"Apache\",\n            \"url\": \"http://www.apache.org/licenses/LICENSE-2.0\"\n        },\n        {\n            \"type\": \"GPL v2\",\n            \"url\": \"http://www.gnu.org/licenses/gpl-2.0.html\"\n        }\n    ],\n    \"bugs\": \"https://github.com/ivaynberg/select2/issues\",\n    \"homepage\": \"http://ivaynberg.github.com/select2\",\n    \"docs\": \"http://ivaynberg.github.com/select2/\",\n    \"download\": \"https://github.com/ivaynberg/select2/tags\",\n    \"dependencies\": {\n        \"jquery\": \">=1.7.1\"\n    }\n}\n"
  },
  {
    "path": "static/assets/plugins/select2/select2.js",
    "content": "/*\nCopyright 2012 Igor Vaynberg\n\nVersion: 3.5.2 Timestamp: Sat Nov  1 14:43:36 EDT 2014\n\nThis software is licensed under the Apache License, Version 2.0 (the \"Apache License\") or the GNU\nGeneral Public License version 2 (the \"GPL License\"). You may choose either license to govern your\nuse of this software only upon the condition that you accept all of the terms of either the Apache\nLicense or the GPL License.\n\nYou may obtain a copy of the Apache License and the GPL License at:\n\n    http://www.apache.org/licenses/LICENSE-2.0\n    http://www.gnu.org/licenses/gpl-2.0.html\n\nUnless required by applicable law or agreed to in writing, software distributed under the\nApache License or the GPL License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\nCONDITIONS OF ANY KIND, either express or implied. See the Apache License and the GPL License for\nthe specific language governing permissions and limitations under the Apache License and the GPL License.\n*/\n(function ($) {\n    if(typeof $.fn.each2 == \"undefined\") {\n        $.extend($.fn, {\n            /*\n            * 4-10 times faster .each replacement\n            * use it carefully, as it overrides jQuery context of element on each iteration\n            */\n            each2 : function (c) {\n                var j = $([0]), i = -1, l = this.length;\n                while (\n                    ++i < l\n                    && (j.context = j[0] = this[i])\n                    && c.call(j[0], i, j) !== false //\"this\"=DOM, i=index, j=jQuery object\n                );\n                return this;\n            }\n        });\n    }\n})(jQuery);\n\n(function ($, undefined) {\n    \"use strict\";\n    /*global document, window, jQuery, console */\n\n    if (window.Select2 !== undefined) {\n        return;\n    }\n\n    var AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer,\n        lastMousePosition={x:0,y:0}, $document, scrollBarDimensions,\n\n    KEY = {\n        TAB: 9,\n        ENTER: 13,\n        ESC: 27,\n        SPACE: 32,\n        LEFT: 37,\n        UP: 38,\n        RIGHT: 39,\n        DOWN: 40,\n        SHIFT: 16,\n        CTRL: 17,\n        ALT: 18,\n        PAGE_UP: 33,\n        PAGE_DOWN: 34,\n        HOME: 36,\n        END: 35,\n        BACKSPACE: 8,\n        DELETE: 46,\n        isArrow: function (k) {\n            k = k.which ? k.which : k;\n            switch (k) {\n            case KEY.LEFT:\n            case KEY.RIGHT:\n            case KEY.UP:\n            case KEY.DOWN:\n                return true;\n            }\n            return false;\n        },\n        isControl: function (e) {\n            var k = e.which;\n            switch (k) {\n            case KEY.SHIFT:\n            case KEY.CTRL:\n            case KEY.ALT:\n                return true;\n            }\n\n            if (e.metaKey) return true;\n\n            return false;\n        },\n        isFunctionKey: function (k) {\n            k = k.which ? k.which : k;\n            return k >= 112 && k <= 123;\n        }\n    },\n    MEASURE_SCROLLBAR_TEMPLATE = \"<div class='select2-measure-scrollbar'></div>\",\n\n    DIACRITICS = {\"\\u24B6\":\"A\",\"\\uFF21\":\"A\",\"\\u00C0\":\"A\",\"\\u00C1\":\"A\",\"\\u00C2\":\"A\",\"\\u1EA6\":\"A\",\"\\u1EA4\":\"A\",\"\\u1EAA\":\"A\",\"\\u1EA8\":\"A\",\"\\u00C3\":\"A\",\"\\u0100\":\"A\",\"\\u0102\":\"A\",\"\\u1EB0\":\"A\",\"\\u1EAE\":\"A\",\"\\u1EB4\":\"A\",\"\\u1EB2\":\"A\",\"\\u0226\":\"A\",\"\\u01E0\":\"A\",\"\\u00C4\":\"A\",\"\\u01DE\":\"A\",\"\\u1EA2\":\"A\",\"\\u00C5\":\"A\",\"\\u01FA\":\"A\",\"\\u01CD\":\"A\",\"\\u0200\":\"A\",\"\\u0202\":\"A\",\"\\u1EA0\":\"A\",\"\\u1EAC\":\"A\",\"\\u1EB6\":\"A\",\"\\u1E00\":\"A\",\"\\u0104\":\"A\",\"\\u023A\":\"A\",\"\\u2C6F\":\"A\",\"\\uA732\":\"AA\",\"\\u00C6\":\"AE\",\"\\u01FC\":\"AE\",\"\\u01E2\":\"AE\",\"\\uA734\":\"AO\",\"\\uA736\":\"AU\",\"\\uA738\":\"AV\",\"\\uA73A\":\"AV\",\"\\uA73C\":\"AY\",\"\\u24B7\":\"B\",\"\\uFF22\":\"B\",\"\\u1E02\":\"B\",\"\\u1E04\":\"B\",\"\\u1E06\":\"B\",\"\\u0243\":\"B\",\"\\u0182\":\"B\",\"\\u0181\":\"B\",\"\\u24B8\":\"C\",\"\\uFF23\":\"C\",\"\\u0106\":\"C\",\"\\u0108\":\"C\",\"\\u010A\":\"C\",\"\\u010C\":\"C\",\"\\u00C7\":\"C\",\"\\u1E08\":\"C\",\"\\u0187\":\"C\",\"\\u023B\":\"C\",\"\\uA73E\":\"C\",\"\\u24B9\":\"D\",\"\\uFF24\":\"D\",\"\\u1E0A\":\"D\",\"\\u010E\":\"D\",\"\\u1E0C\":\"D\",\"\\u1E10\":\"D\",\"\\u1E12\":\"D\",\"\\u1E0E\":\"D\",\"\\u0110\":\"D\",\"\\u018B\":\"D\",\"\\u018A\":\"D\",\"\\u0189\":\"D\",\"\\uA779\":\"D\",\"\\u01F1\":\"DZ\",\"\\u01C4\":\"DZ\",\"\\u01F2\":\"Dz\",\"\\u01C5\":\"Dz\",\"\\u24BA\":\"E\",\"\\uFF25\":\"E\",\"\\u00C8\":\"E\",\"\\u00C9\":\"E\",\"\\u00CA\":\"E\",\"\\u1EC0\":\"E\",\"\\u1EBE\":\"E\",\"\\u1EC4\":\"E\",\"\\u1EC2\":\"E\",\"\\u1EBC\":\"E\",\"\\u0112\":\"E\",\"\\u1E14\":\"E\",\"\\u1E16\":\"E\",\"\\u0114\":\"E\",\"\\u0116\":\"E\",\"\\u00CB\":\"E\",\"\\u1EBA\":\"E\",\"\\u011A\":\"E\",\"\\u0204\":\"E\",\"\\u0206\":\"E\",\"\\u1EB8\":\"E\",\"\\u1EC6\":\"E\",\"\\u0228\":\"E\",\"\\u1E1C\":\"E\",\"\\u0118\":\"E\",\"\\u1E18\":\"E\",\"\\u1E1A\":\"E\",\"\\u0190\":\"E\",\"\\u018E\":\"E\",\"\\u24BB\":\"F\",\"\\uFF26\":\"F\",\"\\u1E1E\":\"F\",\"\\u0191\":\"F\",\"\\uA77B\":\"F\",\"\\u24BC\":\"G\",\"\\uFF27\":\"G\",\"\\u01F4\":\"G\",\"\\u011C\":\"G\",\"\\u1E20\":\"G\",\"\\u011E\":\"G\",\"\\u0120\":\"G\",\"\\u01E6\":\"G\",\"\\u0122\":\"G\",\"\\u01E4\":\"G\",\"\\u0193\":\"G\",\"\\uA7A0\":\"G\",\"\\uA77D\":\"G\",\"\\uA77E\":\"G\",\"\\u24BD\":\"H\",\"\\uFF28\":\"H\",\"\\u0124\":\"H\",\"\\u1E22\":\"H\",\"\\u1E26\":\"H\",\"\\u021E\":\"H\",\"\\u1E24\":\"H\",\"\\u1E28\":\"H\",\"\\u1E2A\":\"H\",\"\\u0126\":\"H\",\"\\u2C67\":\"H\",\"\\u2C75\":\"H\",\"\\uA78D\":\"H\",\"\\u24BE\":\"I\",\"\\uFF29\":\"I\",\"\\u00CC\":\"I\",\"\\u00CD\":\"I\",\"\\u00CE\":\"I\",\"\\u0128\":\"I\",\"\\u012A\":\"I\",\"\\u012C\":\"I\",\"\\u0130\":\"I\",\"\\u00CF\":\"I\",\"\\u1E2E\":\"I\",\"\\u1EC8\":\"I\",\"\\u01CF\":\"I\",\"\\u0208\":\"I\",\"\\u020A\":\"I\",\"\\u1ECA\":\"I\",\"\\u012E\":\"I\",\"\\u1E2C\":\"I\",\"\\u0197\":\"I\",\"\\u24BF\":\"J\",\"\\uFF2A\":\"J\",\"\\u0134\":\"J\",\"\\u0248\":\"J\",\"\\u24C0\":\"K\",\"\\uFF2B\":\"K\",\"\\u1E30\":\"K\",\"\\u01E8\":\"K\",\"\\u1E32\":\"K\",\"\\u0136\":\"K\",\"\\u1E34\":\"K\",\"\\u0198\":\"K\",\"\\u2C69\":\"K\",\"\\uA740\":\"K\",\"\\uA742\":\"K\",\"\\uA744\":\"K\",\"\\uA7A2\":\"K\",\"\\u24C1\":\"L\",\"\\uFF2C\":\"L\",\"\\u013F\":\"L\",\"\\u0139\":\"L\",\"\\u013D\":\"L\",\"\\u1E36\":\"L\",\"\\u1E38\":\"L\",\"\\u013B\":\"L\",\"\\u1E3C\":\"L\",\"\\u1E3A\":\"L\",\"\\u0141\":\"L\",\"\\u023D\":\"L\",\"\\u2C62\":\"L\",\"\\u2C60\":\"L\",\"\\uA748\":\"L\",\"\\uA746\":\"L\",\"\\uA780\":\"L\",\"\\u01C7\":\"LJ\",\"\\u01C8\":\"Lj\",\"\\u24C2\":\"M\",\"\\uFF2D\":\"M\",\"\\u1E3E\":\"M\",\"\\u1E40\":\"M\",\"\\u1E42\":\"M\",\"\\u2C6E\":\"M\",\"\\u019C\":\"M\",\"\\u24C3\":\"N\",\"\\uFF2E\":\"N\",\"\\u01F8\":\"N\",\"\\u0143\":\"N\",\"\\u00D1\":\"N\",\"\\u1E44\":\"N\",\"\\u0147\":\"N\",\"\\u1E46\":\"N\",\"\\u0145\":\"N\",\"\\u1E4A\":\"N\",\"\\u1E48\":\"N\",\"\\u0220\":\"N\",\"\\u019D\":\"N\",\"\\uA790\":\"N\",\"\\uA7A4\":\"N\",\"\\u01CA\":\"NJ\",\"\\u01CB\":\"Nj\",\"\\u24C4\":\"O\",\"\\uFF2F\":\"O\",\"\\u00D2\":\"O\",\"\\u00D3\":\"O\",\"\\u00D4\":\"O\",\"\\u1ED2\":\"O\",\"\\u1ED0\":\"O\",\"\\u1ED6\":\"O\",\"\\u1ED4\":\"O\",\"\\u00D5\":\"O\",\"\\u1E4C\":\"O\",\"\\u022C\":\"O\",\"\\u1E4E\":\"O\",\"\\u014C\":\"O\",\"\\u1E50\":\"O\",\"\\u1E52\":\"O\",\"\\u014E\":\"O\",\"\\u022E\":\"O\",\"\\u0230\":\"O\",\"\\u00D6\":\"O\",\"\\u022A\":\"O\",\"\\u1ECE\":\"O\",\"\\u0150\":\"O\",\"\\u01D1\":\"O\",\"\\u020C\":\"O\",\"\\u020E\":\"O\",\"\\u01A0\":\"O\",\"\\u1EDC\":\"O\",\"\\u1EDA\":\"O\",\"\\u1EE0\":\"O\",\"\\u1EDE\":\"O\",\"\\u1EE2\":\"O\",\"\\u1ECC\":\"O\",\"\\u1ED8\":\"O\",\"\\u01EA\":\"O\",\"\\u01EC\":\"O\",\"\\u00D8\":\"O\",\"\\u01FE\":\"O\",\"\\u0186\":\"O\",\"\\u019F\":\"O\",\"\\uA74A\":\"O\",\"\\uA74C\":\"O\",\"\\u01A2\":\"OI\",\"\\uA74E\":\"OO\",\"\\u0222\":\"OU\",\"\\u24C5\":\"P\",\"\\uFF30\":\"P\",\"\\u1E54\":\"P\",\"\\u1E56\":\"P\",\"\\u01A4\":\"P\",\"\\u2C63\":\"P\",\"\\uA750\":\"P\",\"\\uA752\":\"P\",\"\\uA754\":\"P\",\"\\u24C6\":\"Q\",\"\\uFF31\":\"Q\",\"\\uA756\":\"Q\",\"\\uA758\":\"Q\",\"\\u024A\":\"Q\",\"\\u24C7\":\"R\",\"\\uFF32\":\"R\",\"\\u0154\":\"R\",\"\\u1E58\":\"R\",\"\\u0158\":\"R\",\"\\u0210\":\"R\",\"\\u0212\":\"R\",\"\\u1E5A\":\"R\",\"\\u1E5C\":\"R\",\"\\u0156\":\"R\",\"\\u1E5E\":\"R\",\"\\u024C\":\"R\",\"\\u2C64\":\"R\",\"\\uA75A\":\"R\",\"\\uA7A6\":\"R\",\"\\uA782\":\"R\",\"\\u24C8\":\"S\",\"\\uFF33\":\"S\",\"\\u1E9E\":\"S\",\"\\u015A\":\"S\",\"\\u1E64\":\"S\",\"\\u015C\":\"S\",\"\\u1E60\":\"S\",\"\\u0160\":\"S\",\"\\u1E66\":\"S\",\"\\u1E62\":\"S\",\"\\u1E68\":\"S\",\"\\u0218\":\"S\",\"\\u015E\":\"S\",\"\\u2C7E\":\"S\",\"\\uA7A8\":\"S\",\"\\uA784\":\"S\",\"\\u24C9\":\"T\",\"\\uFF34\":\"T\",\"\\u1E6A\":\"T\",\"\\u0164\":\"T\",\"\\u1E6C\":\"T\",\"\\u021A\":\"T\",\"\\u0162\":\"T\",\"\\u1E70\":\"T\",\"\\u1E6E\":\"T\",\"\\u0166\":\"T\",\"\\u01AC\":\"T\",\"\\u01AE\":\"T\",\"\\u023E\":\"T\",\"\\uA786\":\"T\",\"\\uA728\":\"TZ\",\"\\u24CA\":\"U\",\"\\uFF35\":\"U\",\"\\u00D9\":\"U\",\"\\u00DA\":\"U\",\"\\u00DB\":\"U\",\"\\u0168\":\"U\",\"\\u1E78\":\"U\",\"\\u016A\":\"U\",\"\\u1E7A\":\"U\",\"\\u016C\":\"U\",\"\\u00DC\":\"U\",\"\\u01DB\":\"U\",\"\\u01D7\":\"U\",\"\\u01D5\":\"U\",\"\\u01D9\":\"U\",\"\\u1EE6\":\"U\",\"\\u016E\":\"U\",\"\\u0170\":\"U\",\"\\u01D3\":\"U\",\"\\u0214\":\"U\",\"\\u0216\":\"U\",\"\\u01AF\":\"U\",\"\\u1EEA\":\"U\",\"\\u1EE8\":\"U\",\"\\u1EEE\":\"U\",\"\\u1EEC\":\"U\",\"\\u1EF0\":\"U\",\"\\u1EE4\":\"U\",\"\\u1E72\":\"U\",\"\\u0172\":\"U\",\"\\u1E76\":\"U\",\"\\u1E74\":\"U\",\"\\u0244\":\"U\",\"\\u24CB\":\"V\",\"\\uFF36\":\"V\",\"\\u1E7C\":\"V\",\"\\u1E7E\":\"V\",\"\\u01B2\":\"V\",\"\\uA75E\":\"V\",\"\\u0245\":\"V\",\"\\uA760\":\"VY\",\"\\u24CC\":\"W\",\"\\uFF37\":\"W\",\"\\u1E80\":\"W\",\"\\u1E82\":\"W\",\"\\u0174\":\"W\",\"\\u1E86\":\"W\",\"\\u1E84\":\"W\",\"\\u1E88\":\"W\",\"\\u2C72\":\"W\",\"\\u24CD\":\"X\",\"\\uFF38\":\"X\",\"\\u1E8A\":\"X\",\"\\u1E8C\":\"X\",\"\\u24CE\":\"Y\",\"\\uFF39\":\"Y\",\"\\u1EF2\":\"Y\",\"\\u00DD\":\"Y\",\"\\u0176\":\"Y\",\"\\u1EF8\":\"Y\",\"\\u0232\":\"Y\",\"\\u1E8E\":\"Y\",\"\\u0178\":\"Y\",\"\\u1EF6\":\"Y\",\"\\u1EF4\":\"Y\",\"\\u01B3\":\"Y\",\"\\u024E\":\"Y\",\"\\u1EFE\":\"Y\",\"\\u24CF\":\"Z\",\"\\uFF3A\":\"Z\",\"\\u0179\":\"Z\",\"\\u1E90\":\"Z\",\"\\u017B\":\"Z\",\"\\u017D\":\"Z\",\"\\u1E92\":\"Z\",\"\\u1E94\":\"Z\",\"\\u01B5\":\"Z\",\"\\u0224\":\"Z\",\"\\u2C7F\":\"Z\",\"\\u2C6B\":\"Z\",\"\\uA762\":\"Z\",\"\\u24D0\":\"a\",\"\\uFF41\":\"a\",\"\\u1E9A\":\"a\",\"\\u00E0\":\"a\",\"\\u00E1\":\"a\",\"\\u00E2\":\"a\",\"\\u1EA7\":\"a\",\"\\u1EA5\":\"a\",\"\\u1EAB\":\"a\",\"\\u1EA9\":\"a\",\"\\u00E3\":\"a\",\"\\u0101\":\"a\",\"\\u0103\":\"a\",\"\\u1EB1\":\"a\",\"\\u1EAF\":\"a\",\"\\u1EB5\":\"a\",\"\\u1EB3\":\"a\",\"\\u0227\":\"a\",\"\\u01E1\":\"a\",\"\\u00E4\":\"a\",\"\\u01DF\":\"a\",\"\\u1EA3\":\"a\",\"\\u00E5\":\"a\",\"\\u01FB\":\"a\",\"\\u01CE\":\"a\",\"\\u0201\":\"a\",\"\\u0203\":\"a\",\"\\u1EA1\":\"a\",\"\\u1EAD\":\"a\",\"\\u1EB7\":\"a\",\"\\u1E01\":\"a\",\"\\u0105\":\"a\",\"\\u2C65\":\"a\",\"\\u0250\":\"a\",\"\\uA733\":\"aa\",\"\\u00E6\":\"ae\",\"\\u01FD\":\"ae\",\"\\u01E3\":\"ae\",\"\\uA735\":\"ao\",\"\\uA737\":\"au\",\"\\uA739\":\"av\",\"\\uA73B\":\"av\",\"\\uA73D\":\"ay\",\"\\u24D1\":\"b\",\"\\uFF42\":\"b\",\"\\u1E03\":\"b\",\"\\u1E05\":\"b\",\"\\u1E07\":\"b\",\"\\u0180\":\"b\",\"\\u0183\":\"b\",\"\\u0253\":\"b\",\"\\u24D2\":\"c\",\"\\uFF43\":\"c\",\"\\u0107\":\"c\",\"\\u0109\":\"c\",\"\\u010B\":\"c\",\"\\u010D\":\"c\",\"\\u00E7\":\"c\",\"\\u1E09\":\"c\",\"\\u0188\":\"c\",\"\\u023C\":\"c\",\"\\uA73F\":\"c\",\"\\u2184\":\"c\",\"\\u24D3\":\"d\",\"\\uFF44\":\"d\",\"\\u1E0B\":\"d\",\"\\u010F\":\"d\",\"\\u1E0D\":\"d\",\"\\u1E11\":\"d\",\"\\u1E13\":\"d\",\"\\u1E0F\":\"d\",\"\\u0111\":\"d\",\"\\u018C\":\"d\",\"\\u0256\":\"d\",\"\\u0257\":\"d\",\"\\uA77A\":\"d\",\"\\u01F3\":\"dz\",\"\\u01C6\":\"dz\",\"\\u24D4\":\"e\",\"\\uFF45\":\"e\",\"\\u00E8\":\"e\",\"\\u00E9\":\"e\",\"\\u00EA\":\"e\",\"\\u1EC1\":\"e\",\"\\u1EBF\":\"e\",\"\\u1EC5\":\"e\",\"\\u1EC3\":\"e\",\"\\u1EBD\":\"e\",\"\\u0113\":\"e\",\"\\u1E15\":\"e\",\"\\u1E17\":\"e\",\"\\u0115\":\"e\",\"\\u0117\":\"e\",\"\\u00EB\":\"e\",\"\\u1EBB\":\"e\",\"\\u011B\":\"e\",\"\\u0205\":\"e\",\"\\u0207\":\"e\",\"\\u1EB9\":\"e\",\"\\u1EC7\":\"e\",\"\\u0229\":\"e\",\"\\u1E1D\":\"e\",\"\\u0119\":\"e\",\"\\u1E19\":\"e\",\"\\u1E1B\":\"e\",\"\\u0247\":\"e\",\"\\u025B\":\"e\",\"\\u01DD\":\"e\",\"\\u24D5\":\"f\",\"\\uFF46\":\"f\",\"\\u1E1F\":\"f\",\"\\u0192\":\"f\",\"\\uA77C\":\"f\",\"\\u24D6\":\"g\",\"\\uFF47\":\"g\",\"\\u01F5\":\"g\",\"\\u011D\":\"g\",\"\\u1E21\":\"g\",\"\\u011F\":\"g\",\"\\u0121\":\"g\",\"\\u01E7\":\"g\",\"\\u0123\":\"g\",\"\\u01E5\":\"g\",\"\\u0260\":\"g\",\"\\uA7A1\":\"g\",\"\\u1D79\":\"g\",\"\\uA77F\":\"g\",\"\\u24D7\":\"h\",\"\\uFF48\":\"h\",\"\\u0125\":\"h\",\"\\u1E23\":\"h\",\"\\u1E27\":\"h\",\"\\u021F\":\"h\",\"\\u1E25\":\"h\",\"\\u1E29\":\"h\",\"\\u1E2B\":\"h\",\"\\u1E96\":\"h\",\"\\u0127\":\"h\",\"\\u2C68\":\"h\",\"\\u2C76\":\"h\",\"\\u0265\":\"h\",\"\\u0195\":\"hv\",\"\\u24D8\":\"i\",\"\\uFF49\":\"i\",\"\\u00EC\":\"i\",\"\\u00ED\":\"i\",\"\\u00EE\":\"i\",\"\\u0129\":\"i\",\"\\u012B\":\"i\",\"\\u012D\":\"i\",\"\\u00EF\":\"i\",\"\\u1E2F\":\"i\",\"\\u1EC9\":\"i\",\"\\u01D0\":\"i\",\"\\u0209\":\"i\",\"\\u020B\":\"i\",\"\\u1ECB\":\"i\",\"\\u012F\":\"i\",\"\\u1E2D\":\"i\",\"\\u0268\":\"i\",\"\\u0131\":\"i\",\"\\u24D9\":\"j\",\"\\uFF4A\":\"j\",\"\\u0135\":\"j\",\"\\u01F0\":\"j\",\"\\u0249\":\"j\",\"\\u24DA\":\"k\",\"\\uFF4B\":\"k\",\"\\u1E31\":\"k\",\"\\u01E9\":\"k\",\"\\u1E33\":\"k\",\"\\u0137\":\"k\",\"\\u1E35\":\"k\",\"\\u0199\":\"k\",\"\\u2C6A\":\"k\",\"\\uA741\":\"k\",\"\\uA743\":\"k\",\"\\uA745\":\"k\",\"\\uA7A3\":\"k\",\"\\u24DB\":\"l\",\"\\uFF4C\":\"l\",\"\\u0140\":\"l\",\"\\u013A\":\"l\",\"\\u013E\":\"l\",\"\\u1E37\":\"l\",\"\\u1E39\":\"l\",\"\\u013C\":\"l\",\"\\u1E3D\":\"l\",\"\\u1E3B\":\"l\",\"\\u017F\":\"l\",\"\\u0142\":\"l\",\"\\u019A\":\"l\",\"\\u026B\":\"l\",\"\\u2C61\":\"l\",\"\\uA749\":\"l\",\"\\uA781\":\"l\",\"\\uA747\":\"l\",\"\\u01C9\":\"lj\",\"\\u24DC\":\"m\",\"\\uFF4D\":\"m\",\"\\u1E3F\":\"m\",\"\\u1E41\":\"m\",\"\\u1E43\":\"m\",\"\\u0271\":\"m\",\"\\u026F\":\"m\",\"\\u24DD\":\"n\",\"\\uFF4E\":\"n\",\"\\u01F9\":\"n\",\"\\u0144\":\"n\",\"\\u00F1\":\"n\",\"\\u1E45\":\"n\",\"\\u0148\":\"n\",\"\\u1E47\":\"n\",\"\\u0146\":\"n\",\"\\u1E4B\":\"n\",\"\\u1E49\":\"n\",\"\\u019E\":\"n\",\"\\u0272\":\"n\",\"\\u0149\":\"n\",\"\\uA791\":\"n\",\"\\uA7A5\":\"n\",\"\\u01CC\":\"nj\",\"\\u24DE\":\"o\",\"\\uFF4F\":\"o\",\"\\u00F2\":\"o\",\"\\u00F3\":\"o\",\"\\u00F4\":\"o\",\"\\u1ED3\":\"o\",\"\\u1ED1\":\"o\",\"\\u1ED7\":\"o\",\"\\u1ED5\":\"o\",\"\\u00F5\":\"o\",\"\\u1E4D\":\"o\",\"\\u022D\":\"o\",\"\\u1E4F\":\"o\",\"\\u014D\":\"o\",\"\\u1E51\":\"o\",\"\\u1E53\":\"o\",\"\\u014F\":\"o\",\"\\u022F\":\"o\",\"\\u0231\":\"o\",\"\\u00F6\":\"o\",\"\\u022B\":\"o\",\"\\u1ECF\":\"o\",\"\\u0151\":\"o\",\"\\u01D2\":\"o\",\"\\u020D\":\"o\",\"\\u020F\":\"o\",\"\\u01A1\":\"o\",\"\\u1EDD\":\"o\",\"\\u1EDB\":\"o\",\"\\u1EE1\":\"o\",\"\\u1EDF\":\"o\",\"\\u1EE3\":\"o\",\"\\u1ECD\":\"o\",\"\\u1ED9\":\"o\",\"\\u01EB\":\"o\",\"\\u01ED\":\"o\",\"\\u00F8\":\"o\",\"\\u01FF\":\"o\",\"\\u0254\":\"o\",\"\\uA74B\":\"o\",\"\\uA74D\":\"o\",\"\\u0275\":\"o\",\"\\u01A3\":\"oi\",\"\\u0223\":\"ou\",\"\\uA74F\":\"oo\",\"\\u24DF\":\"p\",\"\\uFF50\":\"p\",\"\\u1E55\":\"p\",\"\\u1E57\":\"p\",\"\\u01A5\":\"p\",\"\\u1D7D\":\"p\",\"\\uA751\":\"p\",\"\\uA753\":\"p\",\"\\uA755\":\"p\",\"\\u24E0\":\"q\",\"\\uFF51\":\"q\",\"\\u024B\":\"q\",\"\\uA757\":\"q\",\"\\uA759\":\"q\",\"\\u24E1\":\"r\",\"\\uFF52\":\"r\",\"\\u0155\":\"r\",\"\\u1E59\":\"r\",\"\\u0159\":\"r\",\"\\u0211\":\"r\",\"\\u0213\":\"r\",\"\\u1E5B\":\"r\",\"\\u1E5D\":\"r\",\"\\u0157\":\"r\",\"\\u1E5F\":\"r\",\"\\u024D\":\"r\",\"\\u027D\":\"r\",\"\\uA75B\":\"r\",\"\\uA7A7\":\"r\",\"\\uA783\":\"r\",\"\\u24E2\":\"s\",\"\\uFF53\":\"s\",\"\\u00DF\":\"s\",\"\\u015B\":\"s\",\"\\u1E65\":\"s\",\"\\u015D\":\"s\",\"\\u1E61\":\"s\",\"\\u0161\":\"s\",\"\\u1E67\":\"s\",\"\\u1E63\":\"s\",\"\\u1E69\":\"s\",\"\\u0219\":\"s\",\"\\u015F\":\"s\",\"\\u023F\":\"s\",\"\\uA7A9\":\"s\",\"\\uA785\":\"s\",\"\\u1E9B\":\"s\",\"\\u24E3\":\"t\",\"\\uFF54\":\"t\",\"\\u1E6B\":\"t\",\"\\u1E97\":\"t\",\"\\u0165\":\"t\",\"\\u1E6D\":\"t\",\"\\u021B\":\"t\",\"\\u0163\":\"t\",\"\\u1E71\":\"t\",\"\\u1E6F\":\"t\",\"\\u0167\":\"t\",\"\\u01AD\":\"t\",\"\\u0288\":\"t\",\"\\u2C66\":\"t\",\"\\uA787\":\"t\",\"\\uA729\":\"tz\",\"\\u24E4\":\"u\",\"\\uFF55\":\"u\",\"\\u00F9\":\"u\",\"\\u00FA\":\"u\",\"\\u00FB\":\"u\",\"\\u0169\":\"u\",\"\\u1E79\":\"u\",\"\\u016B\":\"u\",\"\\u1E7B\":\"u\",\"\\u016D\":\"u\",\"\\u00FC\":\"u\",\"\\u01DC\":\"u\",\"\\u01D8\":\"u\",\"\\u01D6\":\"u\",\"\\u01DA\":\"u\",\"\\u1EE7\":\"u\",\"\\u016F\":\"u\",\"\\u0171\":\"u\",\"\\u01D4\":\"u\",\"\\u0215\":\"u\",\"\\u0217\":\"u\",\"\\u01B0\":\"u\",\"\\u1EEB\":\"u\",\"\\u1EE9\":\"u\",\"\\u1EEF\":\"u\",\"\\u1EED\":\"u\",\"\\u1EF1\":\"u\",\"\\u1EE5\":\"u\",\"\\u1E73\":\"u\",\"\\u0173\":\"u\",\"\\u1E77\":\"u\",\"\\u1E75\":\"u\",\"\\u0289\":\"u\",\"\\u24E5\":\"v\",\"\\uFF56\":\"v\",\"\\u1E7D\":\"v\",\"\\u1E7F\":\"v\",\"\\u028B\":\"v\",\"\\uA75F\":\"v\",\"\\u028C\":\"v\",\"\\uA761\":\"vy\",\"\\u24E6\":\"w\",\"\\uFF57\":\"w\",\"\\u1E81\":\"w\",\"\\u1E83\":\"w\",\"\\u0175\":\"w\",\"\\u1E87\":\"w\",\"\\u1E85\":\"w\",\"\\u1E98\":\"w\",\"\\u1E89\":\"w\",\"\\u2C73\":\"w\",\"\\u24E7\":\"x\",\"\\uFF58\":\"x\",\"\\u1E8B\":\"x\",\"\\u1E8D\":\"x\",\"\\u24E8\":\"y\",\"\\uFF59\":\"y\",\"\\u1EF3\":\"y\",\"\\u00FD\":\"y\",\"\\u0177\":\"y\",\"\\u1EF9\":\"y\",\"\\u0233\":\"y\",\"\\u1E8F\":\"y\",\"\\u00FF\":\"y\",\"\\u1EF7\":\"y\",\"\\u1E99\":\"y\",\"\\u1EF5\":\"y\",\"\\u01B4\":\"y\",\"\\u024F\":\"y\",\"\\u1EFF\":\"y\",\"\\u24E9\":\"z\",\"\\uFF5A\":\"z\",\"\\u017A\":\"z\",\"\\u1E91\":\"z\",\"\\u017C\":\"z\",\"\\u017E\":\"z\",\"\\u1E93\":\"z\",\"\\u1E95\":\"z\",\"\\u01B6\":\"z\",\"\\u0225\":\"z\",\"\\u0240\":\"z\",\"\\u2C6C\":\"z\",\"\\uA763\":\"z\",\"\\u0386\":\"\\u0391\",\"\\u0388\":\"\\u0395\",\"\\u0389\":\"\\u0397\",\"\\u038A\":\"\\u0399\",\"\\u03AA\":\"\\u0399\",\"\\u038C\":\"\\u039F\",\"\\u038E\":\"\\u03A5\",\"\\u03AB\":\"\\u03A5\",\"\\u038F\":\"\\u03A9\",\"\\u03AC\":\"\\u03B1\",\"\\u03AD\":\"\\u03B5\",\"\\u03AE\":\"\\u03B7\",\"\\u03AF\":\"\\u03B9\",\"\\u03CA\":\"\\u03B9\",\"\\u0390\":\"\\u03B9\",\"\\u03CC\":\"\\u03BF\",\"\\u03CD\":\"\\u03C5\",\"\\u03CB\":\"\\u03C5\",\"\\u03B0\":\"\\u03C5\",\"\\u03C9\":\"\\u03C9\",\"\\u03C2\":\"\\u03C3\"};\n\n    $document = $(document);\n\n    nextUid=(function() { var counter=1; return function() { return counter++; }; }());\n\n\n    function reinsertElement(element) {\n        var placeholder = $(document.createTextNode(''));\n\n        element.before(placeholder);\n        placeholder.before(element);\n        placeholder.remove();\n    }\n\n    function stripDiacritics(str) {\n        // Used 'uni range + named function' from http://jsperf.com/diacritics/18\n        function match(a) {\n            return DIACRITICS[a] || a;\n        }\n\n        return str.replace(/[^\\u0000-\\u007E]/g, match);\n    }\n\n    function indexOf(value, array) {\n        var i = 0, l = array.length;\n        for (; i < l; i = i + 1) {\n            if (equal(value, array[i])) return i;\n        }\n        return -1;\n    }\n\n    function measureScrollbar () {\n        var $template = $( MEASURE_SCROLLBAR_TEMPLATE );\n        $template.appendTo(document.body);\n\n        var dim = {\n            width: $template.width() - $template[0].clientWidth,\n            height: $template.height() - $template[0].clientHeight\n        };\n        $template.remove();\n\n        return dim;\n    }\n\n    /**\n     * Compares equality of a and b\n     * @param a\n     * @param b\n     */\n    function equal(a, b) {\n        if (a === b) return true;\n        if (a === undefined || b === undefined) return false;\n        if (a === null || b === null) return false;\n        // Check whether 'a' or 'b' is a string (primitive or object).\n        // The concatenation of an empty string (+'') converts its argument to a string's primitive.\n        if (a.constructor === String) return a+'' === b+''; // a+'' - in case 'a' is a String object\n        if (b.constructor === String) return b+'' === a+''; // b+'' - in case 'b' is a String object\n        return false;\n    }\n\n    /**\n     * Splits the string into an array of values, transforming each value. An empty array is returned for nulls or empty\n     * strings\n     * @param string\n     * @param separator\n     */\n    function splitVal(string, separator, transform) {\n        var val, i, l;\n        if (string === null || string.length < 1) return [];\n        val = string.split(separator);\n        for (i = 0, l = val.length; i < l; i = i + 1) val[i] = transform(val[i]);\n        return val;\n    }\n\n    function getSideBorderPadding(element) {\n        return element.outerWidth(false) - element.width();\n    }\n\n    function installKeyUpChangeEvent(element) {\n        var key=\"keyup-change-value\";\n        element.on(\"keydown\", function () {\n            if ($.data(element, key) === undefined) {\n                $.data(element, key, element.val());\n            }\n        });\n        element.on(\"keyup\", function () {\n            var val= $.data(element, key);\n            if (val !== undefined && element.val() !== val) {\n                $.removeData(element, key);\n                element.trigger(\"keyup-change\");\n            }\n        });\n    }\n\n\n    /**\n     * filters mouse events so an event is fired only if the mouse moved.\n     *\n     * filters out mouse events that occur when mouse is stationary but\n     * the elements under the pointer are scrolled.\n     */\n    function installFilteredMouseMove(element) {\n        element.on(\"mousemove\", function (e) {\n            var lastpos = lastMousePosition;\n            if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) {\n                $(e.target).trigger(\"mousemove-filtered\", e);\n            }\n        });\n    }\n\n    /**\n     * Debounces a function. Returns a function that calls the original fn function only if no invocations have been made\n     * within the last quietMillis milliseconds.\n     *\n     * @param quietMillis number of milliseconds to wait before invoking fn\n     * @param fn function to be debounced\n     * @param ctx object to be used as this reference within fn\n     * @return debounced version of fn\n     */\n    function debounce(quietMillis, fn, ctx) {\n        ctx = ctx || undefined;\n        var timeout;\n        return function () {\n            var args = arguments;\n            window.clearTimeout(timeout);\n            timeout = window.setTimeout(function() {\n                fn.apply(ctx, args);\n            }, quietMillis);\n        };\n    }\n\n    function installDebouncedScroll(threshold, element) {\n        var notify = debounce(threshold, function (e) { element.trigger(\"scroll-debounced\", e);});\n        element.on(\"scroll\", function (e) {\n            if (indexOf(e.target, element.get()) >= 0) notify(e);\n        });\n    }\n\n    function focus($el) {\n        if ($el[0] === document.activeElement) return;\n\n        /* set the focus in a 0 timeout - that way the focus is set after the processing\n            of the current event has finished - which seems like the only reliable way\n            to set focus */\n        window.setTimeout(function() {\n            var el=$el[0], pos=$el.val().length, range;\n\n            $el.focus();\n\n            /* make sure el received focus so we do not error out when trying to manipulate the caret.\n                sometimes modals or others listeners may steal it after its set */\n            var isVisible = (el.offsetWidth > 0 || el.offsetHeight > 0);\n            if (isVisible && el === document.activeElement) {\n\n                /* after the focus is set move the caret to the end, necessary when we val()\n                    just before setting focus */\n                if(el.setSelectionRange)\n                {\n                    el.setSelectionRange(pos, pos);\n                }\n                else if (el.createTextRange) {\n                    range = el.createTextRange();\n                    range.collapse(false);\n                    range.select();\n                }\n            }\n        }, 0);\n    }\n\n    function getCursorInfo(el) {\n        el = $(el)[0];\n        var offset = 0;\n        var length = 0;\n        if ('selectionStart' in el) {\n            offset = el.selectionStart;\n            length = el.selectionEnd - offset;\n        } else if ('selection' in document) {\n            el.focus();\n            var sel = document.selection.createRange();\n            length = document.selection.createRange().text.length;\n            sel.moveStart('character', -el.value.length);\n            offset = sel.text.length - length;\n        }\n        return { offset: offset, length: length };\n    }\n\n    function killEvent(event) {\n        event.preventDefault();\n        event.stopPropagation();\n    }\n    function killEventImmediately(event) {\n        event.preventDefault();\n        event.stopImmediatePropagation();\n    }\n\n    function measureTextWidth(e) {\n        if (!sizer){\n            var style = e[0].currentStyle || window.getComputedStyle(e[0], null);\n            sizer = $(document.createElement(\"div\")).css({\n                position: \"absolute\",\n                left: \"-10000px\",\n                top: \"-10000px\",\n                display: \"none\",\n                fontSize: style.fontSize,\n                fontFamily: style.fontFamily,\n                fontStyle: style.fontStyle,\n                fontWeight: style.fontWeight,\n                letterSpacing: style.letterSpacing,\n                textTransform: style.textTransform,\n                whiteSpace: \"nowrap\"\n            });\n            sizer.attr(\"class\",\"select2-sizer\");\n            $(document.body).append(sizer);\n        }\n        sizer.text(e.val());\n        return sizer.width();\n    }\n\n    function syncCssClasses(dest, src, adapter) {\n        var classes, replacements = [], adapted;\n\n        classes = $.trim(dest.attr(\"class\"));\n\n        if (classes) {\n            classes = '' + classes; // for IE which returns object\n\n            $(classes.split(/\\s+/)).each2(function() {\n                if (this.indexOf(\"select2-\") === 0) {\n                    replacements.push(this);\n                }\n            });\n        }\n\n        classes = $.trim(src.attr(\"class\"));\n\n        if (classes) {\n            classes = '' + classes; // for IE which returns object\n\n            $(classes.split(/\\s+/)).each2(function() {\n                if (this.indexOf(\"select2-\") !== 0) {\n                    adapted = adapter(this);\n\n                    if (adapted) {\n                        replacements.push(adapted);\n                    }\n                }\n            });\n        }\n\n        dest.attr(\"class\", replacements.join(\" \"));\n    }\n\n\n    function markMatch(text, term, markup, escapeMarkup) {\n        var match=stripDiacritics(text.toUpperCase()).indexOf(stripDiacritics(term.toUpperCase())),\n            tl=term.length;\n\n        if (match<0) {\n            markup.push(escapeMarkup(text));\n            return;\n        }\n\n        markup.push(escapeMarkup(text.substring(0, match)));\n        markup.push(\"<span class='select2-match'>\");\n        markup.push(escapeMarkup(text.substring(match, match + tl)));\n        markup.push(\"</span>\");\n        markup.push(escapeMarkup(text.substring(match + tl, text.length)));\n    }\n\n    function defaultEscapeMarkup(markup) {\n        var replace_map = {\n            '\\\\': '&#92;',\n            '&': '&amp;',\n            '<': '&lt;',\n            '>': '&gt;',\n            '\"': '&quot;',\n            \"'\": '&#39;',\n            \"/\": '&#47;'\n        };\n\n        return String(markup).replace(/[&<>\"'\\/\\\\]/g, function (match) {\n            return replace_map[match];\n        });\n    }\n\n    /**\n     * Produces an ajax-based query function\n     *\n     * @param options object containing configuration parameters\n     * @param options.params parameter map for the transport ajax call, can contain such options as cache, jsonpCallback, etc. see $.ajax\n     * @param options.transport function that will be used to execute the ajax request. must be compatible with parameters supported by $.ajax\n     * @param options.url url for the data\n     * @param options.data a function(searchTerm, pageNumber, context) that should return an object containing query string parameters for the above url.\n     * @param options.dataType request data type: ajax, jsonp, other datatypes supported by jQuery's $.ajax function or the transport function if specified\n     * @param options.quietMillis (optional) milliseconds to wait before making the ajaxRequest, helps debounce the ajax function if invoked too often\n     * @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2.\n     *      The expected format is an object containing the following keys:\n     *      results array of objects that will be used as choices\n     *      more (optional) boolean indicating whether there are more results available\n     *      Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}\n     */\n    function ajax(options) {\n        var timeout, // current scheduled but not yet executed request\n            handler = null,\n            quietMillis = options.quietMillis || 100,\n            ajaxUrl = options.url,\n            self = this;\n\n        return function (query) {\n            window.clearTimeout(timeout);\n            timeout = window.setTimeout(function () {\n                var data = options.data, // ajax data function\n                    url = ajaxUrl, // ajax url string or function\n                    transport = options.transport || $.fn.select2.ajaxDefaults.transport,\n                    // deprecated - to be removed in 4.0  - use params instead\n                    deprecated = {\n                        type: options.type || 'GET', // set type of request (GET or POST)\n                        cache: options.cache || false,\n                        jsonpCallback: options.jsonpCallback||undefined,\n                        dataType: options.dataType||\"json\"\n                    },\n                    params = $.extend({}, $.fn.select2.ajaxDefaults.params, deprecated);\n\n                data = data ? data.call(self, query.term, query.page, query.context) : null;\n                url = (typeof url === 'function') ? url.call(self, query.term, query.page, query.context) : url;\n\n                if (handler && typeof handler.abort === \"function\") { handler.abort(); }\n\n                if (options.params) {\n                    if ($.isFunction(options.params)) {\n                        $.extend(params, options.params.call(self));\n                    } else {\n                        $.extend(params, options.params);\n                    }\n                }\n\n                $.extend(params, {\n                    url: url,\n                    dataType: options.dataType,\n                    data: data,\n                    success: function (data) {\n                        // TODO - replace query.page with query so users have access to term, page, etc.\n                        // added query as third paramter to keep backwards compatibility\n                        var results = options.results(data, query.page, query);\n                        query.callback(results);\n                    },\n                    error: function(jqXHR, textStatus, errorThrown){\n                        var results = {\n                            hasError: true,\n                            jqXHR: jqXHR,\n                            textStatus: textStatus,\n                            errorThrown: errorThrown\n                        };\n\n                        query.callback(results);\n                    }\n                });\n                handler = transport.call(self, params);\n            }, quietMillis);\n        };\n    }\n\n    /**\n     * Produces a query function that works with a local array\n     *\n     * @param options object containing configuration parameters. The options parameter can either be an array or an\n     * object.\n     *\n     * If the array form is used it is assumed that it contains objects with 'id' and 'text' keys.\n     *\n     * If the object form is used it is assumed that it contains 'data' and 'text' keys. The 'data' key should contain\n     * an array of objects that will be used as choices. These objects must contain at least an 'id' key. The 'text'\n     * key can either be a String in which case it is expected that each element in the 'data' array has a key with the\n     * value of 'text' which will be used to match choices. Alternatively, text can be a function(item) that can extract\n     * the text.\n     */\n    function local(options) {\n        var data = options, // data elements\n            dataText,\n            tmp,\n            text = function (item) { return \"\"+item.text; }; // function used to retrieve the text portion of a data item that is matched against the search\n\n         if ($.isArray(data)) {\n            tmp = data;\n            data = { results: tmp };\n        }\n\n         if ($.isFunction(data) === false) {\n            tmp = data;\n            data = function() { return tmp; };\n        }\n\n        var dataItem = data();\n        if (dataItem.text) {\n            text = dataItem.text;\n            // if text is not a function we assume it to be a key name\n            if (!$.isFunction(text)) {\n                dataText = dataItem.text; // we need to store this in a separate variable because in the next step data gets reset and data.text is no longer available\n                text = function (item) { return item[dataText]; };\n            }\n        }\n\n        return function (query) {\n            var t = query.term, filtered = { results: [] }, process;\n            if (t === \"\") {\n                query.callback(data());\n                return;\n            }\n\n            process = function(datum, collection) {\n                var group, attr;\n                datum = datum[0];\n                if (datum.children) {\n                    group = {};\n                    for (attr in datum) {\n                        if (datum.hasOwnProperty(attr)) group[attr]=datum[attr];\n                    }\n                    group.children=[];\n                    $(datum.children).each2(function(i, childDatum) { process(childDatum, group.children); });\n                    if (group.children.length || query.matcher(t, text(group), datum)) {\n                        collection.push(group);\n                    }\n                } else {\n                    if (query.matcher(t, text(datum), datum)) {\n                        collection.push(datum);\n                    }\n                }\n            };\n\n            $(data().results).each2(function(i, datum) { process(datum, filtered.results); });\n            query.callback(filtered);\n        };\n    }\n\n    // TODO javadoc\n    function tags(data) {\n        var isFunc = $.isFunction(data);\n        return function (query) {\n            var t = query.term, filtered = {results: []};\n            var result = isFunc ? data(query) : data;\n            if ($.isArray(result)) {\n                $(result).each(function () {\n                    var isObject = this.text !== undefined,\n                        text = isObject ? this.text : this;\n                    if (t === \"\" || query.matcher(t, text)) {\n                        filtered.results.push(isObject ? this : {id: this, text: this});\n                    }\n                });\n                query.callback(filtered);\n            }\n        };\n    }\n\n    /**\n     * Checks if the formatter function should be used.\n     *\n     * Throws an error if it is not a function. Returns true if it should be used,\n     * false if no formatting should be performed.\n     *\n     * @param formatter\n     */\n    function checkFormatter(formatter, formatterName) {\n        if ($.isFunction(formatter)) return true;\n        if (!formatter) return false;\n        if (typeof(formatter) === 'string') return true;\n        throw new Error(formatterName +\" must be a string, function, or falsy value\");\n    }\n\n  /**\n   * Returns a given value\n   * If given a function, returns its output\n   *\n   * @param val string|function\n   * @param context value of \"this\" to be passed to function\n   * @returns {*}\n   */\n    function evaluate(val, context) {\n        if ($.isFunction(val)) {\n            var args = Array.prototype.slice.call(arguments, 2);\n            return val.apply(context, args);\n        }\n        return val;\n    }\n\n    function countResults(results) {\n        var count = 0;\n        $.each(results, function(i, item) {\n            if (item.children) {\n                count += countResults(item.children);\n            } else {\n                count++;\n            }\n        });\n        return count;\n    }\n\n    /**\n     * Default tokenizer. This function uses breaks the input on substring match of any string from the\n     * opts.tokenSeparators array and uses opts.createSearchChoice to create the choice object. Both of those\n     * two options have to be defined in order for the tokenizer to work.\n     *\n     * @param input text user has typed so far or pasted into the search field\n     * @param selection currently selected choices\n     * @param selectCallback function(choice) callback tho add the choice to selection\n     * @param opts select2's opts\n     * @return undefined/null to leave the current input unchanged, or a string to change the input to the returned value\n     */\n    function defaultTokenizer(input, selection, selectCallback, opts) {\n        var original = input, // store the original so we can compare and know if we need to tell the search to update its text\n            dupe = false, // check for whether a token we extracted represents a duplicate selected choice\n            token, // token\n            index, // position at which the separator was found\n            i, l, // looping variables\n            separator; // the matched separator\n\n        if (!opts.createSearchChoice || !opts.tokenSeparators || opts.tokenSeparators.length < 1) return undefined;\n\n        while (true) {\n            index = -1;\n\n            for (i = 0, l = opts.tokenSeparators.length; i < l; i++) {\n                separator = opts.tokenSeparators[i];\n                index = input.indexOf(separator);\n                if (index >= 0) break;\n            }\n\n            if (index < 0) break; // did not find any token separator in the input string, bail\n\n            token = input.substring(0, index);\n            input = input.substring(index + separator.length);\n\n            if (token.length > 0) {\n                token = opts.createSearchChoice.call(this, token, selection);\n                if (token !== undefined && token !== null && opts.id(token) !== undefined && opts.id(token) !== null) {\n                    dupe = false;\n                    for (i = 0, l = selection.length; i < l; i++) {\n                        if (equal(opts.id(token), opts.id(selection[i]))) {\n                            dupe = true; break;\n                        }\n                    }\n\n                    if (!dupe) selectCallback(token);\n                }\n            }\n        }\n\n        if (original!==input) return input;\n    }\n\n    function cleanupJQueryElements() {\n        var self = this;\n\n        $.each(arguments, function (i, element) {\n            self[element].remove();\n            self[element] = null;\n        });\n    }\n\n    /**\n     * Creates a new class\n     *\n     * @param superClass\n     * @param methods\n     */\n    function clazz(SuperClass, methods) {\n        var constructor = function () {};\n        constructor.prototype = new SuperClass;\n        constructor.prototype.constructor = constructor;\n        constructor.prototype.parent = SuperClass.prototype;\n        constructor.prototype = $.extend(constructor.prototype, methods);\n        return constructor;\n    }\n\n    AbstractSelect2 = clazz(Object, {\n\n        // abstract\n        bind: function (func) {\n            var self = this;\n            return function () {\n                func.apply(self, arguments);\n            };\n        },\n\n        // abstract\n        init: function (opts) {\n            var results, search, resultsSelector = \".select2-results\";\n\n            // prepare options\n            this.opts = opts = this.prepareOpts(opts);\n\n            this.id=opts.id;\n\n            // destroy if called on an existing component\n            if (opts.element.data(\"select2\") !== undefined &&\n                opts.element.data(\"select2\") !== null) {\n                opts.element.data(\"select2\").destroy();\n            }\n\n            this.container = this.createContainer();\n\n            this.liveRegion = $('.select2-hidden-accessible');\n            if (this.liveRegion.length == 0) {\n                this.liveRegion = $(\"<span>\", {\n                        role: \"status\",\n                        \"aria-live\": \"polite\"\n                    })\n                    .addClass(\"select2-hidden-accessible\")\n                    .appendTo(document.body);\n            }\n\n            this.containerId=\"s2id_\"+(opts.element.attr(\"id\") || \"autogen\"+nextUid());\n            this.containerEventName= this.containerId\n                .replace(/([.])/g, '_')\n                .replace(/([;&,\\-\\.\\+\\*\\~':\"\\!\\^#$%@\\[\\]\\(\\)=>\\|])/g, '\\\\$1');\n            this.container.attr(\"id\", this.containerId);\n\n            this.container.attr(\"title\", opts.element.attr(\"title\"));\n\n            this.body = $(document.body);\n\n            syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);\n\n            this.container.attr(\"style\", opts.element.attr(\"style\"));\n            this.container.css(evaluate(opts.containerCss, this.opts.element));\n            this.container.addClass(evaluate(opts.containerCssClass, this.opts.element));\n\n            this.elementTabIndex = this.opts.element.attr(\"tabindex\");\n\n            // swap container for the element\n            this.opts.element\n                .data(\"select2\", this)\n                .attr(\"tabindex\", \"-1\")\n                .before(this.container)\n                .on(\"click.select2\", killEvent); // do not leak click events\n\n            this.container.data(\"select2\", this);\n\n            this.dropdown = this.container.find(\".select2-drop\");\n\n            syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);\n\n            this.dropdown.addClass(evaluate(opts.dropdownCssClass, this.opts.element));\n            this.dropdown.data(\"select2\", this);\n            this.dropdown.on(\"click\", killEvent);\n\n            this.results = results = this.container.find(resultsSelector);\n            this.search = search = this.container.find(\"input.select2-input\");\n\n            this.queryCount = 0;\n            this.resultsPage = 0;\n            this.context = null;\n\n            // initialize the container\n            this.initContainer();\n\n            this.container.on(\"click\", killEvent);\n\n            installFilteredMouseMove(this.results);\n\n            this.dropdown.on(\"mousemove-filtered\", resultsSelector, this.bind(this.highlightUnderEvent));\n            this.dropdown.on(\"touchstart touchmove touchend\", resultsSelector, this.bind(function (event) {\n                this._touchEvent = true;\n                this.highlightUnderEvent(event);\n            }));\n            this.dropdown.on(\"touchmove\", resultsSelector, this.bind(this.touchMoved));\n            this.dropdown.on(\"touchstart touchend\", resultsSelector, this.bind(this.clearTouchMoved));\n\n            // Waiting for a click event on touch devices to select option and hide dropdown\n            // otherwise click will be triggered on an underlying element\n            this.dropdown.on('click', this.bind(function (event) {\n                if (this._touchEvent) {\n                    this._touchEvent = false;\n                    this.selectHighlighted();\n                }\n            }));\n\n            installDebouncedScroll(80, this.results);\n            this.dropdown.on(\"scroll-debounced\", resultsSelector, this.bind(this.loadMoreIfNeeded));\n\n            // do not propagate change event from the search field out of the component\n            $(this.container).on(\"change\", \".select2-input\", function(e) {e.stopPropagation();});\n            $(this.dropdown).on(\"change\", \".select2-input\", function(e) {e.stopPropagation();});\n\n            // if jquery.mousewheel plugin is installed we can prevent out-of-bounds scrolling of results via mousewheel\n            if ($.fn.mousewheel) {\n                results.mousewheel(function (e, delta, deltaX, deltaY) {\n                    var top = results.scrollTop();\n                    if (deltaY > 0 && top - deltaY <= 0) {\n                        results.scrollTop(0);\n                        killEvent(e);\n                    } else if (deltaY < 0 && results.get(0).scrollHeight - results.scrollTop() + deltaY <= results.height()) {\n                        results.scrollTop(results.get(0).scrollHeight - results.height());\n                        killEvent(e);\n                    }\n                });\n            }\n\n            installKeyUpChangeEvent(search);\n            search.on(\"keyup-change input paste\", this.bind(this.updateResults));\n            search.on(\"focus\", function () { search.addClass(\"select2-focused\"); });\n            search.on(\"blur\", function () { search.removeClass(\"select2-focused\");});\n\n            this.dropdown.on(\"mouseup\", resultsSelector, this.bind(function (e) {\n                if ($(e.target).closest(\".select2-result-selectable\").length > 0) {\n                    this.highlightUnderEvent(e);\n                    this.selectHighlighted(e);\n                }\n            }));\n\n            // trap all mouse events from leaving the dropdown. sometimes there may be a modal that is listening\n            // for mouse events outside of itself so it can close itself. since the dropdown is now outside the select2's\n            // dom it will trigger the popup close, which is not what we want\n            // focusin can cause focus wars between modals and select2 since the dropdown is outside the modal.\n            this.dropdown.on(\"click mouseup mousedown touchstart touchend focusin\", function (e) { e.stopPropagation(); });\n\n            this.nextSearchTerm = undefined;\n\n            if ($.isFunction(this.opts.initSelection)) {\n                // initialize selection based on the current value of the source element\n                this.initSelection();\n\n                // if the user has provided a function that can set selection based on the value of the source element\n                // we monitor the change event on the element and trigger it, allowing for two way synchronization\n                this.monitorSource();\n            }\n\n            if (opts.maximumInputLength !== null) {\n                this.search.attr(\"maxlength\", opts.maximumInputLength);\n            }\n\n            var disabled = opts.element.prop(\"disabled\");\n            if (disabled === undefined) disabled = false;\n            this.enable(!disabled);\n\n            var readonly = opts.element.prop(\"readonly\");\n            if (readonly === undefined) readonly = false;\n            this.readonly(readonly);\n\n            // Calculate size of scrollbar\n            scrollBarDimensions = scrollBarDimensions || measureScrollbar();\n\n            this.autofocus = opts.element.prop(\"autofocus\");\n            opts.element.prop(\"autofocus\", false);\n            if (this.autofocus) this.focus();\n\n            this.search.attr(\"placeholder\", opts.searchInputPlaceholder);\n        },\n\n        // abstract\n        destroy: function () {\n            var element=this.opts.element, select2 = element.data(\"select2\"), self = this;\n\n            this.close();\n\n            if (element.length && element[0].detachEvent && self._sync) {\n                element.each(function () {\n                    if (self._sync) {\n                        this.detachEvent(\"onpropertychange\", self._sync);\n                    }\n                });\n            }\n            if (this.propertyObserver) {\n                this.propertyObserver.disconnect();\n                this.propertyObserver = null;\n            }\n            this._sync = null;\n\n            if (select2 !== undefined) {\n                select2.container.remove();\n                select2.liveRegion.remove();\n                select2.dropdown.remove();\n                element\n                    .show()\n                    .removeData(\"select2\")\n                    .off(\".select2\")\n                    .prop(\"autofocus\", this.autofocus || false);\n                if (this.elementTabIndex) {\n                    element.attr({tabindex: this.elementTabIndex});\n                } else {\n                    element.removeAttr(\"tabindex\");\n                }\n                element.show();\n            }\n\n            cleanupJQueryElements.call(this,\n                \"container\",\n                \"liveRegion\",\n                \"dropdown\",\n                \"results\",\n                \"search\"\n            );\n        },\n\n        // abstract\n        optionToData: function(element) {\n            if (element.is(\"option\")) {\n                return {\n                    id:element.prop(\"value\"),\n                    text:element.text(),\n                    element: element.get(),\n                    css: element.attr(\"class\"),\n                    disabled: element.prop(\"disabled\"),\n                    locked: equal(element.attr(\"locked\"), \"locked\") || equal(element.data(\"locked\"), true)\n                };\n            } else if (element.is(\"optgroup\")) {\n                return {\n                    text:element.attr(\"label\"),\n                    children:[],\n                    element: element.get(),\n                    css: element.attr(\"class\")\n                };\n            }\n        },\n\n        // abstract\n        prepareOpts: function (opts) {\n            var element, select, idKey, ajaxUrl, self = this;\n\n            element = opts.element;\n\n            if (element.get(0).tagName.toLowerCase() === \"select\") {\n                this.select = select = opts.element;\n            }\n\n            if (select) {\n                // these options are not allowed when attached to a select because they are picked up off the element itself\n                $.each([\"id\", \"multiple\", \"ajax\", \"query\", \"createSearchChoice\", \"initSelection\", \"data\", \"tags\"], function () {\n                    if (this in opts) {\n                        throw new Error(\"Option '\" + this + \"' is not allowed for Select2 when attached to a <select> element.\");\n                    }\n                });\n            }\n\n            opts = $.extend({}, {\n                populateResults: function(container, results, query) {\n                    var populate, id=this.opts.id, liveRegion=this.liveRegion;\n\n                    populate=function(results, container, depth) {\n\n                        var i, l, result, selectable, disabled, compound, node, label, innerContainer, formatted;\n\n                        results = opts.sortResults(results, container, query);\n\n                        // collect the created nodes for bulk append\n                        var nodes = [];\n                        for (i = 0, l = results.length; i < l; i = i + 1) {\n\n                            result=results[i];\n\n                            disabled = (result.disabled === true);\n                            selectable = (!disabled) && (id(result) !== undefined);\n\n                            compound=result.children && result.children.length > 0;\n\n                            node=$(\"<li></li>\");\n                            node.addClass(\"select2-results-dept-\"+depth);\n                            node.addClass(\"select2-result\");\n                            node.addClass(selectable ? \"select2-result-selectable\" : \"select2-result-unselectable\");\n                            if (disabled) { node.addClass(\"select2-disabled\"); }\n                            if (compound) { node.addClass(\"select2-result-with-children\"); }\n                            node.addClass(self.opts.formatResultCssClass(result));\n                            node.attr(\"role\", \"presentation\");\n\n                            label=$(document.createElement(\"div\"));\n                            label.addClass(\"select2-result-label\");\n                            label.attr(\"id\", \"select2-result-label-\" + nextUid());\n                            label.attr(\"role\", \"option\");\n\n                            formatted=opts.formatResult(result, label, query, self.opts.escapeMarkup);\n                            if (formatted!==undefined) {\n                                label.html(formatted);\n                                node.append(label);\n                            }\n\n\n                            if (compound) {\n\n                                innerContainer=$(\"<ul></ul>\");\n                                innerContainer.addClass(\"select2-result-sub\");\n                                populate(result.children, innerContainer, depth+1);\n                                node.append(innerContainer);\n                            }\n\n                            node.data(\"select2-data\", result);\n                            nodes.push(node[0]);\n                        }\n\n                        // bulk append the created nodes\n                        container.append(nodes);\n                        liveRegion.text(opts.formatMatches(results.length));\n                    };\n\n                    populate(results, container, 0);\n                }\n            }, $.fn.select2.defaults, opts);\n\n            if (typeof(opts.id) !== \"function\") {\n                idKey = opts.id;\n                opts.id = function (e) { return e[idKey]; };\n            }\n\n            if ($.isArray(opts.element.data(\"select2Tags\"))) {\n                if (\"tags\" in opts) {\n                    throw \"tags specified as both an attribute 'data-select2-tags' and in options of Select2 \" + opts.element.attr(\"id\");\n                }\n                opts.tags=opts.element.data(\"select2Tags\");\n            }\n\n            if (select) {\n                opts.query = this.bind(function (query) {\n                    var data = { results: [], more: false },\n                        term = query.term,\n                        children, placeholderOption, process;\n\n                    process=function(element, collection) {\n                        var group;\n                        if (element.is(\"option\")) {\n                            if (query.matcher(term, element.text(), element)) {\n                                collection.push(self.optionToData(element));\n                            }\n                        } else if (element.is(\"optgroup\")) {\n                            group=self.optionToData(element);\n                            element.children().each2(function(i, elm) { process(elm, group.children); });\n                            if (group.children.length>0) {\n                                collection.push(group);\n                            }\n                        }\n                    };\n\n                    children=element.children();\n\n                    // ignore the placeholder option if there is one\n                    if (this.getPlaceholder() !== undefined && children.length > 0) {\n                        placeholderOption = this.getPlaceholderOption();\n                        if (placeholderOption) {\n                            children=children.not(placeholderOption);\n                        }\n                    }\n\n                    children.each2(function(i, elm) { process(elm, data.results); });\n\n                    query.callback(data);\n                });\n                // this is needed because inside val() we construct choices from options and their id is hardcoded\n                opts.id=function(e) { return e.id; };\n            } else {\n                if (!(\"query\" in opts)) {\n\n                    if (\"ajax\" in opts) {\n                        ajaxUrl = opts.element.data(\"ajax-url\");\n                        if (ajaxUrl && ajaxUrl.length > 0) {\n                            opts.ajax.url = ajaxUrl;\n                        }\n                        opts.query = ajax.call(opts.element, opts.ajax);\n                    } else if (\"data\" in opts) {\n                        opts.query = local(opts.data);\n                    } else if (\"tags\" in opts) {\n                        opts.query = tags(opts.tags);\n                        if (opts.createSearchChoice === undefined) {\n                            opts.createSearchChoice = function (term) { return {id: $.trim(term), text: $.trim(term)}; };\n                        }\n                        if (opts.initSelection === undefined) {\n                            opts.initSelection = function (element, callback) {\n                                var data = [];\n                                $(splitVal(element.val(), opts.separator, opts.transformVal)).each(function () {\n                                    var obj = { id: this, text: this },\n                                        tags = opts.tags;\n                                    if ($.isFunction(tags)) tags=tags();\n                                    $(tags).each(function() { if (equal(this.id, obj.id)) { obj = this; return false; } });\n                                    data.push(obj);\n                                });\n\n                                callback(data);\n                            };\n                        }\n                    }\n                }\n            }\n            if (typeof(opts.query) !== \"function\") {\n                throw \"query function not defined for Select2 \" + opts.element.attr(\"id\");\n            }\n\n            if (opts.createSearchChoicePosition === 'top') {\n                opts.createSearchChoicePosition = function(list, item) { list.unshift(item); };\n            }\n            else if (opts.createSearchChoicePosition === 'bottom') {\n                opts.createSearchChoicePosition = function(list, item) { list.push(item); };\n            }\n            else if (typeof(opts.createSearchChoicePosition) !== \"function\")  {\n                throw \"invalid createSearchChoicePosition option must be 'top', 'bottom' or a custom function\";\n            }\n\n            return opts;\n        },\n\n        /**\n         * Monitor the original element for changes and update select2 accordingly\n         */\n        // abstract\n        monitorSource: function () {\n            var el = this.opts.element, observer, self = this;\n\n            el.on(\"change.select2\", this.bind(function (e) {\n                if (this.opts.element.data(\"select2-change-triggered\") !== true) {\n                    this.initSelection();\n                }\n            }));\n\n            this._sync = this.bind(function () {\n\n                // sync enabled state\n                var disabled = el.prop(\"disabled\");\n                if (disabled === undefined) disabled = false;\n                this.enable(!disabled);\n\n                var readonly = el.prop(\"readonly\");\n                if (readonly === undefined) readonly = false;\n                this.readonly(readonly);\n\n                if (this.container) {\n                    syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);\n                    this.container.addClass(evaluate(this.opts.containerCssClass, this.opts.element));\n                }\n\n                if (this.dropdown) {\n                    syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);\n                    this.dropdown.addClass(evaluate(this.opts.dropdownCssClass, this.opts.element));\n                }\n\n            });\n\n            // IE8-10 (IE9/10 won't fire propertyChange via attachEventListener)\n            if (el.length && el[0].attachEvent) {\n                el.each(function() {\n                    this.attachEvent(\"onpropertychange\", self._sync);\n                });\n            }\n\n            // safari, chrome, firefox, IE11\n            observer = window.MutationObserver || window.WebKitMutationObserver|| window.MozMutationObserver;\n            if (observer !== undefined) {\n                if (this.propertyObserver) { delete this.propertyObserver; this.propertyObserver = null; }\n                this.propertyObserver = new observer(function (mutations) {\n                    $.each(mutations, self._sync);\n                });\n                this.propertyObserver.observe(el.get(0), { attributes:true, subtree:false });\n            }\n        },\n\n        // abstract\n        triggerSelect: function(data) {\n            var evt = $.Event(\"select2-selecting\", { val: this.id(data), object: data, choice: data });\n            this.opts.element.trigger(evt);\n            return !evt.isDefaultPrevented();\n        },\n\n        /**\n         * Triggers the change event on the source element\n         */\n        // abstract\n        triggerChange: function (details) {\n\n            details = details || {};\n            details= $.extend({}, details, { type: \"change\", val: this.val() });\n            // prevents recursive triggering\n            this.opts.element.data(\"select2-change-triggered\", true);\n            this.opts.element.trigger(details);\n            this.opts.element.data(\"select2-change-triggered\", false);\n\n            // some validation frameworks ignore the change event and listen instead to keyup, click for selects\n            // so here we trigger the click event manually\n            this.opts.element.click();\n\n            // ValidationEngine ignores the change event and listens instead to blur\n            // so here we trigger the blur event manually if so desired\n            if (this.opts.blurOnChange)\n                this.opts.element.blur();\n        },\n\n        //abstract\n        isInterfaceEnabled: function()\n        {\n            return this.enabledInterface === true;\n        },\n\n        // abstract\n        enableInterface: function() {\n            var enabled = this._enabled && !this._readonly,\n                disabled = !enabled;\n\n            if (enabled === this.enabledInterface) return false;\n\n            this.container.toggleClass(\"select2-container-disabled\", disabled);\n            this.close();\n            this.enabledInterface = enabled;\n\n            return true;\n        },\n\n        // abstract\n        enable: function(enabled) {\n            if (enabled === undefined) enabled = true;\n            if (this._enabled === enabled) return;\n            this._enabled = enabled;\n\n            this.opts.element.prop(\"disabled\", !enabled);\n            this.enableInterface();\n        },\n\n        // abstract\n        disable: function() {\n            this.enable(false);\n        },\n\n        // abstract\n        readonly: function(enabled) {\n            if (enabled === undefined) enabled = false;\n            if (this._readonly === enabled) return;\n            this._readonly = enabled;\n\n            this.opts.element.prop(\"readonly\", enabled);\n            this.enableInterface();\n        },\n\n        // abstract\n        opened: function () {\n            return (this.container) ? this.container.hasClass(\"select2-dropdown-open\") : false;\n        },\n\n        // abstract\n        positionDropdown: function() {\n            var $dropdown = this.dropdown,\n                container = this.container,\n                offset = container.offset(),\n                height = container.outerHeight(false),\n                width = container.outerWidth(false),\n                dropHeight = $dropdown.outerHeight(false),\n                $window = $(window),\n                windowWidth = $window.width(),\n                windowHeight = $window.height(),\n                viewPortRight = $window.scrollLeft() + windowWidth,\n                viewportBottom = $window.scrollTop() + windowHeight,\n                dropTop = offset.top + height,\n                dropLeft = offset.left,\n                enoughRoomBelow = dropTop + dropHeight <= viewportBottom,\n                enoughRoomAbove = (offset.top - dropHeight) >= $window.scrollTop(),\n                dropWidth = $dropdown.outerWidth(false),\n                enoughRoomOnRight = function() {\n                    return dropLeft + dropWidth <= viewPortRight;\n                },\n                enoughRoomOnLeft = function() {\n                    return offset.left + viewPortRight + container.outerWidth(false)  > dropWidth;\n                },\n                aboveNow = $dropdown.hasClass(\"select2-drop-above\"),\n                bodyOffset,\n                above,\n                changeDirection,\n                css,\n                resultsListNode;\n\n            // always prefer the current above/below alignment, unless there is not enough room\n            if (aboveNow) {\n                above = true;\n                if (!enoughRoomAbove && enoughRoomBelow) {\n                    changeDirection = true;\n                    above = false;\n                }\n            } else {\n                above = false;\n                if (!enoughRoomBelow && enoughRoomAbove) {\n                    changeDirection = true;\n                    above = true;\n                }\n            }\n\n            //if we are changing direction we need to get positions when dropdown is hidden;\n            if (changeDirection) {\n                $dropdown.hide();\n                offset = this.container.offset();\n                height = this.container.outerHeight(false);\n                width = this.container.outerWidth(false);\n                dropHeight = $dropdown.outerHeight(false);\n                viewPortRight = $window.scrollLeft() + windowWidth;\n                viewportBottom = $window.scrollTop() + windowHeight;\n                dropTop = offset.top + height;\n                dropLeft = offset.left;\n                dropWidth = $dropdown.outerWidth(false);\n                $dropdown.show();\n\n                // fix so the cursor does not move to the left within the search-textbox in IE\n                this.focusSearch();\n            }\n\n            if (this.opts.dropdownAutoWidth) {\n                resultsListNode = $('.select2-results', $dropdown)[0];\n                $dropdown.addClass('select2-drop-auto-width');\n                $dropdown.css('width', '');\n                // Add scrollbar width to dropdown if vertical scrollbar is present\n                dropWidth = $dropdown.outerWidth(false) + (resultsListNode.scrollHeight === resultsListNode.clientHeight ? 0 : scrollBarDimensions.width);\n                dropWidth > width ? width = dropWidth : dropWidth = width;\n                dropHeight = $dropdown.outerHeight(false);\n            }\n            else {\n                this.container.removeClass('select2-drop-auto-width');\n            }\n\n            //console.log(\"below/ droptop:\", dropTop, \"dropHeight\", dropHeight, \"sum\", (dropTop+dropHeight)+\" viewport bottom\", viewportBottom, \"enough?\", enoughRoomBelow);\n            //console.log(\"above/ offset.top\", offset.top, \"dropHeight\", dropHeight, \"top\", (offset.top-dropHeight), \"scrollTop\", this.body.scrollTop(), \"enough?\", enoughRoomAbove);\n\n            // fix positioning when body has an offset and is not position: static\n            if (this.body.css('position') !== 'static') {\n                bodyOffset = this.body.offset();\n                dropTop -= bodyOffset.top;\n                dropLeft -= bodyOffset.left;\n            }\n\n            if (!enoughRoomOnRight() && enoughRoomOnLeft()) {\n                dropLeft = offset.left + this.container.outerWidth(false) - dropWidth;\n            }\n\n            css =  {\n                left: dropLeft,\n                width: width\n            };\n\n            if (above) {\n                css.top = offset.top - dropHeight;\n                css.bottom = 'auto';\n                this.container.addClass(\"select2-drop-above\");\n                $dropdown.addClass(\"select2-drop-above\");\n            }\n            else {\n                css.top = dropTop;\n                css.bottom = 'auto';\n                this.container.removeClass(\"select2-drop-above\");\n                $dropdown.removeClass(\"select2-drop-above\");\n            }\n            css = $.extend(css, evaluate(this.opts.dropdownCss, this.opts.element));\n\n            $dropdown.css(css);\n        },\n\n        // abstract\n        shouldOpen: function() {\n            var event;\n\n            if (this.opened()) return false;\n\n            if (this._enabled === false || this._readonly === true) return false;\n\n            event = $.Event(\"select2-opening\");\n            this.opts.element.trigger(event);\n            return !event.isDefaultPrevented();\n        },\n\n        // abstract\n        clearDropdownAlignmentPreference: function() {\n            // clear the classes used to figure out the preference of where the dropdown should be opened\n            this.container.removeClass(\"select2-drop-above\");\n            this.dropdown.removeClass(\"select2-drop-above\");\n        },\n\n        /**\n         * Opens the dropdown\n         *\n         * @return {Boolean} whether or not dropdown was opened. This method will return false if, for example,\n         * the dropdown is already open, or if the 'open' event listener on the element called preventDefault().\n         */\n        // abstract\n        open: function () {\n\n            if (!this.shouldOpen()) return false;\n\n            this.opening();\n\n            // Only bind the document mousemove when the dropdown is visible\n            $document.on(\"mousemove.select2Event\", function (e) {\n                lastMousePosition.x = e.pageX;\n                lastMousePosition.y = e.pageY;\n            });\n\n            return true;\n        },\n\n        /**\n         * Performs the opening of the dropdown\n         */\n        // abstract\n        opening: function() {\n            var cid = this.containerEventName,\n                scroll = \"scroll.\" + cid,\n                resize = \"resize.\"+cid,\n                orient = \"orientationchange.\"+cid,\n                mask;\n\n            this.container.addClass(\"select2-dropdown-open\").addClass(\"select2-container-active\");\n\n            this.clearDropdownAlignmentPreference();\n\n            if(this.dropdown[0] !== this.body.children().last()[0]) {\n                this.dropdown.detach().appendTo(this.body);\n            }\n\n            // create the dropdown mask if doesn't already exist\n            mask = $(\"#select2-drop-mask\");\n            if (mask.length === 0) {\n                mask = $(document.createElement(\"div\"));\n                mask.attr(\"id\",\"select2-drop-mask\").attr(\"class\",\"select2-drop-mask\");\n                mask.hide();\n                mask.appendTo(this.body);\n                mask.on(\"mousedown touchstart click\", function (e) {\n                    // Prevent IE from generating a click event on the body\n                    reinsertElement(mask);\n\n                    var dropdown = $(\"#select2-drop\"), self;\n                    if (dropdown.length > 0) {\n                        self=dropdown.data(\"select2\");\n                        if (self.opts.selectOnBlur) {\n                            self.selectHighlighted({noFocus: true});\n                        }\n                        self.close();\n                        e.preventDefault();\n                        e.stopPropagation();\n                    }\n                });\n            }\n\n            // ensure the mask is always right before the dropdown\n            if (this.dropdown.prev()[0] !== mask[0]) {\n                this.dropdown.before(mask);\n            }\n\n            // move the global id to the correct dropdown\n            $(\"#select2-drop\").removeAttr(\"id\");\n            this.dropdown.attr(\"id\", \"select2-drop\");\n\n            // show the elements\n            mask.show();\n\n            this.positionDropdown();\n            this.dropdown.show();\n            this.positionDropdown();\n\n            this.dropdown.addClass(\"select2-drop-active\");\n\n            // attach listeners to events that can change the position of the container and thus require\n            // the position of the dropdown to be updated as well so it does not come unglued from the container\n            var that = this;\n            this.container.parents().add(window).each(function () {\n                $(this).on(resize+\" \"+scroll+\" \"+orient, function (e) {\n                    if (that.opened()) that.positionDropdown();\n                });\n            });\n\n\n        },\n\n        // abstract\n        close: function () {\n            if (!this.opened()) return;\n\n            var cid = this.containerEventName,\n                scroll = \"scroll.\" + cid,\n                resize = \"resize.\"+cid,\n                orient = \"orientationchange.\"+cid;\n\n            // unbind event listeners\n            this.container.parents().add(window).each(function () { $(this).off(scroll).off(resize).off(orient); });\n\n            this.clearDropdownAlignmentPreference();\n\n            $(\"#select2-drop-mask\").hide();\n            this.dropdown.removeAttr(\"id\"); // only the active dropdown has the select2-drop id\n            this.dropdown.hide();\n            this.container.removeClass(\"select2-dropdown-open\").removeClass(\"select2-container-active\");\n            this.results.empty();\n\n            // Now that the dropdown is closed, unbind the global document mousemove event\n            $document.off(\"mousemove.select2Event\");\n\n            this.clearSearch();\n            this.search.removeClass(\"select2-active\");\n            this.opts.element.trigger($.Event(\"select2-close\"));\n        },\n\n        /**\n         * Opens control, sets input value, and updates results.\n         */\n        // abstract\n        externalSearch: function (term) {\n            this.open();\n            this.search.val(term);\n            this.updateResults(false);\n        },\n\n        // abstract\n        clearSearch: function () {\n\n        },\n\n        //abstract\n        getMaximumSelectionSize: function() {\n            return evaluate(this.opts.maximumSelectionSize, this.opts.element);\n        },\n\n        // abstract\n        ensureHighlightVisible: function () {\n            var results = this.results, children, index, child, hb, rb, y, more, topOffset;\n\n            index = this.highlight();\n\n            if (index < 0) return;\n\n            if (index == 0) {\n\n                // if the first element is highlighted scroll all the way to the top,\n                // that way any unselectable headers above it will also be scrolled\n                // into view\n\n                results.scrollTop(0);\n                return;\n            }\n\n            children = this.findHighlightableChoices().find('.select2-result-label');\n\n            child = $(children[index]);\n\n            topOffset = (child.offset() || {}).top || 0;\n\n            hb = topOffset + child.outerHeight(true);\n\n            // if this is the last child lets also make sure select2-more-results is visible\n            if (index === children.length - 1) {\n                more = results.find(\"li.select2-more-results\");\n                if (more.length > 0) {\n                    hb = more.offset().top + more.outerHeight(true);\n                }\n            }\n\n            rb = results.offset().top + results.outerHeight(false);\n            if (hb > rb) {\n                results.scrollTop(results.scrollTop() + (hb - rb));\n            }\n            y = topOffset - results.offset().top;\n\n            // make sure the top of the element is visible\n            if (y < 0 && child.css('display') != 'none' ) {\n                results.scrollTop(results.scrollTop() + y); // y is negative\n            }\n        },\n\n        // abstract\n        findHighlightableChoices: function() {\n            return this.results.find(\".select2-result-selectable:not(.select2-disabled):not(.select2-selected)\");\n        },\n\n        // abstract\n        moveHighlight: function (delta) {\n            var choices = this.findHighlightableChoices(),\n                index = this.highlight();\n\n            while (index > -1 && index < choices.length) {\n                index += delta;\n                var choice = $(choices[index]);\n                if (choice.hasClass(\"select2-result-selectable\") && !choice.hasClass(\"select2-disabled\") && !choice.hasClass(\"select2-selected\")) {\n                    this.highlight(index);\n                    break;\n                }\n            }\n        },\n\n        // abstract\n        highlight: function (index) {\n            var choices = this.findHighlightableChoices(),\n                choice,\n                data;\n\n            if (arguments.length === 0) {\n                return indexOf(choices.filter(\".select2-highlighted\")[0], choices.get());\n            }\n\n            if (index >= choices.length) index = choices.length - 1;\n            if (index < 0) index = 0;\n\n            this.removeHighlight();\n\n            choice = $(choices[index]);\n            choice.addClass(\"select2-highlighted\");\n\n            // ensure assistive technology can determine the active choice\n            this.search.attr(\"aria-activedescendant\", choice.find(\".select2-result-label\").attr(\"id\"));\n\n            this.ensureHighlightVisible();\n\n            this.liveRegion.text(choice.text());\n\n            data = choice.data(\"select2-data\");\n            if (data) {\n                this.opts.element.trigger({ type: \"select2-highlight\", val: this.id(data), choice: data });\n            }\n        },\n\n        removeHighlight: function() {\n            this.results.find(\".select2-highlighted\").removeClass(\"select2-highlighted\");\n        },\n\n        touchMoved: function() {\n            this._touchMoved = true;\n        },\n\n        clearTouchMoved: function() {\n          this._touchMoved = false;\n        },\n\n        // abstract\n        countSelectableResults: function() {\n            return this.findHighlightableChoices().length;\n        },\n\n        // abstract\n        highlightUnderEvent: function (event) {\n            var el = $(event.target).closest(\".select2-result-selectable\");\n            if (el.length > 0 && !el.is(\".select2-highlighted\")) {\n                var choices = this.findHighlightableChoices();\n                this.highlight(choices.index(el));\n            } else if (el.length == 0) {\n                // if we are over an unselectable item remove all highlights\n                this.removeHighlight();\n            }\n        },\n\n        // abstract\n        loadMoreIfNeeded: function () {\n            var results = this.results,\n                more = results.find(\"li.select2-more-results\"),\n                below, // pixels the element is below the scroll fold, below==0 is when the element is starting to be visible\n                page = this.resultsPage + 1,\n                self=this,\n                term=this.search.val(),\n                context=this.context;\n\n            if (more.length === 0) return;\n            below = more.offset().top - results.offset().top - results.height();\n\n            if (below <= this.opts.loadMorePadding) {\n                more.addClass(\"select2-active\");\n                this.opts.query({\n                        element: this.opts.element,\n                        term: term,\n                        page: page,\n                        context: context,\n                        matcher: this.opts.matcher,\n                        callback: this.bind(function (data) {\n\n                    // ignore a response if the select2 has been closed before it was received\n                    if (!self.opened()) return;\n\n\n                    self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});\n                    self.postprocessResults(data, false, false);\n\n                    if (data.more===true) {\n                        more.detach().appendTo(results).html(self.opts.escapeMarkup(evaluate(self.opts.formatLoadMore, self.opts.element, page+1)));\n                        window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);\n                    } else {\n                        more.remove();\n                    }\n                    self.positionDropdown();\n                    self.resultsPage = page;\n                    self.context = data.context;\n                    this.opts.element.trigger({ type: \"select2-loaded\", items: data });\n                })});\n            }\n        },\n\n        /**\n         * Default tokenizer function which does nothing\n         */\n        tokenize: function() {\n\n        },\n\n        /**\n         * @param initial whether or not this is the call to this method right after the dropdown has been opened\n         */\n        // abstract\n        updateResults: function (initial) {\n            var search = this.search,\n                results = this.results,\n                opts = this.opts,\n                data,\n                self = this,\n                input,\n                term = search.val(),\n                lastTerm = $.data(this.container, \"select2-last-term\"),\n                // sequence number used to drop out-of-order responses\n                queryNumber;\n\n            // prevent duplicate queries against the same term\n            if (initial !== true && lastTerm && equal(term, lastTerm)) return;\n\n            $.data(this.container, \"select2-last-term\", term);\n\n            // if the search is currently hidden we do not alter the results\n            if (initial !== true && (this.showSearchInput === false || !this.opened())) {\n                return;\n            }\n\n            function postRender() {\n                search.removeClass(\"select2-active\");\n                self.positionDropdown();\n                if (results.find('.select2-no-results,.select2-selection-limit,.select2-searching').length) {\n                    self.liveRegion.text(results.text());\n                }\n                else {\n                    self.liveRegion.text(self.opts.formatMatches(results.find('.select2-result-selectable:not(\".select2-selected\")').length));\n                }\n            }\n\n            function render(html) {\n                results.html(html);\n                postRender();\n            }\n\n            queryNumber = ++this.queryCount;\n\n            var maxSelSize = this.getMaximumSelectionSize();\n            if (maxSelSize >=1) {\n                data = this.data();\n                if ($.isArray(data) && data.length >= maxSelSize && checkFormatter(opts.formatSelectionTooBig, \"formatSelectionTooBig\")) {\n                    render(\"<li class='select2-selection-limit'>\" + evaluate(opts.formatSelectionTooBig, opts.element, maxSelSize) + \"</li>\");\n                    return;\n                }\n            }\n\n            if (search.val().length < opts.minimumInputLength) {\n                if (checkFormatter(opts.formatInputTooShort, \"formatInputTooShort\")) {\n                    render(\"<li class='select2-no-results'>\" + evaluate(opts.formatInputTooShort, opts.element, search.val(), opts.minimumInputLength) + \"</li>\");\n                } else {\n                    render(\"\");\n                }\n                if (initial && this.showSearch) this.showSearch(true);\n                return;\n            }\n\n            if (opts.maximumInputLength && search.val().length > opts.maximumInputLength) {\n                if (checkFormatter(opts.formatInputTooLong, \"formatInputTooLong\")) {\n                    render(\"<li class='select2-no-results'>\" + evaluate(opts.formatInputTooLong, opts.element, search.val(), opts.maximumInputLength) + \"</li>\");\n                } else {\n                    render(\"\");\n                }\n                return;\n            }\n\n            if (opts.formatSearching && this.findHighlightableChoices().length === 0) {\n                render(\"<li class='select2-searching'>\" + evaluate(opts.formatSearching, opts.element) + \"</li>\");\n            }\n\n            search.addClass(\"select2-active\");\n\n            this.removeHighlight();\n\n            // give the tokenizer a chance to pre-process the input\n            input = this.tokenize();\n            if (input != undefined && input != null) {\n                search.val(input);\n            }\n\n            this.resultsPage = 1;\n\n            opts.query({\n                element: opts.element,\n                    term: search.val(),\n                    page: this.resultsPage,\n                    context: null,\n                    matcher: opts.matcher,\n                    callback: this.bind(function (data) {\n                var def; // default choice\n\n                // ignore old responses\n                if (queryNumber != this.queryCount) {\n                  return;\n                }\n\n                // ignore a response if the select2 has been closed before it was received\n                if (!this.opened()) {\n                    this.search.removeClass(\"select2-active\");\n                    return;\n                }\n\n                // handle ajax error\n                if(data.hasError !== undefined && checkFormatter(opts.formatAjaxError, \"formatAjaxError\")) {\n                    render(\"<li class='select2-ajax-error'>\" + evaluate(opts.formatAjaxError, opts.element, data.jqXHR, data.textStatus, data.errorThrown) + \"</li>\");\n                    return;\n                }\n\n                // save context, if any\n                this.context = (data.context===undefined) ? null : data.context;\n                // create a default choice and prepend it to the list\n                if (this.opts.createSearchChoice && search.val() !== \"\") {\n                    def = this.opts.createSearchChoice.call(self, search.val(), data.results);\n                    if (def !== undefined && def !== null && self.id(def) !== undefined && self.id(def) !== null) {\n                        if ($(data.results).filter(\n                            function () {\n                                return equal(self.id(this), self.id(def));\n                            }).length === 0) {\n                            this.opts.createSearchChoicePosition(data.results, def);\n                        }\n                    }\n                }\n\n                if (data.results.length === 0 && checkFormatter(opts.formatNoMatches, \"formatNoMatches\")) {\n                    render(\"<li class='select2-no-results'>\" + evaluate(opts.formatNoMatches, opts.element, search.val()) + \"</li>\");\n                    return;\n                }\n\n                results.empty();\n                self.opts.populateResults.call(this, results, data.results, {term: search.val(), page: this.resultsPage, context:null});\n\n                if (data.more === true && checkFormatter(opts.formatLoadMore, \"formatLoadMore\")) {\n                    results.append(\"<li class='select2-more-results'>\" + opts.escapeMarkup(evaluate(opts.formatLoadMore, opts.element, this.resultsPage)) + \"</li>\");\n                    window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);\n                }\n\n                this.postprocessResults(data, initial);\n\n                postRender();\n\n                this.opts.element.trigger({ type: \"select2-loaded\", items: data });\n            })});\n        },\n\n        // abstract\n        cancel: function () {\n            this.close();\n        },\n\n        // abstract\n        blur: function () {\n            // if selectOnBlur == true, select the currently highlighted option\n            if (this.opts.selectOnBlur)\n                this.selectHighlighted({noFocus: true});\n\n            this.close();\n            this.container.removeClass(\"select2-container-active\");\n            // synonymous to .is(':focus'), which is available in jquery >= 1.6\n            if (this.search[0] === document.activeElement) { this.search.blur(); }\n            this.clearSearch();\n            this.selection.find(\".select2-search-choice-focus\").removeClass(\"select2-search-choice-focus\");\n        },\n\n        // abstract\n        focusSearch: function () {\n            focus(this.search);\n        },\n\n        // abstract\n        selectHighlighted: function (options) {\n            if (this._touchMoved) {\n              this.clearTouchMoved();\n              return;\n            }\n            var index=this.highlight(),\n                highlighted=this.results.find(\".select2-highlighted\"),\n                data = highlighted.closest('.select2-result').data(\"select2-data\");\n\n            if (data) {\n                this.highlight(index);\n                this.onSelect(data, options);\n            } else if (options && options.noFocus) {\n                this.close();\n            }\n        },\n\n        // abstract\n        getPlaceholder: function () {\n            var placeholderOption;\n            return this.opts.element.attr(\"placeholder\") ||\n                this.opts.element.attr(\"data-placeholder\") || // jquery 1.4 compat\n                this.opts.element.data(\"placeholder\") ||\n                this.opts.placeholder ||\n                ((placeholderOption = this.getPlaceholderOption()) !== undefined ? placeholderOption.text() : undefined);\n        },\n\n        // abstract\n        getPlaceholderOption: function() {\n            if (this.select) {\n                var firstOption = this.select.children('option').first();\n                if (this.opts.placeholderOption !== undefined ) {\n                    //Determine the placeholder option based on the specified placeholderOption setting\n                    return (this.opts.placeholderOption === \"first\" && firstOption) ||\n                           (typeof this.opts.placeholderOption === \"function\" && this.opts.placeholderOption(this.select));\n                } else if ($.trim(firstOption.text()) === \"\" && firstOption.val() === \"\") {\n                    //No explicit placeholder option specified, use the first if it's blank\n                    return firstOption;\n                }\n            }\n        },\n\n        /**\n         * Get the desired width for the container element.  This is\n         * derived first from option `width` passed to select2, then\n         * the inline 'style' on the original element, and finally\n         * falls back to the jQuery calculated element width.\n         */\n        // abstract\n        initContainerWidth: function () {\n            function resolveContainerWidth() {\n                var style, attrs, matches, i, l, attr;\n\n                if (this.opts.width === \"off\") {\n                    return null;\n                } else if (this.opts.width === \"element\"){\n                    return this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px';\n                } else if (this.opts.width === \"copy\" || this.opts.width === \"resolve\") {\n                    // check if there is inline style on the element that contains width\n                    style = this.opts.element.attr('style');\n                    if (style !== undefined) {\n                        attrs = style.split(';');\n                        for (i = 0, l = attrs.length; i < l; i = i + 1) {\n                            attr = attrs[i].replace(/\\s/g, '');\n                            matches = attr.match(/^width:(([-+]?([0-9]*\\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i);\n                            if (matches !== null && matches.length >= 1)\n                                return matches[1];\n                        }\n                    }\n\n                    if (this.opts.width === \"resolve\") {\n                        // next check if css('width') can resolve a width that is percent based, this is sometimes possible\n                        // when attached to input type=hidden or elements hidden via css\n                        style = this.opts.element.css('width');\n                        if (style.indexOf(\"%\") > 0) return style;\n\n                        // finally, fallback on the calculated width of the element\n                        return (this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px');\n                    }\n\n                    return null;\n                } else if ($.isFunction(this.opts.width)) {\n                    return this.opts.width();\n                } else {\n                    return this.opts.width;\n               }\n            };\n\n            var width = resolveContainerWidth.call(this);\n            if (width !== null) {\n                this.container.css(\"width\", width);\n            }\n        }\n    });\n\n    SingleSelect2 = clazz(AbstractSelect2, {\n\n        // single\n\n        createContainer: function () {\n            var container = $(document.createElement(\"div\")).attr({\n                \"class\": \"select2-container\"\n            }).html([\n                \"<a href='javascript:void(0)' class='select2-choice' tabindex='-1'>\",\n                \"   <span class='select2-chosen'>&#160;</span><abbr class='select2-search-choice-close'></abbr>\",\n                \"   <span class='select2-arrow' role='presentation'><b role='presentation'></b></span>\",\n                \"</a>\",\n                \"<label for='' class='select2-offscreen'></label>\",\n                \"<input class='select2-focusser select2-offscreen' type='text' aria-haspopup='true' role='button' />\",\n                \"<div class='select2-drop select2-display-none'>\",\n                \"   <div class='select2-search'>\",\n                \"       <label for='' class='select2-offscreen'></label>\",\n                \"       <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input' role='combobox' aria-expanded='true'\",\n                \"       aria-autocomplete='list' />\",\n                \"   </div>\",\n                \"   <ul class='select2-results' role='listbox'>\",\n                \"   </ul>\",\n                \"</div>\"].join(\"\"));\n            return container;\n        },\n\n        // single\n        enableInterface: function() {\n            if (this.parent.enableInterface.apply(this, arguments)) {\n                this.focusser.prop(\"disabled\", !this.isInterfaceEnabled());\n            }\n        },\n\n        // single\n        opening: function () {\n            var el, range, len;\n\n            if (this.opts.minimumResultsForSearch >= 0) {\n                this.showSearch(true);\n            }\n\n            this.parent.opening.apply(this, arguments);\n\n            if (this.showSearchInput !== false) {\n                // IE appends focusser.val() at the end of field :/ so we manually insert it at the beginning using a range\n                // all other browsers handle this just fine\n\n                this.search.val(this.focusser.val());\n            }\n            if (this.opts.shouldFocusInput(this)) {\n                this.search.focus();\n                // move the cursor to the end after focussing, otherwise it will be at the beginning and\n                // new text will appear *before* focusser.val()\n                el = this.search.get(0);\n                if (el.createTextRange) {\n                    range = el.createTextRange();\n                    range.collapse(false);\n                    range.select();\n                } else if (el.setSelectionRange) {\n                    len = this.search.val().length;\n                    el.setSelectionRange(len, len);\n                }\n            }\n\n            // initializes search's value with nextSearchTerm (if defined by user)\n            // ignore nextSearchTerm if the dropdown is opened by the user pressing a letter\n            if(this.search.val() === \"\") {\n                if(this.nextSearchTerm != undefined){\n                    this.search.val(this.nextSearchTerm);\n                    this.search.select();\n                }\n            }\n\n            this.focusser.prop(\"disabled\", true).val(\"\");\n            this.updateResults(true);\n            this.opts.element.trigger($.Event(\"select2-open\"));\n        },\n\n        // single\n        close: function () {\n            if (!this.opened()) return;\n            this.parent.close.apply(this, arguments);\n\n            this.focusser.prop(\"disabled\", false);\n\n            if (this.opts.shouldFocusInput(this)) {\n                this.focusser.focus();\n            }\n        },\n\n        // single\n        focus: function () {\n            if (this.opened()) {\n                this.close();\n            } else {\n                this.focusser.prop(\"disabled\", false);\n                if (this.opts.shouldFocusInput(this)) {\n                    this.focusser.focus();\n                }\n            }\n        },\n\n        // single\n        isFocused: function () {\n            return this.container.hasClass(\"select2-container-active\");\n        },\n\n        // single\n        cancel: function () {\n            this.parent.cancel.apply(this, arguments);\n            this.focusser.prop(\"disabled\", false);\n\n            if (this.opts.shouldFocusInput(this)) {\n                this.focusser.focus();\n            }\n        },\n\n        // single\n        destroy: function() {\n            $(\"label[for='\" + this.focusser.attr('id') + \"']\")\n                .attr('for', this.opts.element.attr(\"id\"));\n            this.parent.destroy.apply(this, arguments);\n\n            cleanupJQueryElements.call(this,\n                \"selection\",\n                \"focusser\"\n            );\n        },\n\n        // single\n        initContainer: function () {\n\n            var selection,\n                container = this.container,\n                dropdown = this.dropdown,\n                idSuffix = nextUid(),\n                elementLabel;\n\n            if (this.opts.minimumResultsForSearch < 0) {\n                this.showSearch(false);\n            } else {\n                this.showSearch(true);\n            }\n\n            this.selection = selection = container.find(\".select2-choice\");\n\n            this.focusser = container.find(\".select2-focusser\");\n\n            // add aria associations\n            selection.find(\".select2-chosen\").attr(\"id\", \"select2-chosen-\"+idSuffix);\n            this.focusser.attr(\"aria-labelledby\", \"select2-chosen-\"+idSuffix);\n            this.results.attr(\"id\", \"select2-results-\"+idSuffix);\n            this.search.attr(\"aria-owns\", \"select2-results-\"+idSuffix);\n\n            // rewrite labels from original element to focusser\n            this.focusser.attr(\"id\", \"s2id_autogen\"+idSuffix);\n\n            elementLabel = $(\"label[for='\" + this.opts.element.attr(\"id\") + \"']\");\n            this.opts.element.focus(this.bind(function () { this.focus(); }));\n\n            this.focusser.prev()\n                .text(elementLabel.text())\n                .attr('for', this.focusser.attr('id'));\n\n            // Ensure the original element retains an accessible name\n            var originalTitle = this.opts.element.attr(\"title\");\n            this.opts.element.attr(\"title\", (originalTitle || elementLabel.text()));\n\n            this.focusser.attr(\"tabindex\", this.elementTabIndex);\n\n            // write label for search field using the label from the focusser element\n            this.search.attr(\"id\", this.focusser.attr('id') + '_search');\n\n            this.search.prev()\n                .text($(\"label[for='\" + this.focusser.attr('id') + \"']\").text())\n                .attr('for', this.search.attr('id'));\n\n            this.search.on(\"keydown\", this.bind(function (e) {\n                if (!this.isInterfaceEnabled()) return;\n\n                // filter 229 keyCodes (input method editor is processing key input)\n                if (229 == e.keyCode) return;\n\n                if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {\n                    // prevent the page from scrolling\n                    killEvent(e);\n                    return;\n                }\n\n                switch (e.which) {\n                    case KEY.UP:\n                    case KEY.DOWN:\n                        this.moveHighlight((e.which === KEY.UP) ? -1 : 1);\n                        killEvent(e);\n                        return;\n                    case KEY.ENTER:\n                        this.selectHighlighted();\n                        killEvent(e);\n                        return;\n                    case KEY.TAB:\n                        this.selectHighlighted({noFocus: true});\n                        return;\n                    case KEY.ESC:\n                        this.cancel(e);\n                        killEvent(e);\n                        return;\n                }\n            }));\n\n            this.search.on(\"blur\", this.bind(function(e) {\n                // a workaround for chrome to keep the search field focussed when the scroll bar is used to scroll the dropdown.\n                // without this the search field loses focus which is annoying\n                if (document.activeElement === this.body.get(0)) {\n                    window.setTimeout(this.bind(function() {\n                        if (this.opened()) {\n                            this.search.focus();\n                        }\n                    }), 0);\n                }\n            }));\n\n            this.focusser.on(\"keydown\", this.bind(function (e) {\n                if (!this.isInterfaceEnabled()) return;\n\n                if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {\n                    return;\n                }\n\n                if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {\n                    killEvent(e);\n                    return;\n                }\n\n                if (e.which == KEY.DOWN || e.which == KEY.UP\n                    || (e.which == KEY.ENTER && this.opts.openOnEnter)) {\n\n                    if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) return;\n\n                    this.open();\n                    killEvent(e);\n                    return;\n                }\n\n                if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) {\n                    if (this.opts.allowClear) {\n                        this.clear();\n                    }\n                    killEvent(e);\n                    return;\n                }\n            }));\n\n\n            installKeyUpChangeEvent(this.focusser);\n            this.focusser.on(\"keyup-change input\", this.bind(function(e) {\n                if (this.opts.minimumResultsForSearch >= 0) {\n                    e.stopPropagation();\n                    if (this.opened()) return;\n                    this.open();\n                }\n            }));\n\n            selection.on(\"mousedown touchstart\", \"abbr\", this.bind(function (e) {\n                if (!this.isInterfaceEnabled()) {\n                    return;\n                }\n\n                this.clear();\n                killEventImmediately(e);\n                this.close();\n\n                if (this.selection) {\n                    this.selection.focus();\n                }\n            }));\n\n            selection.on(\"mousedown touchstart\", this.bind(function (e) {\n                // Prevent IE from generating a click event on the body\n                reinsertElement(selection);\n\n                if (!this.container.hasClass(\"select2-container-active\")) {\n                    this.opts.element.trigger($.Event(\"select2-focus\"));\n                }\n\n                if (this.opened()) {\n                    this.close();\n                } else if (this.isInterfaceEnabled()) {\n                    this.open();\n                }\n\n                killEvent(e);\n            }));\n\n            dropdown.on(\"mousedown touchstart\", this.bind(function() {\n                if (this.opts.shouldFocusInput(this)) {\n                    this.search.focus();\n                }\n            }));\n\n            selection.on(\"focus\", this.bind(function(e) {\n                killEvent(e);\n            }));\n\n            this.focusser.on(\"focus\", this.bind(function(){\n                if (!this.container.hasClass(\"select2-container-active\")) {\n                    this.opts.element.trigger($.Event(\"select2-focus\"));\n                }\n                this.container.addClass(\"select2-container-active\");\n            })).on(\"blur\", this.bind(function() {\n                if (!this.opened()) {\n                    this.container.removeClass(\"select2-container-active\");\n                    this.opts.element.trigger($.Event(\"select2-blur\"));\n                }\n            }));\n            this.search.on(\"focus\", this.bind(function(){\n                if (!this.container.hasClass(\"select2-container-active\")) {\n                    this.opts.element.trigger($.Event(\"select2-focus\"));\n                }\n                this.container.addClass(\"select2-container-active\");\n            }));\n\n            this.initContainerWidth();\n            this.opts.element.hide();\n            this.setPlaceholder();\n\n        },\n\n        // single\n        clear: function(triggerChange) {\n            var data=this.selection.data(\"select2-data\");\n            if (data) { // guard against queued quick consecutive clicks\n                var evt = $.Event(\"select2-clearing\");\n                this.opts.element.trigger(evt);\n                if (evt.isDefaultPrevented()) {\n                    return;\n                }\n                var placeholderOption = this.getPlaceholderOption();\n                this.opts.element.val(placeholderOption ? placeholderOption.val() : \"\");\n                this.selection.find(\".select2-chosen\").empty();\n                this.selection.removeData(\"select2-data\");\n                this.setPlaceholder();\n\n                if (triggerChange !== false){\n                    this.opts.element.trigger({ type: \"select2-removed\", val: this.id(data), choice: data });\n                    this.triggerChange({removed:data});\n                }\n            }\n        },\n\n        /**\n         * Sets selection based on source element's value\n         */\n        // single\n        initSelection: function () {\n            var selected;\n            if (this.isPlaceholderOptionSelected()) {\n                this.updateSelection(null);\n                this.close();\n                this.setPlaceholder();\n            } else {\n                var self = this;\n                this.opts.initSelection.call(null, this.opts.element, function(selected){\n                    if (selected !== undefined && selected !== null) {\n                        self.updateSelection(selected);\n                        self.close();\n                        self.setPlaceholder();\n                        self.nextSearchTerm = self.opts.nextSearchTerm(selected, self.search.val());\n                    }\n                });\n            }\n        },\n\n        isPlaceholderOptionSelected: function() {\n            var placeholderOption;\n            if (this.getPlaceholder() === undefined) return false; // no placeholder specified so no option should be considered\n            return ((placeholderOption = this.getPlaceholderOption()) !== undefined && placeholderOption.prop(\"selected\"))\n                || (this.opts.element.val() === \"\")\n                || (this.opts.element.val() === undefined)\n                || (this.opts.element.val() === null);\n        },\n\n        // single\n        prepareOpts: function () {\n            var opts = this.parent.prepareOpts.apply(this, arguments),\n                self=this;\n\n            if (opts.element.get(0).tagName.toLowerCase() === \"select\") {\n                // install the selection initializer\n                opts.initSelection = function (element, callback) {\n                    var selected = element.find(\"option\").filter(function() { return this.selected && !this.disabled });\n                    // a single select box always has a value, no need to null check 'selected'\n                    callback(self.optionToData(selected));\n                };\n            } else if (\"data\" in opts) {\n                // install default initSelection when applied to hidden input and data is local\n                opts.initSelection = opts.initSelection || function (element, callback) {\n                    var id = element.val();\n                    //search in data by id, storing the actual matching item\n                    var match = null;\n                    opts.query({\n                        matcher: function(term, text, el){\n                            var is_match = equal(id, opts.id(el));\n                            if (is_match) {\n                                match = el;\n                            }\n                            return is_match;\n                        },\n                        callback: !$.isFunction(callback) ? $.noop : function() {\n                            callback(match);\n                        }\n                    });\n                };\n            }\n\n            return opts;\n        },\n\n        // single\n        getPlaceholder: function() {\n            // if a placeholder is specified on a single select without a valid placeholder option ignore it\n            if (this.select) {\n                if (this.getPlaceholderOption() === undefined) {\n                    return undefined;\n                }\n            }\n\n            return this.parent.getPlaceholder.apply(this, arguments);\n        },\n\n        // single\n        setPlaceholder: function () {\n            var placeholder = this.getPlaceholder();\n\n            if (this.isPlaceholderOptionSelected() && placeholder !== undefined) {\n\n                // check for a placeholder option if attached to a select\n                if (this.select && this.getPlaceholderOption() === undefined) return;\n\n                this.selection.find(\".select2-chosen\").html(this.opts.escapeMarkup(placeholder));\n\n                this.selection.addClass(\"select2-default\");\n\n                this.container.removeClass(\"select2-allowclear\");\n            }\n        },\n\n        // single\n        postprocessResults: function (data, initial, noHighlightUpdate) {\n            var selected = 0, self = this, showSearchInput = true;\n\n            // find the selected element in the result list\n\n            this.findHighlightableChoices().each2(function (i, elm) {\n                if (equal(self.id(elm.data(\"select2-data\")), self.opts.element.val())) {\n                    selected = i;\n                    return false;\n                }\n            });\n\n            // and highlight it\n            if (noHighlightUpdate !== false) {\n                if (initial === true && selected >= 0) {\n                    this.highlight(selected);\n                } else {\n                    this.highlight(0);\n                }\n            }\n\n            // hide the search box if this is the first we got the results and there are enough of them for search\n\n            if (initial === true) {\n                var min = this.opts.minimumResultsForSearch;\n                if (min >= 0) {\n                    this.showSearch(countResults(data.results) >= min);\n                }\n            }\n        },\n\n        // single\n        showSearch: function(showSearchInput) {\n            if (this.showSearchInput === showSearchInput) return;\n\n            this.showSearchInput = showSearchInput;\n\n            this.dropdown.find(\".select2-search\").toggleClass(\"select2-search-hidden\", !showSearchInput);\n            this.dropdown.find(\".select2-search\").toggleClass(\"select2-offscreen\", !showSearchInput);\n            //add \"select2-with-searchbox\" to the container if search box is shown\n            $(this.dropdown, this.container).toggleClass(\"select2-with-searchbox\", showSearchInput);\n        },\n\n        // single\n        onSelect: function (data, options) {\n\n            if (!this.triggerSelect(data)) { return; }\n\n            var old = this.opts.element.val(),\n                oldData = this.data();\n\n            this.opts.element.val(this.id(data));\n            this.updateSelection(data);\n\n            this.opts.element.trigger({ type: \"select2-selected\", val: this.id(data), choice: data });\n\n            this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());\n            this.close();\n\n            if ((!options || !options.noFocus) && this.opts.shouldFocusInput(this)) {\n                this.focusser.focus();\n            }\n\n            if (!equal(old, this.id(data))) {\n                this.triggerChange({ added: data, removed: oldData });\n            }\n        },\n\n        // single\n        updateSelection: function (data) {\n\n            var container=this.selection.find(\".select2-chosen\"), formatted, cssClass;\n\n            this.selection.data(\"select2-data\", data);\n\n            container.empty();\n            if (data !== null) {\n                formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);\n            }\n            if (formatted !== undefined) {\n                container.append(formatted);\n            }\n            cssClass=this.opts.formatSelectionCssClass(data, container);\n            if (cssClass !== undefined) {\n                container.addClass(cssClass);\n            }\n\n            this.selection.removeClass(\"select2-default\");\n\n            if (this.opts.allowClear && this.getPlaceholder() !== undefined) {\n                this.container.addClass(\"select2-allowclear\");\n            }\n        },\n\n        // single\n        val: function () {\n            var val,\n                triggerChange = false,\n                data = null,\n                self = this,\n                oldData = this.data();\n\n            if (arguments.length === 0) {\n                return this.opts.element.val();\n            }\n\n            val = arguments[0];\n\n            if (arguments.length > 1) {\n                triggerChange = arguments[1];\n            }\n\n            if (this.select) {\n                this.select\n                    .val(val)\n                    .find(\"option\").filter(function() { return this.selected }).each2(function (i, elm) {\n                        data = self.optionToData(elm);\n                        return false;\n                    });\n                this.updateSelection(data);\n                this.setPlaceholder();\n                if (triggerChange) {\n                    this.triggerChange({added: data, removed:oldData});\n                }\n            } else {\n                // val is an id. !val is true for [undefined,null,'',0] - 0 is legal\n                if (!val && val !== 0) {\n                    this.clear(triggerChange);\n                    return;\n                }\n                if (this.opts.initSelection === undefined) {\n                    throw new Error(\"cannot call val() if initSelection() is not defined\");\n                }\n                this.opts.element.val(val);\n                this.opts.initSelection(this.opts.element, function(data){\n                    self.opts.element.val(!data ? \"\" : self.id(data));\n                    self.updateSelection(data);\n                    self.setPlaceholder();\n                    if (triggerChange) {\n                        self.triggerChange({added: data, removed:oldData});\n                    }\n                });\n            }\n        },\n\n        // single\n        clearSearch: function () {\n            this.search.val(\"\");\n            this.focusser.val(\"\");\n        },\n\n        // single\n        data: function(value) {\n            var data,\n                triggerChange = false;\n\n            if (arguments.length === 0) {\n                data = this.selection.data(\"select2-data\");\n                if (data == undefined) data = null;\n                return data;\n            } else {\n                if (arguments.length > 1) {\n                    triggerChange = arguments[1];\n                }\n                if (!value) {\n                    this.clear(triggerChange);\n                } else {\n                    data = this.data();\n                    this.opts.element.val(!value ? \"\" : this.id(value));\n                    this.updateSelection(value);\n                    if (triggerChange) {\n                        this.triggerChange({added: value, removed:data});\n                    }\n                }\n            }\n        }\n    });\n\n    MultiSelect2 = clazz(AbstractSelect2, {\n\n        // multi\n        createContainer: function () {\n            var container = $(document.createElement(\"div\")).attr({\n                \"class\": \"select2-container select2-container-multi\"\n            }).html([\n                \"<ul class='select2-choices'>\",\n                \"  <li class='select2-search-field'>\",\n                \"    <label for='' class='select2-offscreen'></label>\",\n                \"    <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'>\",\n                \"  </li>\",\n                \"</ul>\",\n                \"<div class='select2-drop select2-drop-multi select2-display-none'>\",\n                \"   <ul class='select2-results'>\",\n                \"   </ul>\",\n                \"</div>\"].join(\"\"));\n            return container;\n        },\n\n        // multi\n        prepareOpts: function () {\n            var opts = this.parent.prepareOpts.apply(this, arguments),\n                self=this;\n\n            // TODO validate placeholder is a string if specified\n            if (opts.element.get(0).tagName.toLowerCase() === \"select\") {\n                // install the selection initializer\n                opts.initSelection = function (element, callback) {\n\n                    var data = [];\n\n                    element.find(\"option\").filter(function() { return this.selected && !this.disabled }).each2(function (i, elm) {\n                        data.push(self.optionToData(elm));\n                    });\n                    callback(data);\n                };\n            } else if (\"data\" in opts) {\n                // install default initSelection when applied to hidden input and data is local\n                opts.initSelection = opts.initSelection || function (element, callback) {\n                    var ids = splitVal(element.val(), opts.separator, opts.transformVal);\n                    //search in data by array of ids, storing matching items in a list\n                    var matches = [];\n                    opts.query({\n                        matcher: function(term, text, el){\n                            var is_match = $.grep(ids, function(id) {\n                                return equal(id, opts.id(el));\n                            }).length;\n                            if (is_match) {\n                                matches.push(el);\n                            }\n                            return is_match;\n                        },\n                        callback: !$.isFunction(callback) ? $.noop : function() {\n                            // reorder matches based on the order they appear in the ids array because right now\n                            // they are in the order in which they appear in data array\n                            var ordered = [];\n                            for (var i = 0; i < ids.length; i++) {\n                                var id = ids[i];\n                                for (var j = 0; j < matches.length; j++) {\n                                    var match = matches[j];\n                                    if (equal(id, opts.id(match))) {\n                                        ordered.push(match);\n                                        matches.splice(j, 1);\n                                        break;\n                                    }\n                                }\n                            }\n                            callback(ordered);\n                        }\n                    });\n                };\n            }\n\n            return opts;\n        },\n\n        // multi\n        selectChoice: function (choice) {\n\n            var selected = this.container.find(\".select2-search-choice-focus\");\n            if (selected.length && choice && choice[0] == selected[0]) {\n\n            } else {\n                if (selected.length) {\n                    this.opts.element.trigger(\"choice-deselected\", selected);\n                }\n                selected.removeClass(\"select2-search-choice-focus\");\n                if (choice && choice.length) {\n                    this.close();\n                    choice.addClass(\"select2-search-choice-focus\");\n                    this.opts.element.trigger(\"choice-selected\", choice);\n                }\n            }\n        },\n\n        // multi\n        destroy: function() {\n            $(\"label[for='\" + this.search.attr('id') + \"']\")\n                .attr('for', this.opts.element.attr(\"id\"));\n            this.parent.destroy.apply(this, arguments);\n\n            cleanupJQueryElements.call(this,\n                \"searchContainer\",\n                \"selection\"\n            );\n        },\n\n        // multi\n        initContainer: function () {\n\n            var selector = \".select2-choices\", selection;\n\n            this.searchContainer = this.container.find(\".select2-search-field\");\n            this.selection = selection = this.container.find(selector);\n\n            var _this = this;\n            this.selection.on(\"click\", \".select2-container:not(.select2-container-disabled) .select2-search-choice:not(.select2-locked)\", function (e) {\n                _this.search[0].focus();\n                _this.selectChoice($(this));\n            });\n\n            // rewrite labels from original element to focusser\n            this.search.attr(\"id\", \"s2id_autogen\"+nextUid());\n\n            this.search.prev()\n                .text($(\"label[for='\" + this.opts.element.attr(\"id\") + \"']\").text())\n                .attr('for', this.search.attr('id'));\n            this.opts.element.focus(this.bind(function () { this.focus(); }));\n\n            this.search.on(\"input paste\", this.bind(function() {\n                if (this.search.attr('placeholder') && this.search.val().length == 0) return;\n                if (!this.isInterfaceEnabled()) return;\n                if (!this.opened()) {\n                    this.open();\n                }\n            }));\n\n            this.search.attr(\"tabindex\", this.elementTabIndex);\n\n            this.keydowns = 0;\n            this.search.on(\"keydown\", this.bind(function (e) {\n                if (!this.isInterfaceEnabled()) return;\n\n                ++this.keydowns;\n                var selected = selection.find(\".select2-search-choice-focus\");\n                var prev = selected.prev(\".select2-search-choice:not(.select2-locked)\");\n                var next = selected.next(\".select2-search-choice:not(.select2-locked)\");\n                var pos = getCursorInfo(this.search);\n\n                if (selected.length &&\n                    (e.which == KEY.LEFT || e.which == KEY.RIGHT || e.which == KEY.BACKSPACE || e.which == KEY.DELETE || e.which == KEY.ENTER)) {\n                    var selectedChoice = selected;\n                    if (e.which == KEY.LEFT && prev.length) {\n                        selectedChoice = prev;\n                    }\n                    else if (e.which == KEY.RIGHT) {\n                        selectedChoice = next.length ? next : null;\n                    }\n                    else if (e.which === KEY.BACKSPACE) {\n                        if (this.unselect(selected.first())) {\n                            this.search.width(10);\n                            selectedChoice = prev.length ? prev : next;\n                        }\n                    } else if (e.which == KEY.DELETE) {\n                        if (this.unselect(selected.first())) {\n                            this.search.width(10);\n                            selectedChoice = next.length ? next : null;\n                        }\n                    } else if (e.which == KEY.ENTER) {\n                        selectedChoice = null;\n                    }\n\n                    this.selectChoice(selectedChoice);\n                    killEvent(e);\n                    if (!selectedChoice || !selectedChoice.length) {\n                        this.open();\n                    }\n                    return;\n                } else if (((e.which === KEY.BACKSPACE && this.keydowns == 1)\n                    || e.which == KEY.LEFT) && (pos.offset == 0 && !pos.length)) {\n\n                    this.selectChoice(selection.find(\".select2-search-choice:not(.select2-locked)\").last());\n                    killEvent(e);\n                    return;\n                } else {\n                    this.selectChoice(null);\n                }\n\n                if (this.opened()) {\n                    switch (e.which) {\n                    case KEY.UP:\n                    case KEY.DOWN:\n                        this.moveHighlight((e.which === KEY.UP) ? -1 : 1);\n                        killEvent(e);\n                        return;\n                    case KEY.ENTER:\n                        this.selectHighlighted();\n                        killEvent(e);\n                        return;\n                    case KEY.TAB:\n                        this.selectHighlighted({noFocus:true});\n                        this.close();\n                        return;\n                    case KEY.ESC:\n                        this.cancel(e);\n                        killEvent(e);\n                        return;\n                    }\n                }\n\n                if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e)\n                 || e.which === KEY.BACKSPACE || e.which === KEY.ESC) {\n                    return;\n                }\n\n                if (e.which === KEY.ENTER) {\n                    if (this.opts.openOnEnter === false) {\n                        return;\n                    } else if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {\n                        return;\n                    }\n                }\n\n                this.open();\n\n                if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {\n                    // prevent the page from scrolling\n                    killEvent(e);\n                }\n\n                if (e.which === KEY.ENTER) {\n                    // prevent form from being submitted\n                    killEvent(e);\n                }\n\n            }));\n\n            this.search.on(\"keyup\", this.bind(function (e) {\n                this.keydowns = 0;\n                this.resizeSearch();\n            })\n            );\n\n            this.search.on(\"blur\", this.bind(function(e) {\n                this.container.removeClass(\"select2-container-active\");\n                this.search.removeClass(\"select2-focused\");\n                this.selectChoice(null);\n                if (!this.opened()) this.clearSearch();\n                e.stopImmediatePropagation();\n                this.opts.element.trigger($.Event(\"select2-blur\"));\n            }));\n\n            this.container.on(\"click\", selector, this.bind(function (e) {\n                if (!this.isInterfaceEnabled()) return;\n                if ($(e.target).closest(\".select2-search-choice\").length > 0) {\n                    // clicked inside a select2 search choice, do not open\n                    return;\n                }\n                this.selectChoice(null);\n                this.clearPlaceholder();\n                if (!this.container.hasClass(\"select2-container-active\")) {\n                    this.opts.element.trigger($.Event(\"select2-focus\"));\n                }\n                this.open();\n                this.focusSearch();\n                e.preventDefault();\n            }));\n\n            this.container.on(\"focus\", selector, this.bind(function () {\n                if (!this.isInterfaceEnabled()) return;\n                if (!this.container.hasClass(\"select2-container-active\")) {\n                    this.opts.element.trigger($.Event(\"select2-focus\"));\n                }\n                this.container.addClass(\"select2-container-active\");\n                this.dropdown.addClass(\"select2-drop-active\");\n                this.clearPlaceholder();\n            }));\n\n            this.initContainerWidth();\n            this.opts.element.hide();\n\n            // set the placeholder if necessary\n            this.clearSearch();\n        },\n\n        // multi\n        enableInterface: function() {\n            if (this.parent.enableInterface.apply(this, arguments)) {\n                this.search.prop(\"disabled\", !this.isInterfaceEnabled());\n            }\n        },\n\n        // multi\n        initSelection: function () {\n            var data;\n            if (this.opts.element.val() === \"\" && this.opts.element.text() === \"\") {\n                this.updateSelection([]);\n                this.close();\n                // set the placeholder if necessary\n                this.clearSearch();\n            }\n            if (this.select || this.opts.element.val() !== \"\") {\n                var self = this;\n                this.opts.initSelection.call(null, this.opts.element, function(data){\n                    if (data !== undefined && data !== null) {\n                        self.updateSelection(data);\n                        self.close();\n                        // set the placeholder if necessary\n                        self.clearSearch();\n                    }\n                });\n            }\n        },\n\n        // multi\n        clearSearch: function () {\n            var placeholder = this.getPlaceholder(),\n                maxWidth = this.getMaxSearchWidth();\n\n            if (placeholder !== undefined  && this.getVal().length === 0 && this.search.hasClass(\"select2-focused\") === false) {\n                this.search.val(placeholder).addClass(\"select2-default\");\n                // stretch the search box to full width of the container so as much of the placeholder is visible as possible\n                // we could call this.resizeSearch(), but we do not because that requires a sizer and we do not want to create one so early because of a firefox bug, see #944\n                this.search.width(maxWidth > 0 ? maxWidth : this.container.css(\"width\"));\n            } else {\n                this.search.val(\"\").width(10);\n            }\n        },\n\n        // multi\n        clearPlaceholder: function () {\n            if (this.search.hasClass(\"select2-default\")) {\n                this.search.val(\"\").removeClass(\"select2-default\");\n            }\n        },\n\n        // multi\n        opening: function () {\n            this.clearPlaceholder(); // should be done before super so placeholder is not used to search\n            this.resizeSearch();\n\n            this.parent.opening.apply(this, arguments);\n\n            this.focusSearch();\n\n            // initializes search's value with nextSearchTerm (if defined by user)\n            // ignore nextSearchTerm if the dropdown is opened by the user pressing a letter\n            if(this.search.val() === \"\") {\n                if(this.nextSearchTerm != undefined){\n                    this.search.val(this.nextSearchTerm);\n                    this.search.select();\n                }\n            }\n\n            this.updateResults(true);\n            if (this.opts.shouldFocusInput(this)) {\n                this.search.focus();\n            }\n            this.opts.element.trigger($.Event(\"select2-open\"));\n        },\n\n        // multi\n        close: function () {\n            if (!this.opened()) return;\n            this.parent.close.apply(this, arguments);\n        },\n\n        // multi\n        focus: function () {\n            this.close();\n            this.search.focus();\n        },\n\n        // multi\n        isFocused: function () {\n            return this.search.hasClass(\"select2-focused\");\n        },\n\n        // multi\n        updateSelection: function (data) {\n            var ids = [], filtered = [], self = this;\n\n            // filter out duplicates\n            $(data).each(function () {\n                if (indexOf(self.id(this), ids) < 0) {\n                    ids.push(self.id(this));\n                    filtered.push(this);\n                }\n            });\n            data = filtered;\n\n            this.selection.find(\".select2-search-choice\").remove();\n            $(data).each(function () {\n                self.addSelectedChoice(this);\n            });\n            self.postprocessResults();\n        },\n\n        // multi\n        tokenize: function() {\n            var input = this.search.val();\n            input = this.opts.tokenizer.call(this, input, this.data(), this.bind(this.onSelect), this.opts);\n            if (input != null && input != undefined) {\n                this.search.val(input);\n                if (input.length > 0) {\n                    this.open();\n                }\n            }\n\n        },\n\n        // multi\n        onSelect: function (data, options) {\n\n            if (!this.triggerSelect(data) || data.text === \"\") { return; }\n\n            this.addSelectedChoice(data);\n\n            this.opts.element.trigger({ type: \"selected\", val: this.id(data), choice: data });\n\n            // keep track of the search's value before it gets cleared\n            this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());\n\n            this.clearSearch();\n            this.updateResults();\n\n            if (this.select || !this.opts.closeOnSelect) this.postprocessResults(data, false, this.opts.closeOnSelect===true);\n\n            if (this.opts.closeOnSelect) {\n                this.close();\n                this.search.width(10);\n            } else {\n                if (this.countSelectableResults()>0) {\n                    this.search.width(10);\n                    this.resizeSearch();\n                    if (this.getMaximumSelectionSize() > 0 && this.val().length >= this.getMaximumSelectionSize()) {\n                        // if we reached max selection size repaint the results so choices\n                        // are replaced with the max selection reached message\n                        this.updateResults(true);\n                    } else {\n                        // initializes search's value with nextSearchTerm and update search result\n                        if(this.nextSearchTerm != undefined){\n                            this.search.val(this.nextSearchTerm);\n                            this.updateResults();\n                            this.search.select();\n                        }\n                    }\n                    this.positionDropdown();\n                } else {\n                    // if nothing left to select close\n                    this.close();\n                    this.search.width(10);\n                }\n            }\n\n            // since its not possible to select an element that has already been\n            // added we do not need to check if this is a new element before firing change\n            this.triggerChange({ added: data });\n\n            if (!options || !options.noFocus)\n                this.focusSearch();\n        },\n\n        // multi\n        cancel: function () {\n            this.close();\n            this.focusSearch();\n        },\n\n        addSelectedChoice: function (data) {\n            var enableChoice = !data.locked,\n                enabledItem = $(\n                    \"<li class='select2-search-choice'>\" +\n                    \"    <div></div>\" +\n                    \"    <a href='#' class='select2-search-choice-close' tabindex='-1'></a>\" +\n                    \"</li>\"),\n                disabledItem = $(\n                    \"<li class='select2-search-choice select2-locked'>\" +\n                    \"<div></div>\" +\n                    \"</li>\");\n            var choice = enableChoice ? enabledItem : disabledItem,\n                id = this.id(data),\n                val = this.getVal(),\n                formatted,\n                cssClass;\n\n            formatted=this.opts.formatSelection(data, choice.find(\"div\"), this.opts.escapeMarkup);\n            if (formatted != undefined) {\n                choice.find(\"div\").replaceWith($(\"<div></div>\").html(formatted));\n            }\n            cssClass=this.opts.formatSelectionCssClass(data, choice.find(\"div\"));\n            if (cssClass != undefined) {\n                choice.addClass(cssClass);\n            }\n\n            if(enableChoice){\n              choice.find(\".select2-search-choice-close\")\n                  .on(\"mousedown\", killEvent)\n                  .on(\"click dblclick\", this.bind(function (e) {\n                  if (!this.isInterfaceEnabled()) return;\n\n                  this.unselect($(e.target));\n                  this.selection.find(\".select2-search-choice-focus\").removeClass(\"select2-search-choice-focus\");\n                  killEvent(e);\n                  this.close();\n                  this.focusSearch();\n              })).on(\"focus\", this.bind(function () {\n                  if (!this.isInterfaceEnabled()) return;\n                  this.container.addClass(\"select2-container-active\");\n                  this.dropdown.addClass(\"select2-drop-active\");\n              }));\n            }\n\n            choice.data(\"select2-data\", data);\n            choice.insertBefore(this.searchContainer);\n\n            val.push(id);\n            this.setVal(val);\n        },\n\n        // multi\n        unselect: function (selected) {\n            var val = this.getVal(),\n                data,\n                index;\n            selected = selected.closest(\".select2-search-choice\");\n\n            if (selected.length === 0) {\n                throw \"Invalid argument: \" + selected + \". Must be .select2-search-choice\";\n            }\n\n            data = selected.data(\"select2-data\");\n\n            if (!data) {\n                // prevent a race condition when the 'x' is clicked really fast repeatedly the event can be queued\n                // and invoked on an element already removed\n                return;\n            }\n\n            var evt = $.Event(\"select2-removing\");\n            evt.val = this.id(data);\n            evt.choice = data;\n            this.opts.element.trigger(evt);\n\n            if (evt.isDefaultPrevented()) {\n                return false;\n            }\n\n            while((index = indexOf(this.id(data), val)) >= 0) {\n                val.splice(index, 1);\n                this.setVal(val);\n                if (this.select) this.postprocessResults();\n            }\n\n            selected.remove();\n\n            this.opts.element.trigger({ type: \"select2-removed\", val: this.id(data), choice: data });\n            this.triggerChange({ removed: data });\n\n            return true;\n        },\n\n        // multi\n        postprocessResults: function (data, initial, noHighlightUpdate) {\n            var val = this.getVal(),\n                choices = this.results.find(\".select2-result\"),\n                compound = this.results.find(\".select2-result-with-children\"),\n                self = this;\n\n            choices.each2(function (i, choice) {\n                var id = self.id(choice.data(\"select2-data\"));\n                if (indexOf(id, val) >= 0) {\n                    choice.addClass(\"select2-selected\");\n                    // mark all children of the selected parent as selected\n                    choice.find(\".select2-result-selectable\").addClass(\"select2-selected\");\n                }\n            });\n\n            compound.each2(function(i, choice) {\n                // hide an optgroup if it doesn't have any selectable children\n                if (!choice.is('.select2-result-selectable')\n                    && choice.find(\".select2-result-selectable:not(.select2-selected)\").length === 0) {\n                    choice.addClass(\"select2-selected\");\n                }\n            });\n\n            if (this.highlight() == -1 && noHighlightUpdate !== false && this.opts.closeOnSelect === true){\n                self.highlight(0);\n            }\n\n            //If all results are chosen render formatNoMatches\n            if(!this.opts.createSearchChoice && !choices.filter('.select2-result:not(.select2-selected)').length > 0){\n                if(!data || data && !data.more && this.results.find(\".select2-no-results\").length === 0) {\n                    if (checkFormatter(self.opts.formatNoMatches, \"formatNoMatches\")) {\n                        this.results.append(\"<li class='select2-no-results'>\" + evaluate(self.opts.formatNoMatches, self.opts.element, self.search.val()) + \"</li>\");\n                    }\n                }\n            }\n\n        },\n\n        // multi\n        getMaxSearchWidth: function() {\n            return this.selection.width() - getSideBorderPadding(this.search);\n        },\n\n        // multi\n        resizeSearch: function () {\n            var minimumWidth, left, maxWidth, containerLeft, searchWidth,\n                sideBorderPadding = getSideBorderPadding(this.search);\n\n            minimumWidth = measureTextWidth(this.search) + 10;\n\n            left = this.search.offset().left;\n\n            maxWidth = this.selection.width();\n            containerLeft = this.selection.offset().left;\n\n            searchWidth = maxWidth - (left - containerLeft) - sideBorderPadding;\n\n            if (searchWidth < minimumWidth) {\n                searchWidth = maxWidth - sideBorderPadding;\n            }\n\n            if (searchWidth < 40) {\n                searchWidth = maxWidth - sideBorderPadding;\n            }\n\n            if (searchWidth <= 0) {\n              searchWidth = minimumWidth;\n            }\n\n            this.search.width(Math.floor(searchWidth));\n        },\n\n        // multi\n        getVal: function () {\n            var val;\n            if (this.select) {\n                val = this.select.val();\n                return val === null ? [] : val;\n            } else {\n                val = this.opts.element.val();\n                return splitVal(val, this.opts.separator, this.opts.transformVal);\n            }\n        },\n\n        // multi\n        setVal: function (val) {\n            var unique;\n            if (this.select) {\n                this.select.val(val);\n            } else {\n                unique = [];\n                // filter out duplicates\n                $(val).each(function () {\n                    if (indexOf(this, unique) < 0) unique.push(this);\n                });\n                this.opts.element.val(unique.length === 0 ? \"\" : unique.join(this.opts.separator));\n            }\n        },\n\n        // multi\n        buildChangeDetails: function (old, current) {\n            var current = current.slice(0),\n                old = old.slice(0);\n\n            // remove intersection from each array\n            for (var i = 0; i < current.length; i++) {\n                for (var j = 0; j < old.length; j++) {\n                    if (equal(this.opts.id(current[i]), this.opts.id(old[j]))) {\n                        current.splice(i, 1);\n                        if(i>0){\n                            i--;\n                        }\n                        old.splice(j, 1);\n                        j--;\n                    }\n                }\n            }\n\n            return {added: current, removed: old};\n        },\n\n\n        // multi\n        val: function (val, triggerChange) {\n            var oldData, self=this;\n\n            if (arguments.length === 0) {\n                return this.getVal();\n            }\n\n            oldData=this.data();\n            if (!oldData.length) oldData=[];\n\n            // val is an id. !val is true for [undefined,null,'',0] - 0 is legal\n            if (!val && val !== 0) {\n                this.opts.element.val(\"\");\n                this.updateSelection([]);\n                this.clearSearch();\n                if (triggerChange) {\n                    this.triggerChange({added: this.data(), removed: oldData});\n                }\n                return;\n            }\n\n            // val is a list of ids\n            this.setVal(val);\n\n            if (this.select) {\n                this.opts.initSelection(this.select, this.bind(this.updateSelection));\n                if (triggerChange) {\n                    this.triggerChange(this.buildChangeDetails(oldData, this.data()));\n                }\n            } else {\n                if (this.opts.initSelection === undefined) {\n                    throw new Error(\"val() cannot be called if initSelection() is not defined\");\n                }\n\n                this.opts.initSelection(this.opts.element, function(data){\n                    var ids=$.map(data, self.id);\n                    self.setVal(ids);\n                    self.updateSelection(data);\n                    self.clearSearch();\n                    if (triggerChange) {\n                        self.triggerChange(self.buildChangeDetails(oldData, self.data()));\n                    }\n                });\n            }\n            this.clearSearch();\n        },\n\n        // multi\n        onSortStart: function() {\n            if (this.select) {\n                throw new Error(\"Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.\");\n            }\n\n            // collapse search field into 0 width so its container can be collapsed as well\n            this.search.width(0);\n            // hide the container\n            this.searchContainer.hide();\n        },\n\n        // multi\n        onSortEnd:function() {\n\n            var val=[], self=this;\n\n            // show search and move it to the end of the list\n            this.searchContainer.show();\n            // make sure the search container is the last item in the list\n            this.searchContainer.appendTo(this.searchContainer.parent());\n            // since we collapsed the width in dragStarted, we resize it here\n            this.resizeSearch();\n\n            // update selection\n            this.selection.find(\".select2-search-choice\").each(function() {\n                val.push(self.opts.id($(this).data(\"select2-data\")));\n            });\n            this.setVal(val);\n            this.triggerChange();\n        },\n\n        // multi\n        data: function(values, triggerChange) {\n            var self=this, ids, old;\n            if (arguments.length === 0) {\n                 return this.selection\n                     .children(\".select2-search-choice\")\n                     .map(function() { return $(this).data(\"select2-data\"); })\n                     .get();\n            } else {\n                old = this.data();\n                if (!values) { values = []; }\n                ids = $.map(values, function(e) { return self.opts.id(e); });\n                this.setVal(ids);\n                this.updateSelection(values);\n                this.clearSearch();\n                if (triggerChange) {\n                    this.triggerChange(this.buildChangeDetails(old, this.data()));\n                }\n            }\n        }\n    });\n\n    $.fn.select2 = function () {\n\n        var args = Array.prototype.slice.call(arguments, 0),\n            opts,\n            select2,\n            method, value, multiple,\n            allowedMethods = [\"val\", \"destroy\", \"opened\", \"open\", \"close\", \"focus\", \"isFocused\", \"container\", \"dropdown\", \"onSortStart\", \"onSortEnd\", \"enable\", \"disable\", \"readonly\", \"positionDropdown\", \"data\", \"search\"],\n            valueMethods = [\"opened\", \"isFocused\", \"container\", \"dropdown\"],\n            propertyMethods = [\"val\", \"data\"],\n            methodsMap = { search: \"externalSearch\" };\n\n        this.each(function () {\n            if (args.length === 0 || typeof(args[0]) === \"object\") {\n                opts = args.length === 0 ? {} : $.extend({}, args[0]);\n                opts.element = $(this);\n\n                if (opts.element.get(0).tagName.toLowerCase() === \"select\") {\n                    multiple = opts.element.prop(\"multiple\");\n                } else {\n                    multiple = opts.multiple || false;\n                    if (\"tags\" in opts) {opts.multiple = multiple = true;}\n                }\n\n                select2 = multiple ? new window.Select2[\"class\"].multi() : new window.Select2[\"class\"].single();\n                select2.init(opts);\n            } else if (typeof(args[0]) === \"string\") {\n\n                if (indexOf(args[0], allowedMethods) < 0) {\n                    throw \"Unknown method: \" + args[0];\n                }\n\n                value = undefined;\n                select2 = $(this).data(\"select2\");\n                if (select2 === undefined) return;\n\n                method=args[0];\n\n                if (method === \"container\") {\n                    value = select2.container;\n                } else if (method === \"dropdown\") {\n                    value = select2.dropdown;\n                } else {\n                    if (methodsMap[method]) method = methodsMap[method];\n\n                    value = select2[method].apply(select2, args.slice(1));\n                }\n                if (indexOf(args[0], valueMethods) >= 0\n                    || (indexOf(args[0], propertyMethods) >= 0 && args.length == 1)) {\n                    return false; // abort the iteration, ready to return first matched value\n                }\n            } else {\n                throw \"Invalid arguments to select2 plugin: \" + args;\n            }\n        });\n        return (value === undefined) ? this : value;\n    };\n\n    // plugin defaults, accessible to users\n    $.fn.select2.defaults = {\n        width: \"copy\",\n        loadMorePadding: 0,\n        closeOnSelect: true,\n        openOnEnter: true,\n        containerCss: {},\n        dropdownCss: {},\n        containerCssClass: \"\",\n        dropdownCssClass: \"\",\n        formatResult: function(result, container, query, escapeMarkup) {\n            var markup=[];\n            markMatch(this.text(result), query.term, markup, escapeMarkup);\n            return markup.join(\"\");\n        },\n        transformVal: function(val) {\n            return $.trim(val);\n        },\n        formatSelection: function (data, container, escapeMarkup) {\n            return data ? escapeMarkup(this.text(data)) : undefined;\n        },\n        sortResults: function (results, container, query) {\n            return results;\n        },\n        formatResultCssClass: function(data) {return data.css;},\n        formatSelectionCssClass: function(data, container) {return undefined;},\n        minimumResultsForSearch: 0,\n        minimumInputLength: 0,\n        maximumInputLength: null,\n        maximumSelectionSize: 0,\n        id: function (e) { return e == undefined ? null : e.id; },\n        text: function (e) {\n          if (e && this.data && this.data.text) {\n            if ($.isFunction(this.data.text)) {\n              return this.data.text(e);\n            } else {\n              return e[this.data.text];\n            }\n          } else {\n            return e.text;\n          }\n        },\n        matcher: function(term, text) {\n            return stripDiacritics(''+text).toUpperCase().indexOf(stripDiacritics(''+term).toUpperCase()) >= 0;\n        },\n        separator: \",\",\n        tokenSeparators: [],\n        tokenizer: defaultTokenizer,\n        escapeMarkup: defaultEscapeMarkup,\n        blurOnChange: false,\n        selectOnBlur: false,\n        adaptContainerCssClass: function(c) { return c; },\n        adaptDropdownCssClass: function(c) { return null; },\n        nextSearchTerm: function(selectedObject, currentSearchTerm) { return undefined; },\n        searchInputPlaceholder: '',\n        createSearchChoicePosition: 'top',\n        shouldFocusInput: function (instance) {\n            // Attempt to detect touch devices\n            var supportsTouchEvents = (('ontouchstart' in window) ||\n                                       (navigator.msMaxTouchPoints > 0));\n\n            // Only devices which support touch events should be special cased\n            if (!supportsTouchEvents) {\n                return true;\n            }\n\n            // Never focus the input if search is disabled\n            if (instance.opts.minimumResultsForSearch < 0) {\n                return false;\n            }\n\n            return true;\n        }\n    };\n\n    $.fn.select2.locales = [];\n\n    $.fn.select2.locales['en'] = {\n         formatMatches: function (matches) { if (matches === 1) { return \"One result is available, press enter to select it.\"; } return matches + \" results are available, use up and down arrow keys to navigate.\"; },\n         formatNoMatches: function () { return \"No matches found\"; },\n         formatAjaxError: function (jqXHR, textStatus, errorThrown) { return \"Loading failed\"; },\n         formatInputTooShort: function (input, min) { var n = min - input.length; return \"Please enter \" + n + \" or more character\" + (n == 1 ? \"\" : \"s\"); },\n         formatInputTooLong: function (input, max) { var n = input.length - max; return \"Please delete \" + n + \" character\" + (n == 1 ? \"\" : \"s\"); },\n         formatSelectionTooBig: function (limit) { return \"You can only select \" + limit + \" item\" + (limit == 1 ? \"\" : \"s\"); },\n         formatLoadMore: function (pageNumber) { return \"Loading more results…\"; },\n         formatSearching: function () { return \"Searching…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['en']);\n\n    $.fn.select2.ajaxDefaults = {\n        transport: $.ajax,\n        params: {\n            type: \"GET\",\n            cache: false,\n            dataType: \"json\"\n        }\n    };\n\n    // exports\n    window.Select2 = {\n        query: {\n            ajax: ajax,\n            local: local,\n            tags: tags\n        }, util: {\n            debounce: debounce,\n            markMatch: markMatch,\n            escapeMarkup: defaultEscapeMarkup,\n            stripDiacritics: stripDiacritics\n        }, \"class\": {\n            \"abstract\": AbstractSelect2,\n            \"single\": SingleSelect2,\n            \"multi\": MultiSelect2\n        }\n    };\n\n}(jQuery));\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_ar.js",
    "content": "/**\n * Select2 Arabic translation.\n *\n * Author: Adel KEDJOUR <adel@kedjour.com>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['ar'] = {\n        formatNoMatches: function () { return \"لم يتم العثور على مطابقات\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; if (n == 1){ return \"الرجاء إدخال حرف واحد على الأكثر\"; } return n == 2 ? \"الرجاء إدخال حرفين على الأكثر\" : \"الرجاء إدخال \" + n + \" على الأكثر\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; if (n == 1){ return \"الرجاء إدخال حرف واحد على الأقل\"; } return n == 2 ? \"الرجاء إدخال حرفين على الأقل\" : \"الرجاء إدخال \" + n + \" على الأقل \"; },\n        formatSelectionTooBig: function (limit) { if (limit == 1){ return \"يمكنك أن تختار إختيار واحد فقط\"; } return limit == 2 ? \"يمكنك أن تختار إختيارين فقط\" : \"يمكنك أن تختار \" + limit + \" إختيارات فقط\"; },\n        formatLoadMore: function (pageNumber) { return \"تحميل المزيد من النتائج…\"; },\n        formatSearching: function () { return \"البحث…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['ar']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_az.js",
    "content": "/**\n * Select2 Azerbaijani translation.\n *\n * Author: Farhad Safarov <farhad.safarov@gmail.com>\n */\n(function ($) {\n    \"use strict\";\n\n     $.fn.select2.locales['az'] = {\n        formatMatches: function (matches) { return matches + \" nəticə mövcuddur, hərəkət etdirmək üçün yuxarı və aşağı düymələrindən istifadə edin.\"; },\n        formatNoMatches: function () { return \"Nəticə tapılmadı\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return n + \" simvol daxil edin\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return n + \" simvol silin\"; },\n        formatSelectionTooBig: function (limit) { return \"Sadəcə \" + limit + \" element seçə bilərsiniz\"; },\n        formatLoadMore: function (pageNumber) { return \"Daha çox nəticə yüklənir…\"; },\n        formatSearching: function () { return \"Axtarılır…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['az']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_bg.js",
    "content": "/**\n * Select2 Bulgarian translation.\n * \n * @author  Lubomir Vikev <lubomirvikev@gmail.com>\n * @author  Uriy Efremochkin <efremochkin@uriy.me>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['bg'] = {\n        formatNoMatches: function () { return \"Няма намерени съвпадения\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Моля въведете още \" + n + \" символ\" + (n > 1 ? \"а\" : \"\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Моля въведете с \" + n + \" по-малко символ\" + (n > 1 ? \"а\" : \"\"); },\n        formatSelectionTooBig: function (limit) { return \"Можете да направите до \" + limit + (limit > 1 ? \" избора\" : \" избор\"); },\n        formatLoadMore: function (pageNumber) { return \"Зареждат се още…\"; },\n        formatSearching: function () { return \"Търсене…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['bg']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_ca.js",
    "content": "/**\n * Select2 Catalan translation.\n * \n * Author: David Planella <david.planella@gmail.com>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['ca'] = {\n        formatNoMatches: function () { return \"No s'ha trobat cap coincidència\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Introduïu \" + n + \" caràcter\" + (n == 1 ? \"\" : \"s\") + \" més\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Introduïu \" + n + \" caràcter\" + (n == 1? \"\" : \"s\") + \"menys\"; },\n        formatSelectionTooBig: function (limit) { return \"Només podeu seleccionar \" + limit + \" element\" + (limit == 1 ? \"\" : \"s\"); },\n        formatLoadMore: function (pageNumber) { return \"S'estan carregant més resultats…\"; },\n        formatSearching: function () { return \"S'està cercant…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['ca']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_cs.js",
    "content": "/**\n * Select2 Czech translation.\n * \n * Author: Michal Marek <ahoj@michal-marek.cz>\n * Author - sklonovani: David Vallner <david@vallner.net>\n */\n(function ($) {\n    \"use strict\";\n    // use text for the numbers 2 through 4\n    var smallNumbers = {\n        2: function(masc) { return (masc ? \"dva\" : \"dvě\"); },\n        3: function() { return \"tři\"; },\n        4: function() { return \"čtyři\"; }\n    }\n    $.fn.select2.locales['cs'] = {\n        formatNoMatches: function () { return \"Nenalezeny žádné položky\"; },\n        formatInputTooShort: function (input, min) {\n            var n = min - input.length;\n            if (n == 1) {\n                return \"Prosím zadejte ještě jeden znak\";\n            } else if (n <= 4) {\n                return \"Prosím zadejte ještě další \"+smallNumbers[n](true)+\" znaky\";\n            } else {\n                return \"Prosím zadejte ještě dalších \"+n+\" znaků\";\n            }\n        },\n        formatInputTooLong: function (input, max) {\n            var n = input.length - max;\n            if (n == 1) {\n                return \"Prosím zadejte o jeden znak méně\";\n            } else if (n <= 4) {\n                return \"Prosím zadejte o \"+smallNumbers[n](true)+\" znaky méně\";\n            } else {\n                return \"Prosím zadejte o \"+n+\" znaků méně\";\n            }\n        },\n        formatSelectionTooBig: function (limit) {\n            if (limit == 1) {\n                return \"Můžete zvolit jen jednu položku\";\n            } else if (limit <= 4) {\n                return \"Můžete zvolit maximálně \"+smallNumbers[limit](false)+\" položky\";\n            } else {\n                return \"Můžete zvolit maximálně \"+limit+\" položek\";\n            }\n        },\n        formatLoadMore: function (pageNumber) { return \"Načítají se další výsledky…\"; },\n        formatSearching: function () { return \"Vyhledávání…\"; }\n    };\n\n\t$.extend($.fn.select2.defaults, $.fn.select2.locales['cs']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_da.js",
    "content": "/**\n * Select2 Danish translation.\n *\n * Author: Anders Jenbo <anders@jenbo.dk>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['da'] = {\n        formatNoMatches: function () { return \"Ingen resultater fundet\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Angiv venligst \" + n + \" tegn mere\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Angiv venligst \" + n + \" tegn mindre\"; },\n        formatSelectionTooBig: function (limit) { return \"Du kan kun vælge \" + limit + \" emne\" + (limit === 1 ? \"\" : \"r\"); },\n        formatLoadMore: function (pageNumber) { return \"Indlæser flere resultater…\"; },\n        formatSearching: function () { return \"Søger…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['da']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_de.js",
    "content": "/**\n * Select2 German translation\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['de'] = {\n        formatNoMatches: function () { return \"Keine Übereinstimmungen gefunden\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Bitte \" + n + \" Zeichen mehr eingeben\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Bitte \" + n + \" Zeichen weniger eingeben\"; },\n        formatSelectionTooBig: function (limit) { return \"Sie können nur \" + limit + \" Eintr\" + (limit === 1 ? \"ag\" : \"äge\") + \" auswählen\"; },\n        formatLoadMore: function (pageNumber) { return \"Lade mehr Ergebnisse…\"; },\n        formatSearching: function () { return \"Suche…\"; },\n        formatMatches: function (matches) { return matches + \" Ergebnis \" + (matches > 1 ? \"se\" : \"\") + \" verfügbar, zum Navigieren die Hoch-/Runter-Pfeiltasten verwenden.\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['de']);\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_el.js",
    "content": "/**\n * Select2 Greek translation.\n * \n * @author  Uriy Efremochkin <efremochkin@uriy.me>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['el'] = {\n        formatNoMatches: function () { return \"Δεν βρέθηκαν αποτελέσματα\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Παρακαλούμε εισάγετε \" + n + \" περισσότερο\" + (n > 1 ? \"υς\" : \"\") + \" χαρακτήρ\" + (n > 1 ? \"ες\" : \"α\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Παρακαλούμε διαγράψτε \" + n + \" χαρακτήρ\" + (n > 1 ? \"ες\" : \"α\"); },\n        formatSelectionTooBig: function (limit) { return \"Μπορείτε να επιλέξετε μόνο \" + limit + \" αντικείμεν\" + (limit > 1 ? \"α\" : \"ο\"); },\n        formatLoadMore: function (pageNumber) { return \"Φόρτωση περισσότερων…\"; },\n        formatSearching: function () { return \"Αναζήτηση…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['el']);\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_en.js.template",
    "content": "/**\n * Select2 <Language> translation.\n *\n * Author: Your Name <your@email>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['en'] = {\n        formatMatches: function (matches) { if (matches === 1) { return \"One result is available, press enter to select it.\"; } return matches + \" results are available, use up and down arrow keys to navigate.\"; },\n        formatNoMatches: function () { return \"No matches found\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Please enter \" + n + \" or more character\" + (n == 1 ? \"\" : \"s\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Please delete \" + n + \" character\" + (n == 1 ? \"\" : \"s\"); },\n        formatSelectionTooBig: function (limit) { return \"You can only select \" + limit + \" item\" + (limit == 1 ? \"\" : \"s\"); },\n        formatLoadMore: function (pageNumber) { return \"Loading more results…\"; },\n        formatSearching: function () { return \"Searching…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['en']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_es.js",
    "content": "/**\n * Select2 Spanish translation\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['es'] = {\n    \tformatMatches: function (matches) { if (matches === 1) { return \"Un resultado disponible, presione enter para seleccionarlo.\"; } return matches + \" resultados disponibles, use las teclas de dirección para navegar.\"; },\n        formatNoMatches: function () { return \"No se encontraron resultados\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Por favor, introduzca \" + n + \" car\" + (n == 1? \"ácter\" : \"acteres\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Por favor, elimine \" + n + \" car\" + (n == 1? \"ácter\" : \"acteres\"); },\n        formatSelectionTooBig: function (limit) { return \"Sólo puede seleccionar \" + limit + \" elemento\" + (limit == 1 ? \"\" : \"s\"); },\n        formatLoadMore: function (pageNumber) { return \"Cargando más resultados…\"; },\n        formatSearching: function () { return \"Buscando…\"; },\n        formatAjaxError: function() { return \"La carga falló\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['es']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_et.js",
    "content": "/**\n * Select2 Estonian translation.\n *\n * Author: Kuldar Kalvik <kuldar@kalvik.ee>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['et'] = {\n        formatNoMatches: function () { return \"Tulemused puuduvad\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Sisesta \" + n + \" täht\" + (n == 1 ? \"\" : \"e\") + \" rohkem\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Sisesta \" + n + \" täht\" + (n == 1? \"\" : \"e\") + \" vähem\"; },\n        formatSelectionTooBig: function (limit) { return \"Saad vaid \" + limit + \" tulemus\" + (limit == 1 ? \"e\" : \"t\") + \" valida\"; },\n        formatLoadMore: function (pageNumber) { return \"Laen tulemusi..\"; },\n        formatSearching: function () { return \"Otsin..\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['et']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_eu.js",
    "content": "/**\n * Select2 Basque translation.\n *\n * Author: Julen Ruiz Aizpuru <julenx at gmail dot com>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['eu'] = {\n        formatNoMatches: function () {\n          return \"Ez da bat datorrenik aurkitu\";\n        },\n        formatInputTooShort: function (input, min) {\n          var n = min - input.length;\n          if (n === 1) {\n            return \"Idatzi karaktere bat gehiago\";\n          } else {\n            return \"Idatzi \" + n + \" karaktere gehiago\";\n          }\n        },\n        formatInputTooLong: function (input, max) {\n          var n = input.length - max;\n          if (n === 1) {\n            return \"Idatzi karaktere bat gutxiago\";\n          } else {\n            return \"Idatzi \" + n + \" karaktere gutxiago\";\n          }\n        },\n        formatSelectionTooBig: function (limit) {\n          if (limit === 1 ) {\n            return \"Elementu bakarra hauta dezakezu\";\n          } else {\n            return limit + \" elementu hauta ditzakezu soilik\";\n          }\n        },\n        formatLoadMore: function (pageNumber) {\n          return \"Emaitza gehiago kargatzen…\";\n        },\n        formatSearching: function () {\n          return \"Bilatzen…\";\n        }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['eu']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_fa.js",
    "content": "/**\n * Select2 Persian translation.\n * \n * Author: Ali Choopan <choopan@arsh.co>\n * Author: Ebrahim Byagowi <ebrahim@gnu.org>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['fa'] = {\n        formatMatches: function (matches) { return matches + \" نتیجه موجود است، کلیدهای جهت بالا و پایین را برای گشتن استفاده کنید.\"; },\n        formatNoMatches: function () { return \"نتیجه‌ای یافت نشد.\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"لطفاً \" + n + \" نویسه بیشتر وارد نمایید\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"لطفاً \" + n + \" نویسه را حذف کنید.\"; },\n        formatSelectionTooBig: function (limit) { return \"شما فقط می‌توانید \" + limit + \" مورد را انتخاب کنید\"; },\n        formatLoadMore: function (pageNumber) { return \"در حال بارگیری موارد بیشتر…\"; },\n        formatSearching: function () { return \"در حال جستجو…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['fa']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_fi.js",
    "content": "/**\n * Select2 Finnish translation\n */\n(function ($) {\n    \"use strict\";\n    $.fn.select2.locales['fi'] = {\n        formatNoMatches: function () {\n            return \"Ei tuloksia\";\n        },\n        formatInputTooShort: function (input, min) {\n            var n = min - input.length;\n            return \"Ole hyvä ja anna \" + n + \" merkkiä lisää\";\n        },\n        formatInputTooLong: function (input, max) {\n            var n = input.length - max;\n            return \"Ole hyvä ja anna \" + n + \" merkkiä vähemmän\";\n        },\n        formatSelectionTooBig: function (limit) {\n            return \"Voit valita ainoastaan \" + limit + \" kpl\";\n        },\n        formatLoadMore: function (pageNumber) {\n            return \"Ladataan lisää tuloksia…\";\n        },\n        formatSearching: function () {\n            return \"Etsitään…\";\n        }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['fi']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_fr.js",
    "content": "/**\n * Select2 French translation\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['fr'] = {\n        formatMatches: function (matches) { return matches + \" résultats sont disponibles, utilisez les flèches haut et bas pour naviguer.\"; },\n        formatNoMatches: function () { return \"Aucun résultat trouvé\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Saisissez \" + n + \" caractère\" + (n == 1? \"\" : \"s\") + \" supplémentaire\" + (n == 1? \"\" : \"s\") ; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Supprimez \" + n + \" caractère\" + (n == 1? \"\" : \"s\"); },\n        formatSelectionTooBig: function (limit) { return \"Vous pouvez seulement sélectionner \" + limit + \" élément\" + (limit == 1 ? \"\" : \"s\"); },\n        formatLoadMore: function (pageNumber) { return \"Chargement de résultats supplémentaires…\"; },\n        formatSearching: function () { return \"Recherche en cours…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['fr']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_gl.js",
    "content": "/**\n * Select2 Galician translation\n * \n * Author: Leandro Regueiro <leandro.regueiro@gmail.com>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['gl'] = {\n        formatNoMatches: function () {\n            return \"Non se atoparon resultados\";\n        },\n        formatInputTooShort: function (input, min) {\n            var n = min - input.length;\n            if (n === 1) {\n                return \"Engada un carácter\";\n            } else {\n                return \"Engada \" + n + \" caracteres\";\n            }\n        },\n        formatInputTooLong: function (input, max) {\n            var n = input.length - max;\n            if (n === 1) {\n                return \"Elimine un carácter\";\n            } else {\n                return \"Elimine \" + n + \" caracteres\";\n            }\n        },\n        formatSelectionTooBig: function (limit) {\n            if (limit === 1 ) {\n                return \"Só pode seleccionar un elemento\";\n            } else {\n                return \"Só pode seleccionar \" + limit + \" elementos\";\n            }\n        },\n        formatLoadMore: function (pageNumber) {\n            return \"Cargando máis resultados…\";\n        },\n        formatSearching: function () {\n            return \"Buscando…\";\n        }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['gl']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_he.js",
    "content": "/**\n* Select2 Hebrew translation.\n*\n* Author: Yakir Sitbon <http://www.yakirs.net/>\n*/\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['he'] = {\n        formatNoMatches: function () { return \"לא נמצאו התאמות\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"נא להזין עוד \" + n + \" תווים נוספים\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"נא להזין פחות \" + n + \" תווים\"; },\n        formatSelectionTooBig: function (limit) { return \"ניתן לבחור \" + limit + \" פריטים\"; },\n        formatLoadMore: function (pageNumber) { return \"טוען תוצאות נוספות…\"; },\n        formatSearching: function () { return \"מחפש…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['he']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_hr.js",
    "content": "/**\n * Select2 Croatian translation.\n *\n * @author  Edi Modrić <edi.modric@gmail.com>\n * @author  Uriy Efremochkin <efremochkin@uriy.me>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['hr'] = {\n        formatNoMatches: function () { return \"Nema rezultata\"; },\n        formatInputTooShort: function (input, min) { return \"Unesite još\" + character(min - input.length); },\n        formatInputTooLong: function (input, max) { return \"Unesite\" + character(input.length - max) + \" manje\"; },\n        formatSelectionTooBig: function (limit) { return \"Maksimalan broj odabranih stavki je \" + limit; },\n        formatLoadMore: function (pageNumber) { return \"Učitavanje rezultata…\"; },\n        formatSearching: function () { return \"Pretraga…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['hr']);\n\n    function character (n) {\n        return \" \" + n + \" znak\" + (n%10 < 5 && n%10 > 0 && (n%100 < 5 || n%100 > 19) ? n%10 > 1 ? \"a\" : \"\" : \"ova\");\n    }\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_hu.js",
    "content": "/**\n * Select2 Hungarian translation\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['hu'] = {\n        formatNoMatches: function () { return \"Nincs találat.\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Túl rövid. Még \" + n + \" karakter hiányzik.\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Túl hosszú. \" + n + \" karakterrel több, mint kellene.\"; },\n        formatSelectionTooBig: function (limit) { return \"Csak \" + limit + \" elemet lehet kiválasztani.\"; },\n        formatLoadMore: function (pageNumber) { return \"Töltés…\"; },\n        formatSearching: function () { return \"Keresés…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['hu']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_id.js",
    "content": "/**\n * Select2 Indonesian translation.\n * \n * Author: Ibrahim Yusuf <ibrahim7usuf@gmail.com>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['id'] = {\n        formatNoMatches: function () { return \"Tidak ada data yang sesuai\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Masukkan \" + n + \" huruf lagi\" + (n == 1 ? \"\" : \"s\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Hapus \" + n + \" huruf\" + (n == 1 ? \"\" : \"s\"); },\n        formatSelectionTooBig: function (limit) { return \"Anda hanya dapat memilih \" + limit + \" pilihan\" + (limit == 1 ? \"\" : \"s\"); },\n        formatLoadMore: function (pageNumber) { return \"Mengambil data…\"; },\n        formatSearching: function () { return \"Mencari…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['id']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_is.js",
    "content": "/**\n * Select2 Icelandic translation.\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['is'] = {\n        formatNoMatches: function () { return \"Ekkert fannst\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Vinsamlegast skrifið \" + n + \" staf\" + (n > 1 ? \"i\" : \"\") + \" í viðbót\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Vinsamlegast styttið texta um \" + n + \" staf\" + (n > 1 ? \"i\" : \"\"); },\n        formatSelectionTooBig: function (limit) { return \"Þú getur aðeins valið \" + limit + \" atriði\"; },\n        formatLoadMore: function (pageNumber) { return \"Sæki fleiri niðurstöður…\"; },\n        formatSearching: function () { return \"Leita…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['is']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_it.js",
    "content": "/**\n * Select2 Italian translation\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['it'] = {\n        formatNoMatches: function () { return \"Nessuna corrispondenza trovata\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Inserisci ancora \" + n + \" caratter\" + (n == 1? \"e\" : \"i\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Inserisci \" + n + \" caratter\" + (n == 1? \"e\" : \"i\") + \" in meno\"; },\n        formatSelectionTooBig: function (limit) { return \"Puoi selezionare solo \" + limit + \" element\" + (limit == 1 ? \"o\" : \"i\"); },\n        formatLoadMore: function (pageNumber) { return \"Caricamento in corso…\"; },\n        formatSearching: function () { return \"Ricerca…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['it']);\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_ja.js",
    "content": "/**\n * Select2 Japanese translation.\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['ja'] = {\n        formatNoMatches: function () { return \"該当なし\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"後\" + n + \"文字入れてください\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"検索文字列が\" + n + \"文字長すぎます\"; },\n        formatSelectionTooBig: function (limit) { return \"最多で\" + limit + \"項目までしか選択できません\"; },\n        formatLoadMore: function (pageNumber) { return \"読込中･･･\"; },\n        formatSearching: function () { return \"検索中･･･\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['ja']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_ka.js",
    "content": "/**\n * Select2 Georgian (Kartuli) translation.\n * \n * Author: Dimitri Kurashvili dimakura@gmail.com\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['ka'] = {\n        formatNoMatches: function () { return \"ვერ მოიძებნა\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"გთხოვთ შეიყვანოთ კიდევ \" + n + \" სიმბოლო\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"გთხოვთ წაშალოთ \" + n + \" სიმბოლო\"; },\n        formatSelectionTooBig: function (limit) { return \"თქვენ შეგიძლიათ მხოლოდ \" + limit + \" ჩანაწერის მონიშვნა\"; },\n        formatLoadMore: function (pageNumber) { return \"შედეგის ჩატვირთვა…\"; },\n        formatSearching: function () { return \"ძებნა…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['ka']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_ko.js",
    "content": "/**\n * Select2 Korean translation.\n * \n * @author  Swen Mun <longfinfunnel@gmail.com>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['ko'] = {\n        formatNoMatches: function () { return \"결과 없음\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"너무 짧습니다. \"+n+\"글자 더 입력해주세요.\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"너무 깁니다. \"+n+\"글자 지워주세요.\"; },\n        formatSelectionTooBig: function (limit) { return \"최대 \"+limit+\"개까지만 선택하실 수 있습니다.\"; },\n        formatLoadMore: function (pageNumber) { return \"불러오는 중…\"; },\n        formatSearching: function () { return \"검색 중…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['ko']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_lt.js",
    "content": "/**\n * Select2 Lithuanian translation.\n * \n * @author  CRONUS Karmalakas <cronus dot karmalakas at gmail dot com>\n * @author  Uriy Efremochkin <efremochkin@uriy.me>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['lt'] = {\n        formatNoMatches: function () { return \"Atitikmenų nerasta\"; },\n        formatInputTooShort: function (input, min) { return \"Įrašykite dar\" + character(min - input.length); },\n        formatInputTooLong: function (input, max) { return \"Pašalinkite\" + character(input.length - max); },\n        formatSelectionTooBig: function (limit) {\n        \treturn \"Jūs galite pasirinkti tik \" + limit + \" element\" + ((limit%100 > 9 && limit%100 < 21) || limit%10 == 0 ? \"ų\" : limit%10 > 1 ? \"us\" : \"ą\");\n        },\n        formatLoadMore: function (pageNumber) { return \"Kraunama daugiau rezultatų…\"; },\n        formatSearching: function () { return \"Ieškoma…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['lt']);\n\n    function character (n) {\n        return \" \" + n + \" simbol\" + ((n%100 > 9 && n%100 < 21) || n%10 == 0 ? \"ių\" : n%10 > 1 ? \"ius\" : \"į\");\n    }\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_lv.js",
    "content": "/**\n * Select2 Latvian translation.\n *\n * @author  Uriy Efremochkin <efremochkin@uriy.me>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['lv'] = {\n        formatNoMatches: function () { return \"Sakritību nav\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Lūdzu ievadiet vēl \" + n + \" simbol\" + (n == 11 ? \"us\" : n%10 == 1 ? \"u\" : \"us\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Lūdzu ievadiet par \" + n + \" simbol\" + (n == 11 ? \"iem\" : n%10 == 1 ? \"u\" : \"iem\") + \" mazāk\"; },\n        formatSelectionTooBig: function (limit) { return \"Jūs varat izvēlēties ne vairāk kā \" + limit + \" element\" + (limit == 11 ? \"us\" : limit%10 == 1 ? \"u\" : \"us\"); },\n        formatLoadMore: function (pageNumber) { return \"Datu ielāde…\"; },\n        formatSearching: function () { return \"Meklēšana…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['lv']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_mk.js",
    "content": "/**\n * Select2 Macedonian translation.\n * \n * Author: Marko Aleksic <psybaron@gmail.com>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['mk'] = {\n        formatNoMatches: function () { return \"Нема пронајдено совпаѓања\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Ве молиме внесете уште \" + n + \" карактер\" + (n == 1 ? \"\" : \"и\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Ве молиме внесете \" + n + \" помалку карактер\" + (n == 1? \"\" : \"и\"); },\n        formatSelectionTooBig: function (limit) { return \"Можете да изберете само \" + limit + \" ставк\" + (limit == 1 ? \"а\" : \"и\"); },\n        formatLoadMore: function (pageNumber) { return \"Вчитување резултати…\"; },\n        formatSearching: function () { return \"Пребарување…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['mk']);\n})(jQuery);"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_ms.js",
    "content": "/**\n * Select2 Malay translation.\n * \n * Author: Kepoweran <kepoweran@gmail.com>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['ms'] = {\n        formatNoMatches: function () { return \"Tiada padanan yang ditemui\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Sila masukkan \" + n + \" aksara lagi\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Sila hapuskan \" + n + \" aksara\"; },\n        formatSelectionTooBig: function (limit) { return \"Anda hanya boleh memilih \" + limit + \" pilihan\"; },\n        formatLoadMore: function (pageNumber) { return \"Sedang memuatkan keputusan…\"; },\n        formatSearching: function () { return \"Mencari…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['ms']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_nb.js",
    "content": "/**\n * Select2 Norwegian Bokmål translation.\n *\n * Author: Torgeir Veimo <torgeir.veimo@gmail.com>\n * Author: Bjørn Johansen <post@bjornjohansen.no>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['nb'] = {\n        formatMatches: function (matches) { if (matches === 1) { return \"Ett resultat er tilgjengelig, trykk enter for å velge det.\"; } return matches + \" resultater er tilgjengelig. Bruk piltastene opp og ned for å navigere.\"; },\n        formatNoMatches: function () { return \"Ingen treff\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Vennligst skriv inn \" + n + (n>1 ? \" flere tegn\" : \" tegn til\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Vennligst fjern \" + n + \" tegn\"; },\n        formatSelectionTooBig: function (limit) { return \"Du kan velge maks \" + limit + \" elementer\"; },\n        formatLoadMore: function (pageNumber) { return \"Laster flere resultater …\"; },\n        formatSearching: function () { return \"Søker …\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['no']);\n})(jQuery);\n\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_nl.js",
    "content": "/**\n * Select2 Dutch translation\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['nl'] = {\n        formatNoMatches: function () { return \"Geen resultaten gevonden\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Vul nog \" + n + \" karakter\" + (n == 1? \"\" : \"s\") + \" in\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Haal \" + n + \" karakter\" + (n == 1? \"\" : \"s\") + \" weg\"; },\n        formatSelectionTooBig: function (limit) { return \"Maximaal \" + limit + \" item\" + (limit == 1 ? \"\" : \"s\") + \" toegestaan\"; },\n        formatLoadMore: function (pageNumber) { return \"Meer resultaten laden…\"; },\n        formatSearching: function () { return \"Zoeken…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['nl']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_pl.js",
    "content": "/**\n * Select2 Polish translation.\n *\n * @author  Jan Kondratowicz <jan@kondratowicz.pl>\n * @author  Uriy Efremochkin <efremochkin@uriy.me>\n * @author  Michał Połtyn <mike@poltyn.com>\n * @author  Damian Zajkowski <damian.zajkowski@gmail.com>\n */\n(function($) {\n    \"use strict\";\n\n    $.fn.select2.locales['pl'] = {\n        formatNoMatches: function() {\n            return \"Brak wyników\";\n        },\n        formatInputTooShort: function(input, min) {\n            return \"Wpisz co najmniej\" + character(min - input.length, \"znak\", \"i\");\n        },\n        formatInputTooLong: function(input, max) {\n            return \"Wpisana fraza jest za długa o\" + character(input.length - max, \"znak\", \"i\");\n        },\n        formatSelectionTooBig: function(limit) {\n            return \"Możesz zaznaczyć najwyżej\" + character(limit, \"element\", \"y\");\n        },\n        formatLoadMore: function(pageNumber) {\n            return \"Ładowanie wyników…\";\n        },\n        formatSearching: function() {\n            return \"Szukanie…\";\n        }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['pl']);\n\n    function character(n, word, pluralSuffix) {\n        //Liczba pojedyncza - brak suffiksu\n        //jeden znak\n        //jeden element\n        var suffix = '';\n        if (n > 1 && n < 5) {\n            //Liczaba mnoga ilość od 2 do 4 - własny suffiks\n            //Dwa znaki, trzy znaki, cztery znaki.\n            //Dwa elementy, trzy elementy, cztery elementy\n            suffix = pluralSuffix;\n        } else if (n == 0 || n >= 5) {\n            //Ilość 0 suffiks ów\n            //Liczaba mnoga w ilości 5 i więcej - suffiks ów (nie poprawny dla wszystkich wyrazów, np. 100 wiadomości)\n            //Zero znaków, Pięć znaków, sześć znaków, siedem znaków, osiem znaków.\n            //Zero elementów Pięć elementów, sześć elementów, siedem elementów, osiem elementów.\n            suffix = 'ów';\n        }\n        return \" \" + n + \" \" + word + suffix;\n    }\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_pt-BR.js",
    "content": "/**\n * Select2 Brazilian Portuguese translation\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['pt-BR'] = {\n        formatNoMatches: function () { return \"Nenhum resultado encontrado\"; },\n        formatAjaxError: function () { return \"Erro na busca\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Digite \" + (min == 1 ? \"\" : \"mais\") + \" \" + n + \" caracter\" + (n == 1? \"\" : \"es\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Apague \" + n + \" caracter\" + (n == 1? \"\" : \"es\"); },\n        formatSelectionTooBig: function (limit) { return \"Só é possível selecionar \" + limit + \" elemento\" + (limit == 1 ? \"\" : \"s\"); },\n        formatLoadMore: function (pageNumber) { return \"Carregando mais resultados…\"; },\n        formatSearching: function () { return \"Buscando…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['pt-BR']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_pt-PT.js",
    "content": "/**\n * Select2 Portuguese (Portugal) translation\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['pt-PT'] = {\n        formatNoMatches: function () { return \"Nenhum resultado encontrado\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Introduza \" + n + \" car\" + (n == 1 ? \"ácter\" : \"acteres\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Apague \" + n + \" car\" + (n == 1 ? \"ácter\" : \"acteres\"); },\n        formatSelectionTooBig: function (limit) { return \"Só é possível selecionar \" + limit + \" elemento\" + (limit == 1 ? \"\" : \"s\"); },\n        formatLoadMore: function (pageNumber) { return \"A carregar mais resultados…\"; },\n        formatSearching: function () { return \"A pesquisar…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['pt-PT']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_ro.js",
    "content": "/**\n * Select2 Romanian translation.\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['ro'] = {\n        formatNoMatches: function () { return \"Nu a fost găsit nimic\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Vă rugăm să introduceți incă \" + n + \" caracter\" + (n == 1 ? \"\" : \"e\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Vă rugăm să introduceți mai puțin de \" + n + \" caracter\" + (n == 1? \"\" : \"e\"); },\n        formatSelectionTooBig: function (limit) { return \"Aveți voie să selectați cel mult \" + limit + \" element\" + (limit == 1 ? \"\" : \"e\"); },\n        formatLoadMore: function (pageNumber) { return \"Se încarcă…\"; },\n        formatSearching: function () { return \"Căutare…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['ro']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_rs.js",
    "content": "/**\n * Select2 Serbian translation.\n *\n * @author  Limon Monte <limon.monte@gmail.com>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['rs'] = {\n        formatNoMatches: function () { return \"Ništa nije pronađeno\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Ukucajte bar još \" + n + \" simbol\" + (n % 10 == 1 && n % 100 != 11 ? \"\" : \"a\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Obrišite \" + n + \" simbol\" + (n % 10 == 1 && n % 100 != 11\t ? \"\" : \"a\"); },\n        formatSelectionTooBig: function (limit) { return \"Možete izabrati samo \" + limit + \" stavk\" + (limit % 10 == 1 && limit % 100 != 11\t ? \"u\" : (limit % 10 >= 2 && limit % 10 <= 4 && (limit % 100 < 12 || limit % 100 > 14)? \"e\" : \"i\")); },\n        formatLoadMore: function (pageNumber) { return \"Preuzimanje još rezultata…\"; },\n        formatSearching: function () { return \"Pretraga…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['rs']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_ru.js",
    "content": "/**\n * Select2 Russian translation.\n *\n * @author  Uriy Efremochkin <efremochkin@uriy.me>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['ru'] = {\n        formatNoMatches: function () { return \"Совпадений не найдено\"; },\n        formatInputTooShort: function (input, min) { return \"Пожалуйста, введите еще хотя бы\" + character(min - input.length); },\n        formatInputTooLong: function (input, max) { return \"Пожалуйста, введите на\" + character(input.length - max) + \" меньше\"; },\n        formatSelectionTooBig: function (limit) { return \"Вы можете выбрать не более \" + limit + \" элемент\" + (limit%10 == 1 && limit%100 != 11 ? \"а\" : \"ов\"); },\n        formatLoadMore: function (pageNumber) { return \"Загрузка данных…\"; },\n        formatSearching: function () { return \"Поиск…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['ru']);\n\n    function character (n) {\n        return \" \" + n + \" символ\" + (n%10 < 5 && n%10 > 0 && (n%100 < 5 || n%100 > 20) ? n%10 > 1 ? \"a\" : \"\" : \"ов\");\n    }\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_sk.js",
    "content": "/**\n * Select2 Slovak translation.\n *\n * Author: David Vallner <david@vallner.net>\n */\n(function ($) {\n    \"use strict\";\n    // use text for the numbers 2 through 4\n    var smallNumbers = {\n        2: function(masc) { return (masc ? \"dva\" : \"dve\"); },\n        3: function() { return \"tri\"; },\n        4: function() { return \"štyri\"; }\n    };\n    $.fn.select2.locales['sk'] = {\n        formatNoMatches: function () { return \"Nenašli sa žiadne položky\"; },\n        formatInputTooShort: function (input, min) {\n            var n = min - input.length;\n            if (n == 1) {\n                return \"Prosím, zadajte ešte jeden znak\";\n            } else if (n <= 4) {\n                return \"Prosím, zadajte ešte ďalšie \"+smallNumbers[n](true)+\" znaky\";\n            } else {\n                return \"Prosím, zadajte ešte ďalších \"+n+\" znakov\";\n            }\n        },\n        formatInputTooLong: function (input, max) {\n            var n = input.length - max;\n            if (n == 1) {\n                return \"Prosím, zadajte o jeden znak menej\";\n            } else if (n >= 2 && n <= 4) {\n                return \"Prosím, zadajte o \"+smallNumbers[n](true)+\" znaky menej\";\n            } else {\n                return \"Prosím, zadajte o \"+n+\" znakov menej\";\n            }\n        },\n        formatSelectionTooBig: function (limit) {\n            if (limit == 1) {\n                return \"Môžete zvoliť len jednu položku\";\n            } else if (limit >= 2 && limit <= 4) {\n                return \"Môžete zvoliť najviac \"+smallNumbers[limit](false)+\" položky\";\n            } else {\n                return \"Môžete zvoliť najviac \"+limit+\" položiek\";\n            }\n        },\n        formatLoadMore: function (pageNumber) { return \"Načítavajú sa ďalšie výsledky…\"; },\n        formatSearching: function () { return \"Vyhľadávanie…\"; }\n    };\n\n\t$.extend($.fn.select2.defaults, $.fn.select2.locales['sk']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_sv.js",
    "content": "/**\n * Select2 Swedish translation.\n *\n * Author: Jens Rantil <jens.rantil@telavox.com>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['sv'] = {\n        formatNoMatches: function () { return \"Inga träffar\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Var god skriv in \" + n + (n>1 ? \" till tecken\" : \" tecken till\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Var god sudda ut \" + n + \" tecken\"; },\n        formatSelectionTooBig: function (limit) { return \"Du kan max välja \" + limit + \" element\"; },\n        formatLoadMore: function (pageNumber) { return \"Laddar fler resultat…\"; },\n        formatSearching: function () { return \"Söker…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['sv']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_th.js",
    "content": "/**\n * Select2 Thai translation.\n *\n * Author: Atsawin Chaowanakritsanakul <joke@nakhon.net>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['th'] = {\n        formatNoMatches: function () { return \"ไม่พบข้อมูล\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"โปรดพิมพ์เพิ่มอีก \" + n + \" ตัวอักษร\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"โปรดลบออก \" + n + \" ตัวอักษร\"; },\n        formatSelectionTooBig: function (limit) { return \"คุณสามารถเลือกได้ไม่เกิน \" + limit + \" รายการ\"; },\n        formatLoadMore: function (pageNumber) { return \"กำลังค้นข้อมูลเพิ่ม…\"; },\n        formatSearching: function () { return \"กำลังค้นข้อมูล…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['th']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_tr.js",
    "content": "/**\n * Select2 Turkish translation.\n * \n * Author: Salim KAYABAŞI <salim.kayabasi@gmail.com>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['tr'] = {\n        formatNoMatches: function () { return \"Sonuç bulunamadı\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"En az \" + n + \" karakter daha girmelisiniz\"; },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return n + \" karakter azaltmalısınız\"; },\n        formatSelectionTooBig: function (limit) { return \"Sadece \" + limit + \" seçim yapabilirsiniz\"; },\n        formatLoadMore: function (pageNumber) { return \"Daha fazla…\"; },\n        formatSearching: function () { return \"Aranıyor…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['tr']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_ug-CN.js",
    "content": "/**\n * Select2 Uyghur translation\n */\n(function ($) {\n    \"use strict\";\n    $.fn.select2.locales['ug-CN'] = {\n        formatNoMatches: function () { return \"ماس كېلىدىغان ئۇچۇر تېپىلمىدى\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"يەنە \" + n + \" ھەرپ كىرگۈزۈڭ\";},\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"\" + n + \"ھەرپ ئۆچۈرۈڭ\";},\n        formatSelectionTooBig: function (limit) { return \"ئەڭ كۆپ بولغاندا\" + limit + \" تال ئۇچۇر تاللىيالايسىز\"; },\n        formatLoadMore: function (pageNumber) { return \"ئۇچۇرلار ئوقۇلىۋاتىدۇ…\"; },\n        formatSearching: function () { return \"ئىزدەۋاتىدۇ…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['ug-CN']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_uk.js",
    "content": "/**\n * Select2 Ukrainian translation.\n * \n * @author  bigmihail <bigmihail@bigmir.net>\n * @author  Uriy Efremochkin <efremochkin@uriy.me>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['uk'] = {\n        formatMatches: function (matches) { return character(matches, \"результат\") + \" знайдено, використовуйте клавіші зі стрілками вверх та вниз для навігації.\"; },\n        formatNoMatches: function () { return \"Нічого не знайдено\"; },\n        formatInputTooShort: function (input, min) { return \"Введіть буль ласка ще \" + character(min - input.length, \"символ\"); },\n        formatInputTooLong: function (input, max) { return \"Введіть буль ласка на \" + character(input.length - max, \"символ\") + \" менше\"; },\n        formatSelectionTooBig: function (limit) { return \"Ви можете вибрати лише \" + character(limit, \"елемент\"); },\n        formatLoadMore: function (pageNumber) { return \"Завантаження даних…\"; },\n        formatSearching: function () { return \"Пошук…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['uk']);\n\n    function character (n, word) {\n        return n + \" \" + word + (n%10 < 5 && n%10 > 0 && (n%100 < 5 || n%100 > 19) ? n%10 > 1 ? \"и\" : \"\" : \"ів\");\n    }\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_vi.js",
    "content": "/**\n * Select2 Vietnamese translation.\n * \n * Author: Long Nguyen <olragon@gmail.com>\n */\n(function ($) {\n    \"use strict\";\n\n    $.fn.select2.locales['vi'] = {\n        formatNoMatches: function () { return \"Không tìm thấy kết quả\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"Vui lòng nhập nhiều hơn \" + n + \" ký tự\" + (n == 1 ? \"\" : \"s\"); },\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"Vui lòng nhập ít hơn \" + n + \" ký tự\" + (n == 1? \"\" : \"s\"); },\n        formatSelectionTooBig: function (limit) { return \"Chỉ có thể chọn được \" + limit + \" tùy chọn\" + (limit == 1 ? \"\" : \"s\"); },\n        formatLoadMore: function (pageNumber) { return \"Đang lấy thêm kết quả…\"; },\n        formatSearching: function () { return \"Đang tìm…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['vi']);\n})(jQuery);\n\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_zh-CN.js",
    "content": "/**\n * Select2 Chinese translation\n */\n(function ($) {\n    \"use strict\";\n    $.fn.select2.locales['zh-CN'] = {\n        formatNoMatches: function () { return \"没有找到匹配项\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"请再输入\" + n + \"个字符\";},\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"请删掉\" + n + \"个字符\";},\n        formatSelectionTooBig: function (limit) { return \"你只能选择最多\" + limit + \"项\"; },\n        formatLoadMore: function (pageNumber) { return \"加载结果中…\"; },\n        formatSearching: function () { return \"搜索中…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['zh-CN']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/select2/select2_locale_zh-TW.js",
    "content": "/**\n * Select2 Traditional Chinese translation\n */\n(function ($) {\n    \"use strict\";\n    $.fn.select2.locales['zh-TW'] = {\n        formatNoMatches: function () { return \"沒有找到相符的項目\"; },\n        formatInputTooShort: function (input, min) { var n = min - input.length; return \"請再輸入\" + n + \"個字元\";},\n        formatInputTooLong: function (input, max) { var n = input.length - max; return \"請刪掉\" + n + \"個字元\";},\n        formatSelectionTooBig: function (limit) { return \"你只能選擇最多\" + limit + \"項\"; },\n        formatLoadMore: function (pageNumber) { return \"載入中…\"; },\n        formatSearching: function () { return \"搜尋中…\"; }\n    };\n\n    $.extend($.fn.select2.defaults, $.fn.select2.locales['zh-TW']);\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/dist/summernote-bs3.css",
    "content": ".note-editor {\n  /*! normalize.css v2.1.3 | MIT License | git.io/normalize */\n\n}\n.note-editor article,\n.note-editor aside,\n.note-editor details,\n.note-editor figcaption,\n.note-editor figure,\n.note-editor footer,\n.note-editor header,\n.note-editor hgroup,\n.note-editor main,\n.note-editor nav,\n.note-editor section,\n.note-editor summary {\n  display: block;\n}\n.note-editor audio,\n.note-editor canvas,\n.note-editor video {\n  display: inline-block;\n}\n.note-editor audio:not([controls]) {\n  display: none;\n  height: 0;\n}\n.note-editor [hidden],\n.note-editor template {\n  display: none;\n}\n.note-editor html {\n  font-family: sans-serif;\n  -ms-text-size-adjust: 100%;\n  -webkit-text-size-adjust: 100%;\n}\n.note-editor body {\n  margin: 0;\n}\n.note-editor a {\n  background: transparent;\n}\n.note-editor a:focus {\n  outline: thin dotted;\n}\n.note-editor a:active,\n.note-editor a:hover {\n  outline: 0;\n}\n.note-editor h1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n.note-editor abbr[title] {\n  border-bottom: 1px dotted;\n}\n.note-editor b,\n.note-editor strong {\n  font-weight: bold;\n}\n.note-editor dfn {\n  font-style: italic;\n}\n.note-editor hr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0;\n}\n.note-editor mark {\n  background: #ff0;\n  color: #000;\n}\n.note-editor code,\n.note-editor kbd,\n.note-editor pre,\n.note-editor samp {\n  font-family: monospace, serif;\n  font-size: 1em;\n}\n.note-editor pre {\n  white-space: pre-wrap;\n}\n.note-editor q {\n  quotes: \"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\";\n}\n.note-editor small {\n  font-size: 80%;\n}\n.note-editor sub,\n.note-editor sup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n.note-editor sup {\n  top: -0.5em;\n}\n.note-editor sub {\n  bottom: -0.25em;\n}\n.note-editor img {\n  border: 0;\n}\n.note-editor svg:not(:root) {\n  overflow: hidden;\n}\n.note-editor figure {\n  margin: 0;\n}\n.note-editor fieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n.note-editor legend {\n  border: 0;\n  padding: 0;\n}\n.note-editor button,\n.note-editor input,\n.note-editor select,\n.note-editor textarea {\n  font-family: inherit;\n  font-size: 100%;\n  margin: 0;\n}\n.note-editor button,\n.note-editor input {\n  line-height: normal;\n}\n.note-editor button,\n.note-editor select {\n  text-transform: none;\n}\n.note-editor button,\n.note-editor html input[type=\"button\"],\n.note-editor input[type=\"reset\"],\n.note-editor input[type=\"submit\"] {\n  -webkit-appearance: button;\n  cursor: pointer;\n}\n.note-editor button[disabled],\n.note-editor html input[disabled] {\n  cursor: default;\n}\n.note-editor input[type=\"checkbox\"],\n.note-editor input[type=\"radio\"] {\n  box-sizing: border-box;\n  padding: 0;\n}\n.note-editor input[type=\"search\"] {\n  -webkit-appearance: textfield;\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box;\n  box-sizing: content-box;\n}\n.note-editor input[type=\"search\"]::-webkit-search-cancel-button,\n.note-editor input[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n.note-editor button::-moz-focus-inner,\n.note-editor input::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n.note-editor textarea {\n  overflow: auto;\n  vertical-align: top;\n}\n.note-editor table {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n@media print {\n  .note-editor * {\n    text-shadow: none !important;\n    color: #000 !important;\n    background: transparent !important;\n    box-shadow: none !important;\n  }\n  .note-editor a,\n  .note-editor a:visited {\n    text-decoration: underline;\n  }\n  .note-editor a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  .note-editor abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  .note-editor .ir a:after,\n  .note-editor a[href^=\"javascript:\"]:after,\n  .note-editor a[href^=\"#\"]:after {\n    content: \"\";\n  }\n  .note-editor pre,\n  .note-editor blockquote {\n    border: 1px solid #999;\n    page-break-inside: avoid;\n  }\n  .note-editor thead {\n    display: table-header-group;\n  }\n  .note-editor tr,\n  .note-editor img {\n    page-break-inside: avoid;\n  }\n  .note-editor img {\n    max-width: 100% !important;\n  }\n  @page  {\n    margin: 2cm .5cm;\n  }\n  .note-editor p,\n  .note-editor h2,\n  .note-editor h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  .note-editor h2,\n  .note-editor h3 {\n    page-break-after: avoid;\n  }\n  .note-editor .navbar {\n    display: none;\n  }\n  .note-editor .table td,\n  .note-editor .table th {\n    background-color: #fff !important;\n  }\n  .note-editor .btn > .caret,\n  .note-editor .dropup > .btn > .caret {\n    border-top-color: #000 !important;\n  }\n  .note-editor .label {\n    border: 1px solid #000;\n  }\n  .note-editor .table {\n    border-collapse: collapse !important;\n  }\n  .note-editor .table-bordered th,\n  .note-editor .table-bordered td {\n    border: 1px solid #ddd !important;\n  }\n}\n.note-editor *,\n.note-editor *:before,\n.note-editor *:after {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n.note-editor html {\n  font-size: 62.5%;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n.note-editor body {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 1.428571429;\n  color: #333333;\n  background-color: #ffffff;\n}\n.note-editor input,\n.note-editor button,\n.note-editor select,\n.note-editor textarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n.note-editor a {\n  color: #428bca;\n  text-decoration: none;\n}\n.note-editor a:hover,\n.note-editor a:focus {\n  color: #2a6496;\n  text-decoration: underline;\n}\n.note-editor a:focus {\n  outline: thin dotted #333;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.note-editor img {\n  vertical-align: middle;\n}\n.note-editor .img-responsive {\n  display: block;\n  max-width: 100%;\n  height: auto;\n}\n.note-editor .img-rounded {\n  border-radius: 6px;\n}\n.note-editor .img-thumbnail {\n  padding: 4px;\n  line-height: 1.428571429;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 4px;\n  -webkit-transition: all 0.2s ease-in-out;\n  transition: all 0.2s ease-in-out;\n  display: inline-block;\n  max-width: 100%;\n  height: auto;\n}\n.note-editor .img-circle {\n  border-radius: 50%;\n}\n.note-editor hr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #eeeeee;\n}\n.note-editor .sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  margin: -1px;\n  padding: 0;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  border: 0;\n}\n.note-editor p {\n  margin: 0 0 10px;\n}\n.note-editor .lead {\n  margin-bottom: 20px;\n  font-size: 16px;\n  font-weight: 200;\n  line-height: 1.4;\n}\n@media (min-width: 768px) {\n  .note-editor .lead {\n    font-size: 21px;\n  }\n}\n.note-editor small,\n.note-editor .small {\n  font-size: 85%;\n}\n.note-editor cite {\n  font-style: normal;\n}\n.note-editor .text-muted {\n  color: #999999;\n}\n.note-editor .text-primary {\n  color: #428bca;\n}\n.note-editor .text-primary:hover {\n  color: #3071a9;\n}\n.note-editor .text-warning {\n  color: #c09853;\n}\n.note-editor .text-warning:hover {\n  color: #a47e3c;\n}\n.note-editor .text-danger {\n  color: #b94a48;\n}\n.note-editor .text-danger:hover {\n  color: #953b39;\n}\n.note-editor .text-success {\n  color: #468847;\n}\n.note-editor .text-success:hover {\n  color: #356635;\n}\n.note-editor .text-info {\n  color: #3a87ad;\n}\n.note-editor .text-info:hover {\n  color: #2d6987;\n}\n.note-editor .text-left {\n  text-align: left;\n}\n.note-editor .text-right {\n  text-align: right;\n}\n.note-editor .text-center {\n  text-align: center;\n}\n.note-editor h1,\n.note-editor h2,\n.note-editor h3,\n.note-editor h4,\n.note-editor h5,\n.note-editor h6,\n.note-editor .h1,\n.note-editor .h2,\n.note-editor .h3,\n.note-editor .h4,\n.note-editor .h5,\n.note-editor .h6 {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-weight: 500;\n  line-height: 1.1;\n  color: inherit;\n}\n.note-editor h1 small,\n.note-editor h2 small,\n.note-editor h3 small,\n.note-editor h4 small,\n.note-editor h5 small,\n.note-editor h6 small,\n.note-editor .h1 small,\n.note-editor .h2 small,\n.note-editor .h3 small,\n.note-editor .h4 small,\n.note-editor .h5 small,\n.note-editor .h6 small,\n.note-editor h1 .small,\n.note-editor h2 .small,\n.note-editor h3 .small,\n.note-editor h4 .small,\n.note-editor h5 .small,\n.note-editor h6 .small,\n.note-editor .h1 .small,\n.note-editor .h2 .small,\n.note-editor .h3 .small,\n.note-editor .h4 .small,\n.note-editor .h5 .small,\n.note-editor .h6 .small {\n  font-weight: normal;\n  line-height: 1;\n  color: #999999;\n}\n.note-editor h1,\n.note-editor h2,\n.note-editor h3 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n}\n.note-editor h1 small,\n.note-editor h2 small,\n.note-editor h3 small,\n.note-editor h1 .small,\n.note-editor h2 .small,\n.note-editor h3 .small {\n  font-size: 65%;\n}\n.note-editor h4,\n.note-editor h5,\n.note-editor h6 {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.note-editor h4 small,\n.note-editor h5 small,\n.note-editor h6 small,\n.note-editor h4 .small,\n.note-editor h5 .small,\n.note-editor h6 .small {\n  font-size: 75%;\n}\n.note-editor h1,\n.note-editor .h1 {\n  font-size: 36px;\n}\n.note-editor h2,\n.note-editor .h2 {\n  font-size: 30px;\n}\n.note-editor h3,\n.note-editor .h3 {\n  font-size: 24px;\n}\n.note-editor h4,\n.note-editor .h4 {\n  font-size: 18px;\n}\n.note-editor h5,\n.note-editor .h5 {\n  font-size: 14px;\n}\n.note-editor h6,\n.note-editor .h6 {\n  font-size: 12px;\n}\n.note-editor .page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eeeeee;\n}\n.note-editor ul,\n.note-editor ol {\n  margin-top: 0;\n  margin-bottom: 10px;\n}\n.note-editor ul ul,\n.note-editor ol ul,\n.note-editor ul ol,\n.note-editor ol ol {\n  margin-bottom: 0;\n}\n.note-editor .list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n.note-editor .list-inline {\n  padding-left: 0;\n  list-style: none;\n}\n.note-editor .list-inline > li {\n  display: inline-block;\n  padding-left: 5px;\n  padding-right: 5px;\n}\n.note-editor dl {\n  margin-bottom: 20px;\n}\n.note-editor dt,\n.note-editor dd {\n  line-height: 1.428571429;\n}\n.note-editor dt {\n  font-weight: bold;\n}\n.note-editor dd {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .note-editor .dl-horizontal dt {\n    float: left;\n    width: 160px;\n    clear: left;\n    text-align: right;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n  .note-editor .dl-horizontal dd {\n    margin-left: 180px;\n  }\n  .note-editor .dl-horizontal dd:before,\n  .note-editor .dl-horizontal dd:after {\n    content: \" \";\n    /* 1 */\n  \n    display: table;\n    /* 2 */\n  \n  }\n  .note-editor .dl-horizontal dd:after {\n    clear: both;\n  }\n  .note-editor .dl-horizontal dd:before,\n  .note-editor .dl-horizontal dd:after {\n    content: \" \";\n    /* 1 */\n  \n    display: table;\n    /* 2 */\n  \n  }\n  .note-editor .dl-horizontal dd:after {\n    clear: both;\n  }\n}\n.note-editor abbr[title],\n.note-editor abbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #999999;\n}\n.note-editor abbr.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\n.note-editor blockquote {\n  padding: 10px 20px;\n  margin: 0 0 20px;\n  border-left: 5px solid #eeeeee;\n}\n.note-editor blockquote p {\n  font-size: 17.5px;\n  font-weight: 300;\n  line-height: 1.25;\n}\n.note-editor blockquote p:last-child {\n  margin-bottom: 0;\n}\n.note-editor blockquote small {\n  display: block;\n  line-height: 1.428571429;\n  color: #999999;\n}\n.note-editor blockquote small:before {\n  content: '\\2014 \\00A0';\n}\n.note-editor blockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid #eeeeee;\n  border-left: 0;\n}\n.note-editor blockquote.pull-right p,\n.note-editor blockquote.pull-right small,\n.note-editor blockquote.pull-right .small {\n  text-align: right;\n}\n.note-editor blockquote.pull-right small:before,\n.note-editor blockquote.pull-right .small:before {\n  content: '';\n}\n.note-editor blockquote.pull-right small:after,\n.note-editor blockquote.pull-right .small:after {\n  content: '\\00A0 \\2014';\n}\n.note-editor blockquote:before,\n.note-editor blockquote:after {\n  content: \"\";\n}\n.note-editor address {\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 1.428571429;\n}\n.note-editor code,\n.note-editor kdb,\n.note-editor pre,\n.note-editor samp {\n  font-family: Monaco, Menlo, Consolas, \"Courier New\", monospace;\n}\n.note-editor code {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #c7254e;\n  background-color: #f9f2f4;\n  white-space: nowrap;\n  border-radius: 4px;\n}\n.note-editor pre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 1.428571429;\n  word-break: break-all;\n  word-wrap: break-word;\n  color: #333333;\n  background-color: #f5f5f5;\n  border: 1px solid #cccccc;\n  border-radius: 4px;\n}\n.note-editor pre 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.note-editor .pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n.note-editor .container {\n  margin-right: auto;\n  margin-left: auto;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n.note-editor .container:before,\n.note-editor .container:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .container:after {\n  clear: both;\n}\n.note-editor .container:before,\n.note-editor .container:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .container:after {\n  clear: both;\n}\n.note-editor .row {\n  margin-left: -15px;\n  margin-right: -15px;\n}\n.note-editor .row:before,\n.note-editor .row:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .row:after {\n  clear: both;\n}\n.note-editor .row:before,\n.note-editor .row:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .row:after {\n  clear: both;\n}\n.note-editor .col-xs-1, \n.note-editor .col-sm-1, \n.note-editor .col-md-1, \n.note-editor .col-lg-1, \n.note-editor .col-xs-2, \n.note-editor .col-sm-2, \n.note-editor .col-md-2, \n.note-editor .col-lg-2, \n.note-editor .col-xs-3, \n.note-editor .col-sm-3, \n.note-editor .col-md-3, \n.note-editor .col-lg-3, \n.note-editor .col-xs-4, \n.note-editor .col-sm-4, \n.note-editor .col-md-4, \n.note-editor .col-lg-4, \n.note-editor .col-xs-5, \n.note-editor .col-sm-5, \n.note-editor .col-md-5, \n.note-editor .col-lg-5, \n.note-editor .col-xs-6, \n.note-editor .col-sm-6, \n.note-editor .col-md-6, \n.note-editor .col-lg-6, \n.note-editor .col-xs-7, \n.note-editor .col-sm-7, \n.note-editor .col-md-7, \n.note-editor .col-lg-7, \n.note-editor .col-xs-8, \n.note-editor .col-sm-8, \n.note-editor .col-md-8, \n.note-editor .col-lg-8, \n.note-editor .col-xs-9, \n.note-editor .col-sm-9, \n.note-editor .col-md-9, \n.note-editor .col-lg-9, \n.note-editor .col-xs-10, \n.note-editor .col-sm-10, \n.note-editor .col-md-10, \n.note-editor .col-lg-10, \n.note-editor .col-xs-11, \n.note-editor .col-sm-11, \n.note-editor .col-md-11, \n.note-editor .col-lg-11, \n.note-editor .col-xs-12, \n.note-editor .col-sm-12, \n.note-editor .col-md-12, \n.note-editor .col-lg-12 {\n  position: relative;\n  min-height: 1px;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n.note-editor .col-xs-1, \n.note-editor .col-xs-2, \n.note-editor .col-xs-3, \n.note-editor .col-xs-4, \n.note-editor .col-xs-5, \n.note-editor .col-xs-6, \n.note-editor .col-xs-7, \n.note-editor .col-xs-8, \n.note-editor .col-xs-9, \n.note-editor .col-xs-10, \n.note-editor .col-xs-11 {\n  float: left;\n}\n.note-editor .col-xs-12 {\n  width: 100%;\n}\n.note-editor .col-xs-11 {\n  width: 91.66666666666666%;\n}\n.note-editor .col-xs-10 {\n  width: 83.33333333333334%;\n}\n.note-editor .col-xs-9 {\n  width: 75%;\n}\n.note-editor .col-xs-8 {\n  width: 66.66666666666666%;\n}\n.note-editor .col-xs-7 {\n  width: 58.333333333333336%;\n}\n.note-editor .col-xs-6 {\n  width: 50%;\n}\n.note-editor .col-xs-5 {\n  width: 41.66666666666667%;\n}\n.note-editor .col-xs-4 {\n  width: 33.33333333333333%;\n}\n.note-editor .col-xs-3 {\n  width: 25%;\n}\n.note-editor .col-xs-2 {\n  width: 16.666666666666664%;\n}\n.note-editor .col-xs-1 {\n  width: 8.333333333333332%;\n}\n.note-editor .col-xs-pull-12 {\n  right: 100%;\n}\n.note-editor .col-xs-pull-11 {\n  right: 91.66666666666666%;\n}\n.note-editor .col-xs-pull-10 {\n  right: 83.33333333333334%;\n}\n.note-editor .col-xs-pull-9 {\n  right: 75%;\n}\n.note-editor .col-xs-pull-8 {\n  right: 66.66666666666666%;\n}\n.note-editor .col-xs-pull-7 {\n  right: 58.333333333333336%;\n}\n.note-editor .col-xs-pull-6 {\n  right: 50%;\n}\n.note-editor .col-xs-pull-5 {\n  right: 41.66666666666667%;\n}\n.note-editor .col-xs-pull-4 {\n  right: 33.33333333333333%;\n}\n.note-editor .col-xs-pull-3 {\n  right: 25%;\n}\n.note-editor .col-xs-pull-2 {\n  right: 16.666666666666664%;\n}\n.note-editor .col-xs-pull-1 {\n  right: 8.333333333333332%;\n}\n.note-editor .col-xs-push-12 {\n  left: 100%;\n}\n.note-editor .col-xs-push-11 {\n  left: 91.66666666666666%;\n}\n.note-editor .col-xs-push-10 {\n  left: 83.33333333333334%;\n}\n.note-editor .col-xs-push-9 {\n  left: 75%;\n}\n.note-editor .col-xs-push-8 {\n  left: 66.66666666666666%;\n}\n.note-editor .col-xs-push-7 {\n  left: 58.333333333333336%;\n}\n.note-editor .col-xs-push-6 {\n  left: 50%;\n}\n.note-editor .col-xs-push-5 {\n  left: 41.66666666666667%;\n}\n.note-editor .col-xs-push-4 {\n  left: 33.33333333333333%;\n}\n.note-editor .col-xs-push-3 {\n  left: 25%;\n}\n.note-editor .col-xs-push-2 {\n  left: 16.666666666666664%;\n}\n.note-editor .col-xs-push-1 {\n  left: 8.333333333333332%;\n}\n.note-editor .col-xs-offset-12 {\n  margin-left: 100%;\n}\n.note-editor .col-xs-offset-11 {\n  margin-left: 91.66666666666666%;\n}\n.note-editor .col-xs-offset-10 {\n  margin-left: 83.33333333333334%;\n}\n.note-editor .col-xs-offset-9 {\n  margin-left: 75%;\n}\n.note-editor .col-xs-offset-8 {\n  margin-left: 66.66666666666666%;\n}\n.note-editor .col-xs-offset-7 {\n  margin-left: 58.333333333333336%;\n}\n.note-editor .col-xs-offset-6 {\n  margin-left: 50%;\n}\n.note-editor .col-xs-offset-5 {\n  margin-left: 41.66666666666667%;\n}\n.note-editor .col-xs-offset-4 {\n  margin-left: 33.33333333333333%;\n}\n.note-editor .col-xs-offset-3 {\n  margin-left: 25%;\n}\n.note-editor .col-xs-offset-2 {\n  margin-left: 16.666666666666664%;\n}\n.note-editor .col-xs-offset-1 {\n  margin-left: 8.333333333333332%;\n}\n@media (min-width: 768px) {\n  .note-editor .container {\n    width: 750px;\n  }\n  .note-editor .col-sm-1, \n  .note-editor .col-sm-2, \n  .note-editor .col-sm-3, \n  .note-editor .col-sm-4, \n  .note-editor .col-sm-5, \n  .note-editor .col-sm-6, \n  .note-editor .col-sm-7, \n  .note-editor .col-sm-8, \n  .note-editor .col-sm-9, \n  .note-editor .col-sm-10, \n  .note-editor .col-sm-11 {\n    float: left;\n  }\n  .note-editor .col-sm-12 {\n    width: 100%;\n  }\n  .note-editor .col-sm-11 {\n    width: 91.66666666666666%;\n  }\n  .note-editor .col-sm-10 {\n    width: 83.33333333333334%;\n  }\n  .note-editor .col-sm-9 {\n    width: 75%;\n  }\n  .note-editor .col-sm-8 {\n    width: 66.66666666666666%;\n  }\n  .note-editor .col-sm-7 {\n    width: 58.333333333333336%;\n  }\n  .note-editor .col-sm-6 {\n    width: 50%;\n  }\n  .note-editor .col-sm-5 {\n    width: 41.66666666666667%;\n  }\n  .note-editor .col-sm-4 {\n    width: 33.33333333333333%;\n  }\n  .note-editor .col-sm-3 {\n    width: 25%;\n  }\n  .note-editor .col-sm-2 {\n    width: 16.666666666666664%;\n  }\n  .note-editor .col-sm-1 {\n    width: 8.333333333333332%;\n  }\n  .note-editor .col-sm-pull-12 {\n    right: 100%;\n  }\n  .note-editor .col-sm-pull-11 {\n    right: 91.66666666666666%;\n  }\n  .note-editor .col-sm-pull-10 {\n    right: 83.33333333333334%;\n  }\n  .note-editor .col-sm-pull-9 {\n    right: 75%;\n  }\n  .note-editor .col-sm-pull-8 {\n    right: 66.66666666666666%;\n  }\n  .note-editor .col-sm-pull-7 {\n    right: 58.333333333333336%;\n  }\n  .note-editor .col-sm-pull-6 {\n    right: 50%;\n  }\n  .note-editor .col-sm-pull-5 {\n    right: 41.66666666666667%;\n  }\n  .note-editor .col-sm-pull-4 {\n    right: 33.33333333333333%;\n  }\n  .note-editor .col-sm-pull-3 {\n    right: 25%;\n  }\n  .note-editor .col-sm-pull-2 {\n    right: 16.666666666666664%;\n  }\n  .note-editor .col-sm-pull-1 {\n    right: 8.333333333333332%;\n  }\n  .note-editor .col-sm-push-12 {\n    left: 100%;\n  }\n  .note-editor .col-sm-push-11 {\n    left: 91.66666666666666%;\n  }\n  .note-editor .col-sm-push-10 {\n    left: 83.33333333333334%;\n  }\n  .note-editor .col-sm-push-9 {\n    left: 75%;\n  }\n  .note-editor .col-sm-push-8 {\n    left: 66.66666666666666%;\n  }\n  .note-editor .col-sm-push-7 {\n    left: 58.333333333333336%;\n  }\n  .note-editor .col-sm-push-6 {\n    left: 50%;\n  }\n  .note-editor .col-sm-push-5 {\n    left: 41.66666666666667%;\n  }\n  .note-editor .col-sm-push-4 {\n    left: 33.33333333333333%;\n  }\n  .note-editor .col-sm-push-3 {\n    left: 25%;\n  }\n  .note-editor .col-sm-push-2 {\n    left: 16.666666666666664%;\n  }\n  .note-editor .col-sm-push-1 {\n    left: 8.333333333333332%;\n  }\n  .note-editor .col-sm-offset-12 {\n    margin-left: 100%;\n  }\n  .note-editor .col-sm-offset-11 {\n    margin-left: 91.66666666666666%;\n  }\n  .note-editor .col-sm-offset-10 {\n    margin-left: 83.33333333333334%;\n  }\n  .note-editor .col-sm-offset-9 {\n    margin-left: 75%;\n  }\n  .note-editor .col-sm-offset-8 {\n    margin-left: 66.66666666666666%;\n  }\n  .note-editor .col-sm-offset-7 {\n    margin-left: 58.333333333333336%;\n  }\n  .note-editor .col-sm-offset-6 {\n    margin-left: 50%;\n  }\n  .note-editor .col-sm-offset-5 {\n    margin-left: 41.66666666666667%;\n  }\n  .note-editor .col-sm-offset-4 {\n    margin-left: 33.33333333333333%;\n  }\n  .note-editor .col-sm-offset-3 {\n    margin-left: 25%;\n  }\n  .note-editor .col-sm-offset-2 {\n    margin-left: 16.666666666666664%;\n  }\n  .note-editor .col-sm-offset-1 {\n    margin-left: 8.333333333333332%;\n  }\n}\n@media (min-width: 992px) {\n  .note-editor .container {\n    width: 970px;\n  }\n  .note-editor .col-md-1, \n  .note-editor .col-md-2, \n  .note-editor .col-md-3, \n  .note-editor .col-md-4, \n  .note-editor .col-md-5, \n  .note-editor .col-md-6, \n  .note-editor .col-md-7, \n  .note-editor .col-md-8, \n  .note-editor .col-md-9, \n  .note-editor .col-md-10, \n  .note-editor .col-md-11 {\n    float: left;\n  }\n  .note-editor .col-md-12 {\n    width: 100%;\n  }\n  .note-editor .col-md-11 {\n    width: 91.66666666666666%;\n  }\n  .note-editor .col-md-10 {\n    width: 83.33333333333334%;\n  }\n  .note-editor .col-md-9 {\n    width: 75%;\n  }\n  .note-editor .col-md-8 {\n    width: 66.66666666666666%;\n  }\n  .note-editor .col-md-7 {\n    width: 58.333333333333336%;\n  }\n  .note-editor .col-md-6 {\n    width: 50%;\n  }\n  .note-editor .col-md-5 {\n    width: 41.66666666666667%;\n  }\n  .note-editor .col-md-4 {\n    width: 33.33333333333333%;\n  }\n  .note-editor .col-md-3 {\n    width: 25%;\n  }\n  .note-editor .col-md-2 {\n    width: 16.666666666666664%;\n  }\n  .note-editor .col-md-1 {\n    width: 8.333333333333332%;\n  }\n  .note-editor .col-md-pull-12 {\n    right: 100%;\n  }\n  .note-editor .col-md-pull-11 {\n    right: 91.66666666666666%;\n  }\n  .note-editor .col-md-pull-10 {\n    right: 83.33333333333334%;\n  }\n  .note-editor .col-md-pull-9 {\n    right: 75%;\n  }\n  .note-editor .col-md-pull-8 {\n    right: 66.66666666666666%;\n  }\n  .note-editor .col-md-pull-7 {\n    right: 58.333333333333336%;\n  }\n  .note-editor .col-md-pull-6 {\n    right: 50%;\n  }\n  .note-editor .col-md-pull-5 {\n    right: 41.66666666666667%;\n  }\n  .note-editor .col-md-pull-4 {\n    right: 33.33333333333333%;\n  }\n  .note-editor .col-md-pull-3 {\n    right: 25%;\n  }\n  .note-editor .col-md-pull-2 {\n    right: 16.666666666666664%;\n  }\n  .note-editor .col-md-pull-1 {\n    right: 8.333333333333332%;\n  }\n  .note-editor .col-md-push-12 {\n    left: 100%;\n  }\n  .note-editor .col-md-push-11 {\n    left: 91.66666666666666%;\n  }\n  .note-editor .col-md-push-10 {\n    left: 83.33333333333334%;\n  }\n  .note-editor .col-md-push-9 {\n    left: 75%;\n  }\n  .note-editor .col-md-push-8 {\n    left: 66.66666666666666%;\n  }\n  .note-editor .col-md-push-7 {\n    left: 58.333333333333336%;\n  }\n  .note-editor .col-md-push-6 {\n    left: 50%;\n  }\n  .note-editor .col-md-push-5 {\n    left: 41.66666666666667%;\n  }\n  .note-editor .col-md-push-4 {\n    left: 33.33333333333333%;\n  }\n  .note-editor .col-md-push-3 {\n    left: 25%;\n  }\n  .note-editor .col-md-push-2 {\n    left: 16.666666666666664%;\n  }\n  .note-editor .col-md-push-1 {\n    left: 8.333333333333332%;\n  }\n  .note-editor .col-md-offset-12 {\n    margin-left: 100%;\n  }\n  .note-editor .col-md-offset-11 {\n    margin-left: 91.66666666666666%;\n  }\n  .note-editor .col-md-offset-10 {\n    margin-left: 83.33333333333334%;\n  }\n  .note-editor .col-md-offset-9 {\n    margin-left: 75%;\n  }\n  .note-editor .col-md-offset-8 {\n    margin-left: 66.66666666666666%;\n  }\n  .note-editor .col-md-offset-7 {\n    margin-left: 58.333333333333336%;\n  }\n  .note-editor .col-md-offset-6 {\n    margin-left: 50%;\n  }\n  .note-editor .col-md-offset-5 {\n    margin-left: 41.66666666666667%;\n  }\n  .note-editor .col-md-offset-4 {\n    margin-left: 33.33333333333333%;\n  }\n  .note-editor .col-md-offset-3 {\n    margin-left: 25%;\n  }\n  .note-editor .col-md-offset-2 {\n    margin-left: 16.666666666666664%;\n  }\n  .note-editor .col-md-offset-1 {\n    margin-left: 8.333333333333332%;\n  }\n}\n@media (min-width: 1200px) {\n  .note-editor .container {\n    width: 1170px;\n  }\n  .note-editor .col-lg-1, \n  .note-editor .col-lg-2, \n  .note-editor .col-lg-3, \n  .note-editor .col-lg-4, \n  .note-editor .col-lg-5, \n  .note-editor .col-lg-6, \n  .note-editor .col-lg-7, \n  .note-editor .col-lg-8, \n  .note-editor .col-lg-9, \n  .note-editor .col-lg-10, \n  .note-editor .col-lg-11 {\n    float: left;\n  }\n  .note-editor .col-lg-12 {\n    width: 100%;\n  }\n  .note-editor .col-lg-11 {\n    width: 91.66666666666666%;\n  }\n  .note-editor .col-lg-10 {\n    width: 83.33333333333334%;\n  }\n  .note-editor .col-lg-9 {\n    width: 75%;\n  }\n  .note-editor .col-lg-8 {\n    width: 66.66666666666666%;\n  }\n  .note-editor .col-lg-7 {\n    width: 58.333333333333336%;\n  }\n  .note-editor .col-lg-6 {\n    width: 50%;\n  }\n  .note-editor .col-lg-5 {\n    width: 41.66666666666667%;\n  }\n  .note-editor .col-lg-4 {\n    width: 33.33333333333333%;\n  }\n  .note-editor .col-lg-3 {\n    width: 25%;\n  }\n  .note-editor .col-lg-2 {\n    width: 16.666666666666664%;\n  }\n  .note-editor .col-lg-1 {\n    width: 8.333333333333332%;\n  }\n  .note-editor .col-lg-pull-12 {\n    right: 100%;\n  }\n  .note-editor .col-lg-pull-11 {\n    right: 91.66666666666666%;\n  }\n  .note-editor .col-lg-pull-10 {\n    right: 83.33333333333334%;\n  }\n  .note-editor .col-lg-pull-9 {\n    right: 75%;\n  }\n  .note-editor .col-lg-pull-8 {\n    right: 66.66666666666666%;\n  }\n  .note-editor .col-lg-pull-7 {\n    right: 58.333333333333336%;\n  }\n  .note-editor .col-lg-pull-6 {\n    right: 50%;\n  }\n  .note-editor .col-lg-pull-5 {\n    right: 41.66666666666667%;\n  }\n  .note-editor .col-lg-pull-4 {\n    right: 33.33333333333333%;\n  }\n  .note-editor .col-lg-pull-3 {\n    right: 25%;\n  }\n  .note-editor .col-lg-pull-2 {\n    right: 16.666666666666664%;\n  }\n  .note-editor .col-lg-pull-1 {\n    right: 8.333333333333332%;\n  }\n  .note-editor .col-lg-push-12 {\n    left: 100%;\n  }\n  .note-editor .col-lg-push-11 {\n    left: 91.66666666666666%;\n  }\n  .note-editor .col-lg-push-10 {\n    left: 83.33333333333334%;\n  }\n  .note-editor .col-lg-push-9 {\n    left: 75%;\n  }\n  .note-editor .col-lg-push-8 {\n    left: 66.66666666666666%;\n  }\n  .note-editor .col-lg-push-7 {\n    left: 58.333333333333336%;\n  }\n  .note-editor .col-lg-push-6 {\n    left: 50%;\n  }\n  .note-editor .col-lg-push-5 {\n    left: 41.66666666666667%;\n  }\n  .note-editor .col-lg-push-4 {\n    left: 33.33333333333333%;\n  }\n  .note-editor .col-lg-push-3 {\n    left: 25%;\n  }\n  .note-editor .col-lg-push-2 {\n    left: 16.666666666666664%;\n  }\n  .note-editor .col-lg-push-1 {\n    left: 8.333333333333332%;\n  }\n  .note-editor .col-lg-offset-12 {\n    margin-left: 100%;\n  }\n  .note-editor .col-lg-offset-11 {\n    margin-left: 91.66666666666666%;\n  }\n  .note-editor .col-lg-offset-10 {\n    margin-left: 83.33333333333334%;\n  }\n  .note-editor .col-lg-offset-9 {\n    margin-left: 75%;\n  }\n  .note-editor .col-lg-offset-8 {\n    margin-left: 66.66666666666666%;\n  }\n  .note-editor .col-lg-offset-7 {\n    margin-left: 58.333333333333336%;\n  }\n  .note-editor .col-lg-offset-6 {\n    margin-left: 50%;\n  }\n  .note-editor .col-lg-offset-5 {\n    margin-left: 41.66666666666667%;\n  }\n  .note-editor .col-lg-offset-4 {\n    margin-left: 33.33333333333333%;\n  }\n  .note-editor .col-lg-offset-3 {\n    margin-left: 25%;\n  }\n  .note-editor .col-lg-offset-2 {\n    margin-left: 16.666666666666664%;\n  }\n  .note-editor .col-lg-offset-1 {\n    margin-left: 8.333333333333332%;\n  }\n}\n.note-editor table {\n  max-width: 100%;\n  background-color: transparent;\n}\n.note-editor th {\n  text-align: left;\n}\n.note-editor .table {\n  width: 100%;\n  margin-bottom: 20px;\n}\n.note-editor .table > thead > tr > th,\n.note-editor .table > tbody > tr > th,\n.note-editor .table > tfoot > tr > th,\n.note-editor .table > thead > tr > td,\n.note-editor .table > tbody > tr > td,\n.note-editor .table > tfoot > tr > td {\n  padding: 8px;\n  line-height: 1.428571429;\n  vertical-align: top;\n  border-top: 1px solid #dddddd;\n}\n.note-editor .table > thead > tr > th {\n  vertical-align: bottom;\n  border-bottom: 2px solid #dddddd;\n}\n.note-editor .table > caption + thead > tr:first-child > th,\n.note-editor .table > colgroup + thead > tr:first-child > th,\n.note-editor .table > thead:first-child > tr:first-child > th,\n.note-editor .table > caption + thead > tr:first-child > td,\n.note-editor .table > colgroup + thead > tr:first-child > td,\n.note-editor .table > thead:first-child > tr:first-child > td {\n  border-top: 0;\n}\n.note-editor .table > tbody + tbody {\n  border-top: 2px solid #dddddd;\n}\n.note-editor .table .table {\n  background-color: #ffffff;\n}\n.note-editor .table-condensed > thead > tr > th,\n.note-editor .table-condensed > tbody > tr > th,\n.note-editor .table-condensed > tfoot > tr > th,\n.note-editor .table-condensed > thead > tr > td,\n.note-editor .table-condensed > tbody > tr > td,\n.note-editor .table-condensed > tfoot > tr > td {\n  padding: 5px;\n}\n.note-editor .table-bordered {\n  border: 1px solid #dddddd;\n}\n.note-editor .table-bordered > thead > tr > th,\n.note-editor .table-bordered > tbody > tr > th,\n.note-editor .table-bordered > tfoot > tr > th,\n.note-editor .table-bordered > thead > tr > td,\n.note-editor .table-bordered > tbody > tr > td,\n.note-editor .table-bordered > tfoot > tr > td {\n  border: 1px solid #dddddd;\n}\n.note-editor .table-bordered > thead > tr > th,\n.note-editor .table-bordered > thead > tr > td {\n  border-bottom-width: 2px;\n}\n.note-editor .table-striped > tbody > tr:nth-child(odd) > td,\n.note-editor .table-striped > tbody > tr:nth-child(odd) > th {\n  background-color: #f9f9f9;\n}\n.note-editor .table-hover > tbody > tr:hover > td,\n.note-editor .table-hover > tbody > tr:hover > th {\n  background-color: #f5f5f5;\n}\n.note-editor table col[class*=\"col-\"] {\n  float: none;\n  display: table-column;\n}\n.note-editor table td[class*=\"col-\"],\n.note-editor table th[class*=\"col-\"] {\n  float: none;\n  display: table-cell;\n}\n.note-editor .table > thead > tr > td.active,\n.note-editor .table > tbody > tr > td.active,\n.note-editor .table > tfoot > tr > td.active,\n.note-editor .table > thead > tr > th.active,\n.note-editor .table > tbody > tr > th.active,\n.note-editor .table > tfoot > tr > th.active,\n.note-editor .table > thead > tr.active > td,\n.note-editor .table > tbody > tr.active > td,\n.note-editor .table > tfoot > tr.active > td,\n.note-editor .table > thead > tr.active > th,\n.note-editor .table > tbody > tr.active > th,\n.note-editor .table > tfoot > tr.active > th {\n  background-color: #f5f5f5;\n}\n.note-editor .table > thead > tr > td.success,\n.note-editor .table > tbody > tr > td.success,\n.note-editor .table > tfoot > tr > td.success,\n.note-editor .table > thead > tr > th.success,\n.note-editor .table > tbody > tr > th.success,\n.note-editor .table > tfoot > tr > th.success,\n.note-editor .table > thead > tr.success > td,\n.note-editor .table > tbody > tr.success > td,\n.note-editor .table > tfoot > tr.success > td,\n.note-editor .table > thead > tr.success > th,\n.note-editor .table > tbody > tr.success > th,\n.note-editor .table > tfoot > tr.success > th {\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.note-editor .table-hover > tbody > tr > td.success:hover,\n.note-editor .table-hover > tbody > tr > th.success:hover,\n.note-editor .table-hover > tbody > tr.success:hover > td,\n.note-editor .table-hover > tbody > tr.success:hover > th {\n  background-color: #d0e9c6;\n  border-color: #c9e2b3;\n}\n.note-editor .table > thead > tr > td.danger,\n.note-editor .table > tbody > tr > td.danger,\n.note-editor .table > tfoot > tr > td.danger,\n.note-editor .table > thead > tr > th.danger,\n.note-editor .table > tbody > tr > th.danger,\n.note-editor .table > tfoot > tr > th.danger,\n.note-editor .table > thead > tr.danger > td,\n.note-editor .table > tbody > tr.danger > td,\n.note-editor .table > tfoot > tr.danger > td,\n.note-editor .table > thead > tr.danger > th,\n.note-editor .table > tbody > tr.danger > th,\n.note-editor .table > tfoot > tr.danger > th {\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.note-editor .table-hover > tbody > tr > td.danger:hover,\n.note-editor .table-hover > tbody > tr > th.danger:hover,\n.note-editor .table-hover > tbody > tr.danger:hover > td,\n.note-editor .table-hover > tbody > tr.danger:hover > th {\n  background-color: #ebcccc;\n  border-color: #e4b9c0;\n}\n.note-editor .table > thead > tr > td.warning,\n.note-editor .table > tbody > tr > td.warning,\n.note-editor .table > tfoot > tr > td.warning,\n.note-editor .table > thead > tr > th.warning,\n.note-editor .table > tbody > tr > th.warning,\n.note-editor .table > tfoot > tr > th.warning,\n.note-editor .table > thead > tr.warning > td,\n.note-editor .table > tbody > tr.warning > td,\n.note-editor .table > tfoot > tr.warning > td,\n.note-editor .table > thead > tr.warning > th,\n.note-editor .table > tbody > tr.warning > th,\n.note-editor .table > tfoot > tr.warning > th {\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.note-editor .table-hover > tbody > tr > td.warning:hover,\n.note-editor .table-hover > tbody > tr > th.warning:hover,\n.note-editor .table-hover > tbody > tr.warning:hover > td,\n.note-editor .table-hover > tbody > tr.warning:hover > th {\n  background-color: #faf2cc;\n  border-color: #f7e1b5;\n}\n@media (max-width: 767px) {\n  .note-editor .table-responsive {\n    width: 100%;\n    margin-bottom: 15px;\n    overflow-y: hidden;\n    overflow-x: scroll;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid #dddddd;\n    -webkit-overflow-scrolling: touch;\n  }\n  .note-editor .table-responsive > .table {\n    margin-bottom: 0;\n  }\n  .note-editor .table-responsive > .table > thead > tr > th,\n  .note-editor .table-responsive > .table > tbody > tr > th,\n  .note-editor .table-responsive > .table > tfoot > tr > th,\n  .note-editor .table-responsive > .table > thead > tr > td,\n  .note-editor .table-responsive > .table > tbody > tr > td,\n  .note-editor .table-responsive > .table > tfoot > tr > td {\n    white-space: nowrap;\n  }\n  .note-editor .table-responsive > .table-bordered {\n    border: 0;\n  }\n  .note-editor .table-responsive > .table-bordered > thead > tr > th:first-child,\n  .note-editor .table-responsive > .table-bordered > tbody > tr > th:first-child,\n  .note-editor .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n  .note-editor .table-responsive > .table-bordered > thead > tr > td:first-child,\n  .note-editor .table-responsive > .table-bordered > tbody > tr > td:first-child,\n  .note-editor .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n    border-left: 0;\n  }\n  .note-editor .table-responsive > .table-bordered > thead > tr > th:last-child,\n  .note-editor .table-responsive > .table-bordered > tbody > tr > th:last-child,\n  .note-editor .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n  .note-editor .table-responsive > .table-bordered > thead > tr > td:last-child,\n  .note-editor .table-responsive > .table-bordered > tbody > tr > td:last-child,\n  .note-editor .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n    border-right: 0;\n  }\n  .note-editor .table-responsive > .table-bordered > tbody > tr:last-child > th,\n  .note-editor .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n  .note-editor .table-responsive > .table-bordered > tbody > tr:last-child > td,\n  .note-editor .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n    border-bottom: 0;\n  }\n}\n.note-editor fieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n.note-editor legend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: inherit;\n  color: #333333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\n.note-editor label {\n  display: inline-block;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\n.note-editor input[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n.note-editor input[type=\"radio\"],\n.note-editor input[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  /* IE8-9 */\n\n  line-height: normal;\n}\n.note-editor input[type=\"file\"] {\n  display: block;\n}\n.note-editor select[multiple],\n.note-editor select[size] {\n  height: auto;\n}\n.note-editor select optgroup {\n  font-size: inherit;\n  font-style: inherit;\n  font-family: inherit;\n}\n.note-editor input[type=\"file\"]:focus,\n.note-editor input[type=\"radio\"]:focus,\n.note-editor input[type=\"checkbox\"]:focus {\n  outline: thin dotted #333;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.note-editor input[type=\"number\"]::-webkit-outer-spin-button,\n.note-editor input[type=\"number\"]::-webkit-inner-spin-button {\n  height: auto;\n}\n.note-editor output {\n  display: block;\n  padding-top: 7px;\n  font-size: 14px;\n  line-height: 1.428571429;\n  color: #555555;\n  vertical-align: middle;\n}\n.note-editor .form-control:-moz-placeholder {\n  color: #999999;\n}\n.note-editor .form-control::-moz-placeholder {\n  color: #999999;\n}\n.note-editor .form-control:-ms-input-placeholder {\n  color: #999999;\n}\n.note-editor .form-control::-webkit-input-placeholder {\n  color: #999999;\n}\n.note-editor .form-control {\n  display: block;\n  width: 100%;\n  height: 34px;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.428571429;\n  color: #555555;\n  vertical-align: middle;\n  background-color: #ffffff;\n  background-image: none;\n  border: 1px solid #cccccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.note-editor .form-control:focus {\n  border-color: #66afe9;\n  outline: 0;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.note-editor .form-control[disabled],\n.note-editor .form-control[readonly],\nfieldset[disabled] .note-editor .form-control {\n  cursor: not-allowed;\n  background-color: #eeeeee;\n}\ntextarea.note-editor .form-control {\n  height: auto;\n}\n.note-editor .form-group {\n  margin-bottom: 15px;\n}\n.note-editor .radio,\n.note-editor .checkbox {\n  display: block;\n  min-height: 20px;\n  margin-top: 10px;\n  margin-bottom: 10px;\n  padding-left: 20px;\n  vertical-align: middle;\n}\n.note-editor .radio label,\n.note-editor .checkbox label {\n  display: inline;\n  margin-bottom: 0;\n  font-weight: normal;\n  cursor: pointer;\n}\n.note-editor .radio input[type=\"radio\"],\n.note-editor .radio-inline input[type=\"radio\"],\n.note-editor .checkbox input[type=\"checkbox\"],\n.note-editor .checkbox-inline input[type=\"checkbox\"] {\n  float: left;\n  margin-left: -20px;\n}\n.note-editor .radio + .radio,\n.note-editor .checkbox + .checkbox {\n  margin-top: -5px;\n}\n.note-editor .radio-inline,\n.note-editor .checkbox-inline {\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  vertical-align: middle;\n  font-weight: normal;\n  cursor: pointer;\n}\n.note-editor .radio-inline + .radio-inline,\n.note-editor .checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px;\n}\n.note-editor input[type=\"radio\"][disabled],\n.note-editor input[type=\"checkbox\"][disabled],\n.note-editor .radio[disabled],\n.note-editor .radio-inline[disabled],\n.note-editor .checkbox[disabled],\n.note-editor .checkbox-inline[disabled],\nfieldset[disabled] .note-editor input[type=\"radio\"],\nfieldset[disabled] .note-editor input[type=\"checkbox\"],\nfieldset[disabled] .note-editor .radio,\nfieldset[disabled] .note-editor .radio-inline,\nfieldset[disabled] .note-editor .checkbox,\nfieldset[disabled] .note-editor .checkbox-inline {\n  cursor: not-allowed;\n}\n.note-editor .input-sm {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.note-editor .input-sm {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.note-editor .input-sm {\n  height: auto;\n}\n.note-editor .input-lg {\n  height: 45px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.33;\n  border-radius: 6px;\n}\nselect.note-editor .input-lg {\n  height: 45px;\n  line-height: 45px;\n}\ntextarea.note-editor .input-lg {\n  height: auto;\n}\n.note-editor .has-warning .help-block,\n.note-editor .has-warning .control-label {\n  color: #c09853;\n}\n.note-editor .has-warning .form-control {\n  border-color: #c09853;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.note-editor .has-warning .form-control:focus {\n  border-color: #a47e3c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;\n}\n.note-editor .has-warning .input-group-addon {\n  color: #c09853;\n  border-color: #c09853;\n  background-color: #fcf8e3;\n}\n.note-editor .has-error .help-block,\n.note-editor .has-error .control-label {\n  color: #b94a48;\n}\n.note-editor .has-error .form-control {\n  border-color: #b94a48;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.note-editor .has-error .form-control:focus {\n  border-color: #953b39;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;\n}\n.note-editor .has-error .input-group-addon {\n  color: #b94a48;\n  border-color: #b94a48;\n  background-color: #f2dede;\n}\n.note-editor .has-success .help-block,\n.note-editor .has-success .control-label {\n  color: #468847;\n}\n.note-editor .has-success .form-control {\n  border-color: #468847;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.note-editor .has-success .form-control:focus {\n  border-color: #356635;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;\n}\n.note-editor .has-success .input-group-addon {\n  color: #468847;\n  border-color: #468847;\n  background-color: #dff0d8;\n}\n.note-editor .form-control-static {\n  margin-bottom: 0;\n}\n.note-editor .help-block {\n  display: block;\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: #737373;\n}\n@media (min-width: 768px) {\n  .note-editor .form-inline .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .note-editor .form-inline .form-control {\n    display: inline-block;\n  }\n  .note-editor .form-inline .radio,\n  .note-editor .form-inline .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    padding-left: 0;\n  }\n  .note-editor .form-inline .radio input[type=\"radio\"],\n  .note-editor .form-inline .checkbox input[type=\"checkbox\"] {\n    float: none;\n    margin-left: 0;\n  }\n}\n.note-editor .form-horizontal .control-label,\n.note-editor .form-horizontal .radio,\n.note-editor .form-horizontal .checkbox,\n.note-editor .form-horizontal .radio-inline,\n.note-editor .form-horizontal .checkbox-inline {\n  margin-top: 0;\n  margin-bottom: 0;\n  padding-top: 7px;\n}\n.note-editor .form-horizontal .form-group {\n  margin-left: -15px;\n  margin-right: -15px;\n}\n.note-editor .form-horizontal .form-group:before,\n.note-editor .form-horizontal .form-group:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .form-horizontal .form-group:after {\n  clear: both;\n}\n.note-editor .form-horizontal .form-group:before,\n.note-editor .form-horizontal .form-group:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .form-horizontal .form-group:after {\n  clear: both;\n}\n.note-editor .form-horizontal .form-control-static {\n  padding-top: 7px;\n}\n@media (min-width: 768px) {\n  .note-editor .form-horizontal .control-label {\n    text-align: right;\n  }\n}\n.note-editor .btn {\n  display: inline-block;\n  margin-bottom: 0;\n  font-weight: normal;\n  text-align: center;\n  vertical-align: middle;\n  cursor: pointer;\n  background-image: none;\n  border: 1px solid transparent;\n  white-space: nowrap;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.428571429;\n  border-radius: 4px;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  -o-user-select: none;\n  user-select: none;\n}\n.note-editor .btn:focus {\n  outline: thin dotted #333;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.note-editor .btn:hover,\n.note-editor .btn:focus {\n  color: #333333;\n  text-decoration: none;\n}\n.note-editor .btn:active,\n.note-editor .btn.active {\n  outline: 0;\n  background-image: none;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.note-editor .btn.disabled,\n.note-editor .btn[disabled],\nfieldset[disabled] .note-editor .btn {\n  cursor: not-allowed;\n  pointer-events: none;\n  opacity: 0.65;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n.note-editor .btn-default {\n  color: #333333;\n  background-color: #ffffff;\n  border-color: #cccccc;\n}\n.note-editor .btn-default:hover,\n.note-editor .btn-default:focus,\n.note-editor .btn-default:active,\n.note-editor .btn-default.active,\n.open .dropdown-toggle.note-editor .btn-default {\n  color: #333333;\n  background-color: #ebebeb;\n  border-color: #adadad;\n}\n.note-editor .btn-default:active,\n.note-editor .btn-default.active,\n.open .dropdown-toggle.note-editor .btn-default {\n  background-image: none;\n}\n.note-editor .btn-default.disabled,\n.note-editor .btn-default[disabled],\nfieldset[disabled] .note-editor .btn-default,\n.note-editor .btn-default.disabled:hover,\n.note-editor .btn-default[disabled]:hover,\nfieldset[disabled] .note-editor .btn-default:hover,\n.note-editor .btn-default.disabled:focus,\n.note-editor .btn-default[disabled]:focus,\nfieldset[disabled] .note-editor .btn-default:focus,\n.note-editor .btn-default.disabled:active,\n.note-editor .btn-default[disabled]:active,\nfieldset[disabled] .note-editor .btn-default:active,\n.note-editor .btn-default.disabled.active,\n.note-editor .btn-default[disabled].active,\nfieldset[disabled] .note-editor .btn-default.active {\n  background-color: #ffffff;\n  border-color: #cccccc;\n}\n.note-editor .btn-primary {\n  color: #ffffff;\n  background-color: #428bca;\n  border-color: #357ebd;\n}\n.note-editor .btn-primary:hover,\n.note-editor .btn-primary:focus,\n.note-editor .btn-primary:active,\n.note-editor .btn-primary.active,\n.open .dropdown-toggle.note-editor .btn-primary {\n  color: #ffffff;\n  background-color: #3276b1;\n  border-color: #285e8e;\n}\n.note-editor .btn-primary:active,\n.note-editor .btn-primary.active,\n.open .dropdown-toggle.note-editor .btn-primary {\n  background-image: none;\n}\n.note-editor .btn-primary.disabled,\n.note-editor .btn-primary[disabled],\nfieldset[disabled] .note-editor .btn-primary,\n.note-editor .btn-primary.disabled:hover,\n.note-editor .btn-primary[disabled]:hover,\nfieldset[disabled] .note-editor .btn-primary:hover,\n.note-editor .btn-primary.disabled:focus,\n.note-editor .btn-primary[disabled]:focus,\nfieldset[disabled] .note-editor .btn-primary:focus,\n.note-editor .btn-primary.disabled:active,\n.note-editor .btn-primary[disabled]:active,\nfieldset[disabled] .note-editor .btn-primary:active,\n.note-editor .btn-primary.disabled.active,\n.note-editor .btn-primary[disabled].active,\nfieldset[disabled] .note-editor .btn-primary.active {\n  background-color: #428bca;\n  border-color: #357ebd;\n}\n.note-editor .btn-warning {\n  color: #ffffff;\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.note-editor .btn-warning:hover,\n.note-editor .btn-warning:focus,\n.note-editor .btn-warning:active,\n.note-editor .btn-warning.active,\n.open .dropdown-toggle.note-editor .btn-warning {\n  color: #ffffff;\n  background-color: #ed9c28;\n  border-color: #d58512;\n}\n.note-editor .btn-warning:active,\n.note-editor .btn-warning.active,\n.open .dropdown-toggle.note-editor .btn-warning {\n  background-image: none;\n}\n.note-editor .btn-warning.disabled,\n.note-editor .btn-warning[disabled],\nfieldset[disabled] .note-editor .btn-warning,\n.note-editor .btn-warning.disabled:hover,\n.note-editor .btn-warning[disabled]:hover,\nfieldset[disabled] .note-editor .btn-warning:hover,\n.note-editor .btn-warning.disabled:focus,\n.note-editor .btn-warning[disabled]:focus,\nfieldset[disabled] .note-editor .btn-warning:focus,\n.note-editor .btn-warning.disabled:active,\n.note-editor .btn-warning[disabled]:active,\nfieldset[disabled] .note-editor .btn-warning:active,\n.note-editor .btn-warning.disabled.active,\n.note-editor .btn-warning[disabled].active,\nfieldset[disabled] .note-editor .btn-warning.active {\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.note-editor .btn-danger {\n  color: #ffffff;\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.note-editor .btn-danger:hover,\n.note-editor .btn-danger:focus,\n.note-editor .btn-danger:active,\n.note-editor .btn-danger.active,\n.open .dropdown-toggle.note-editor .btn-danger {\n  color: #ffffff;\n  background-color: #d2322d;\n  border-color: #ac2925;\n}\n.note-editor .btn-danger:active,\n.note-editor .btn-danger.active,\n.open .dropdown-toggle.note-editor .btn-danger {\n  background-image: none;\n}\n.note-editor .btn-danger.disabled,\n.note-editor .btn-danger[disabled],\nfieldset[disabled] .note-editor .btn-danger,\n.note-editor .btn-danger.disabled:hover,\n.note-editor .btn-danger[disabled]:hover,\nfieldset[disabled] .note-editor .btn-danger:hover,\n.note-editor .btn-danger.disabled:focus,\n.note-editor .btn-danger[disabled]:focus,\nfieldset[disabled] .note-editor .btn-danger:focus,\n.note-editor .btn-danger.disabled:active,\n.note-editor .btn-danger[disabled]:active,\nfieldset[disabled] .note-editor .btn-danger:active,\n.note-editor .btn-danger.disabled.active,\n.note-editor .btn-danger[disabled].active,\nfieldset[disabled] .note-editor .btn-danger.active {\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.note-editor .btn-success {\n  color: #ffffff;\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.note-editor .btn-success:hover,\n.note-editor .btn-success:focus,\n.note-editor .btn-success:active,\n.note-editor .btn-success.active,\n.open .dropdown-toggle.note-editor .btn-success {\n  color: #ffffff;\n  background-color: #47a447;\n  border-color: #398439;\n}\n.note-editor .btn-success:active,\n.note-editor .btn-success.active,\n.open .dropdown-toggle.note-editor .btn-success {\n  background-image: none;\n}\n.note-editor .btn-success.disabled,\n.note-editor .btn-success[disabled],\nfieldset[disabled] .note-editor .btn-success,\n.note-editor .btn-success.disabled:hover,\n.note-editor .btn-success[disabled]:hover,\nfieldset[disabled] .note-editor .btn-success:hover,\n.note-editor .btn-success.disabled:focus,\n.note-editor .btn-success[disabled]:focus,\nfieldset[disabled] .note-editor .btn-success:focus,\n.note-editor .btn-success.disabled:active,\n.note-editor .btn-success[disabled]:active,\nfieldset[disabled] .note-editor .btn-success:active,\n.note-editor .btn-success.disabled.active,\n.note-editor .btn-success[disabled].active,\nfieldset[disabled] .note-editor .btn-success.active {\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.note-editor .btn-info {\n  color: #ffffff;\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.note-editor .btn-info:hover,\n.note-editor .btn-info:focus,\n.note-editor .btn-info:active,\n.note-editor .btn-info.active,\n.open .dropdown-toggle.note-editor .btn-info {\n  color: #ffffff;\n  background-color: #39b3d7;\n  border-color: #269abc;\n}\n.note-editor .btn-info:active,\n.note-editor .btn-info.active,\n.open .dropdown-toggle.note-editor .btn-info {\n  background-image: none;\n}\n.note-editor .btn-info.disabled,\n.note-editor .btn-info[disabled],\nfieldset[disabled] .note-editor .btn-info,\n.note-editor .btn-info.disabled:hover,\n.note-editor .btn-info[disabled]:hover,\nfieldset[disabled] .note-editor .btn-info:hover,\n.note-editor .btn-info.disabled:focus,\n.note-editor .btn-info[disabled]:focus,\nfieldset[disabled] .note-editor .btn-info:focus,\n.note-editor .btn-info.disabled:active,\n.note-editor .btn-info[disabled]:active,\nfieldset[disabled] .note-editor .btn-info:active,\n.note-editor .btn-info.disabled.active,\n.note-editor .btn-info[disabled].active,\nfieldset[disabled] .note-editor .btn-info.active {\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.note-editor .btn-link {\n  color: #428bca;\n  font-weight: normal;\n  cursor: pointer;\n  border-radius: 0;\n}\n.note-editor .btn-link,\n.note-editor .btn-link:active,\n.note-editor .btn-link[disabled],\nfieldset[disabled] .note-editor .btn-link {\n  background-color: transparent;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n.note-editor .btn-link,\n.note-editor .btn-link:hover,\n.note-editor .btn-link:focus,\n.note-editor .btn-link:active {\n  border-color: transparent;\n}\n.note-editor .btn-link:hover,\n.note-editor .btn-link:focus {\n  color: #2a6496;\n  text-decoration: underline;\n  background-color: transparent;\n}\n.note-editor .btn-link[disabled]:hover,\nfieldset[disabled] .note-editor .btn-link:hover,\n.note-editor .btn-link[disabled]:focus,\nfieldset[disabled] .note-editor .btn-link:focus {\n  color: #999999;\n  text-decoration: none;\n}\n.note-editor .btn-lg {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.33;\n  border-radius: 6px;\n}\n.note-editor .btn-sm,\n.note-editor .btn-xs {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.note-editor .btn-xs {\n  padding: 1px 5px;\n}\n.note-editor .btn-block {\n  display: block;\n  width: 100%;\n  padding-left: 0;\n  padding-right: 0;\n}\n.note-editor .btn-block + .btn-block {\n  margin-top: 5px;\n}\n.note-editor input[type=\"submit\"].btn-block,\n.note-editor input[type=\"reset\"].btn-block,\n.note-editor input[type=\"button\"].btn-block {\n  width: 100%;\n}\n.note-editor .fade {\n  opacity: 0;\n  -webkit-transition: opacity 0.15s linear;\n  transition: opacity 0.15s linear;\n}\n.note-editor .fade.in {\n  opacity: 1;\n}\n.note-editor .collapse {\n  display: none;\n}\n.note-editor .collapse.in {\n  display: block;\n}\n.note-editor .collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition: height 0.35s ease;\n  transition: height 0.35s ease;\n}\n.note-editor .caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top: 4px solid #000000;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n  border-bottom: 0 dotted;\n}\n.note-editor .dropdown {\n  position: relative;\n}\n.note-editor .dropdown-toggle:focus {\n  outline: 0;\n}\n.note-editor .dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  list-style: none;\n  font-size: 14px;\n  background-color: #ffffff;\n  border: 1px solid #cccccc;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  background-clip: padding-box;\n}\n.note-editor .dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n.note-editor .dropdown-menu .divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.note-editor .dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 1.428571429;\n  color: #333333;\n  white-space: nowrap;\n}\n.note-editor .dropdown-menu > li > a:hover,\n.note-editor .dropdown-menu > li > a:focus {\n  text-decoration: none;\n  color: #262626;\n  background-color: #f5f5f5;\n}\n.note-editor .dropdown-menu > .active > a,\n.note-editor .dropdown-menu > .active > a:hover,\n.note-editor .dropdown-menu > .active > a:focus {\n  color: #ffffff;\n  text-decoration: none;\n  outline: 0;\n  background-color: #428bca;\n}\n.note-editor .dropdown-menu > .disabled > a,\n.note-editor .dropdown-menu > .disabled > a:hover,\n.note-editor .dropdown-menu > .disabled > a:focus {\n  color: #999999;\n}\n.note-editor .dropdown-menu > .disabled > a:hover,\n.note-editor .dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  cursor: not-allowed;\n}\n.note-editor .open > .dropdown-menu {\n  display: block;\n}\n.note-editor .open > a {\n  outline: 0;\n}\n.note-editor .dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: 12px;\n  line-height: 1.428571429;\n  color: #999999;\n}\n.note-editor .dropdown-backdrop {\n  position: fixed;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  top: 0;\n  z-index: 990;\n}\n.note-editor .pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n.note-editor .dropup .caret,\n.note-editor .navbar-fixed-bottom .dropdown .caret {\n  border-top: 0 dotted;\n  border-bottom: 4px solid #000000;\n  content: \"\";\n}\n.note-editor .dropup .dropdown-menu,\n.note-editor .navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 1px;\n}\n@media (min-width: 768px) {\n  .note-editor .navbar-right .dropdown-menu {\n    right: 0;\n    left: auto;\n  }\n}\n.btn-default .note-editor .caret {\n  border-top-color: #333333;\n}\n.btn-primary .note-editor .caret,\n.btn-success .note-editor .caret,\n.btn-warning .note-editor .caret,\n.btn-danger .note-editor .caret,\n.btn-info .note-editor .caret {\n  border-top-color: #fff;\n}\n.note-editor .dropup .btn-default .caret {\n  border-bottom-color: #333333;\n}\n.note-editor .dropup .btn-primary .caret,\n.note-editor .dropup .btn-success .caret,\n.note-editor .dropup .btn-warning .caret,\n.note-editor .dropup .btn-danger .caret,\n.note-editor .dropup .btn-info .caret {\n  border-bottom-color: #fff;\n}\n.note-editor .btn-group,\n.note-editor .btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n.note-editor .btn-group > .btn,\n.note-editor .btn-group-vertical > .btn {\n  position: relative;\n  float: left;\n}\n.note-editor .btn-group > .btn:hover,\n.note-editor .btn-group-vertical > .btn:hover,\n.note-editor .btn-group > .btn:focus,\n.note-editor .btn-group-vertical > .btn:focus,\n.note-editor .btn-group > .btn:active,\n.note-editor .btn-group-vertical > .btn:active,\n.note-editor .btn-group > .btn.active,\n.note-editor .btn-group-vertical > .btn.active {\n  z-index: 2;\n}\n.note-editor .btn-group > .btn:focus,\n.note-editor .btn-group-vertical > .btn:focus {\n  outline: none;\n}\n.note-editor .btn-group .btn + .btn,\n.note-editor .btn-group .btn + .btn-group,\n.note-editor .btn-group .btn-group + .btn,\n.note-editor .btn-group .btn-group + .btn-group {\n  margin-left: -1px;\n}\n.note-editor .btn-toolbar:before,\n.note-editor .btn-toolbar:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .btn-toolbar:after {\n  clear: both;\n}\n.note-editor .btn-toolbar:before,\n.note-editor .btn-toolbar:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .btn-toolbar:after {\n  clear: both;\n}\n.note-editor .btn-toolbar .btn-group {\n  float: left;\n}\n.note-editor .btn-toolbar > .btn + .btn,\n.note-editor .btn-toolbar > .btn-group + .btn,\n.note-editor .btn-toolbar > .btn + .btn-group,\n.note-editor .btn-toolbar > .btn-group + .btn-group {\n  margin-left: 5px;\n}\n.note-editor .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n.note-editor .btn-group > .btn:first-child {\n  margin-left: 0;\n}\n.note-editor .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.note-editor .btn-group > .btn:last-child:not(:first-child),\n.note-editor .btn-group > .dropdown-toggle:not(:first-child) {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n.note-editor .btn-group > .btn-group {\n  float: left;\n}\n.note-editor .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.note-editor .btn-group > .btn-group:first-child > .btn:last-child,\n.note-editor .btn-group > .btn-group:first-child > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.note-editor .btn-group > .btn-group:last-child > .btn:first-child {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n.note-editor .btn-group .dropdown-toggle:active,\n.note-editor .btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n.note-editor .btn-group-xs > .btn {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n  padding: 1px 5px;\n}\n.note-editor .btn-group-sm > .btn {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.note-editor .btn-group-lg > .btn {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.33;\n  border-radius: 6px;\n}\n.note-editor .btn-group > .btn + .dropdown-toggle {\n  padding-left: 5px;\n  padding-right: 5px;\n}\n.note-editor .btn-group > .btn-lg + .dropdown-toggle {\n  padding-left: 12px;\n  padding-right: 12px;\n}\n.note-editor .btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.note-editor .btn .caret {\n  margin-left: 0;\n}\n.note-editor .btn-lg .caret {\n  border-width: 5px 5px 0;\n  border-bottom-width: 0;\n}\n.note-editor .dropup .btn-lg .caret {\n  border-width: 0 5px 5px;\n}\n.note-editor .btn-group-vertical > .btn,\n.note-editor .btn-group-vertical > .btn-group {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n}\n.note-editor .btn-group-vertical > .btn-group:before,\n.note-editor .btn-group-vertical > .btn-group:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .btn-group-vertical > .btn-group:after {\n  clear: both;\n}\n.note-editor .btn-group-vertical > .btn-group:before,\n.note-editor .btn-group-vertical > .btn-group:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .btn-group-vertical > .btn-group:after {\n  clear: both;\n}\n.note-editor .btn-group-vertical > .btn-group > .btn {\n  float: none;\n}\n.note-editor .btn-group-vertical > .btn + .btn,\n.note-editor .btn-group-vertical > .btn + .btn-group,\n.note-editor .btn-group-vertical > .btn-group + .btn,\n.note-editor .btn-group-vertical > .btn-group + .btn-group {\n  margin-top: -1px;\n  margin-left: 0;\n}\n.note-editor .btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.note-editor .btn-group-vertical > .btn:first-child:not(:last-child) {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.note-editor .btn-group-vertical > .btn:last-child:not(:first-child) {\n  border-bottom-left-radius: 4px;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.note-editor .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.note-editor .btn-group-vertical > .btn-group:first-child > .btn:last-child,\n.note-editor .btn-group-vertical > .btn-group:first-child > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.note-editor .btn-group-vertical > .btn-group:last-child > .btn:first-child {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.note-editor .btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n}\n.note-editor .btn-group-justified .btn {\n  float: none;\n  display: table-cell;\n  width: 1%;\n}\n.note-editor [data-toggle=\"buttons\"] > .btn > input[type=\"radio\"],\n.note-editor [data-toggle=\"buttons\"] > .btn > input[type=\"checkbox\"] {\n  display: none;\n}\n.note-editor .input-group {\n  position: relative;\n  display: table;\n  border-collapse: separate;\n}\n.note-editor .input-group.col {\n  float: none;\n  padding-left: 0;\n  padding-right: 0;\n}\n.note-editor .input-group .form-control {\n  width: 100%;\n  margin-bottom: 0;\n}\n.note-editor .input-group-lg > .form-control,\n.note-editor .input-group-lg > .input-group-addon,\n.note-editor .input-group-lg > .input-group-btn > .btn {\n  height: 45px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.33;\n  border-radius: 6px;\n}\nselect.note-editor .input-group-lg > .form-control,\nselect.note-editor .input-group-lg > .input-group-addon,\nselect.note-editor .input-group-lg > .input-group-btn > .btn {\n  height: 45px;\n  line-height: 45px;\n}\ntextarea.note-editor .input-group-lg > .form-control,\ntextarea.note-editor .input-group-lg > .input-group-addon,\ntextarea.note-editor .input-group-lg > .input-group-btn > .btn {\n  height: auto;\n}\n.note-editor .input-group-sm > .form-control,\n.note-editor .input-group-sm > .input-group-addon,\n.note-editor .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.note-editor .input-group-sm > .form-control,\nselect.note-editor .input-group-sm > .input-group-addon,\nselect.note-editor .input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.note-editor .input-group-sm > .form-control,\ntextarea.note-editor .input-group-sm > .input-group-addon,\ntextarea.note-editor .input-group-sm > .input-group-btn > .btn {\n  height: auto;\n}\n.note-editor .input-group-addon,\n.note-editor .input-group-btn,\n.note-editor .input-group .form-control {\n  display: table-cell;\n}\n.note-editor .input-group-addon:not(:first-child):not(:last-child),\n.note-editor .input-group-btn:not(:first-child):not(:last-child),\n.note-editor .input-group .form-control:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.note-editor .input-group-addon,\n.note-editor .input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle;\n}\n.note-editor .input-group-addon {\n  padding: 6px 12px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1;\n  color: #555555;\n  text-align: center;\n  background-color: #eeeeee;\n  border: 1px solid #cccccc;\n  border-radius: 4px;\n}\n.note-editor .input-group-addon.input-sm {\n  padding: 5px 10px;\n  font-size: 12px;\n  border-radius: 3px;\n}\n.note-editor .input-group-addon.input-lg {\n  padding: 10px 16px;\n  font-size: 18px;\n  border-radius: 6px;\n}\n.note-editor .input-group-addon input[type=\"radio\"],\n.note-editor .input-group-addon input[type=\"checkbox\"] {\n  margin-top: 0;\n}\n.note-editor .input-group .form-control:first-child,\n.note-editor .input-group-addon:first-child,\n.note-editor .input-group-btn:first-child > .btn,\n.note-editor .input-group-btn:first-child > .dropdown-toggle,\n.note-editor .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.note-editor .input-group-addon:first-child {\n  border-right: 0;\n}\n.note-editor .input-group .form-control:last-child,\n.note-editor .input-group-addon:last-child,\n.note-editor .input-group-btn:last-child > .btn,\n.note-editor .input-group-btn:last-child > .dropdown-toggle,\n.note-editor .input-group-btn:first-child > .btn:not(:first-child) {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n.note-editor .input-group-addon:last-child {\n  border-left: 0;\n}\n.note-editor .input-group-btn {\n  position: relative;\n  white-space: nowrap;\n}\n.note-editor .input-group-btn:first-child > .btn {\n  margin-right: -1px;\n}\n.note-editor .input-group-btn:last-child > .btn {\n  margin-left: -1px;\n}\n.note-editor .input-group-btn > .btn {\n  position: relative;\n}\n.note-editor .input-group-btn > .btn + .btn {\n  margin-left: -4px;\n}\n.note-editor .input-group-btn > .btn:hover,\n.note-editor .input-group-btn > .btn:active {\n  z-index: 2;\n}\n.note-editor .nav {\n  margin-bottom: 0;\n  padding-left: 0;\n  list-style: none;\n}\n.note-editor .nav:before,\n.note-editor .nav:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .nav:after {\n  clear: both;\n}\n.note-editor .nav:before,\n.note-editor .nav:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .nav:after {\n  clear: both;\n}\n.note-editor .nav > li {\n  position: relative;\n  display: block;\n}\n.note-editor .nav > li > a {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n}\n.note-editor .nav > li > a:hover,\n.note-editor .nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n.note-editor .nav > li.disabled > a {\n  color: #999999;\n}\n.note-editor .nav > li.disabled > a:hover,\n.note-editor .nav > li.disabled > a:focus {\n  color: #999999;\n  text-decoration: none;\n  background-color: transparent;\n  cursor: not-allowed;\n}\n.note-editor .nav .open > a,\n.note-editor .nav .open > a:hover,\n.note-editor .nav .open > a:focus {\n  background-color: #eeeeee;\n  border-color: #428bca;\n}\n.note-editor .nav .open > a .caret,\n.note-editor .nav .open > a:hover .caret,\n.note-editor .nav .open > a:focus .caret {\n  border-top-color: #2a6496;\n  border-bottom-color: #2a6496;\n}\n.note-editor .nav .nav-divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.note-editor .nav > li > a > img {\n  max-width: none;\n}\n.note-editor .nav-tabs {\n  border-bottom: 1px solid #dddddd;\n}\n.note-editor .nav-tabs > li {\n  float: left;\n  margin-bottom: -1px;\n}\n.note-editor .nav-tabs > li > a {\n  margin-right: 2px;\n  line-height: 1.428571429;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n.note-editor .nav-tabs > li > a:hover {\n  border-color: #eeeeee #eeeeee #dddddd;\n}\n.note-editor .nav-tabs > li.active > a,\n.note-editor .nav-tabs > li.active > a:hover,\n.note-editor .nav-tabs > li.active > a:focus {\n  color: #555555;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-bottom-color: transparent;\n  cursor: default;\n}\n.note-editor .nav-tabs.nav-justified {\n  width: 100%;\n  border-bottom: 0;\n}\n.note-editor .nav-tabs.nav-justified > li {\n  float: none;\n}\n.note-editor .nav-tabs.nav-justified > li > a {\n  text-align: center;\n  margin-bottom: 5px;\n}\n@media (min-width: 768px) {\n  .note-editor .nav-tabs.nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .note-editor .nav-tabs.nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.note-editor .nav-tabs.nav-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.note-editor .nav-tabs.nav-justified > .active > a,\n.note-editor .nav-tabs.nav-justified > .active > a:hover,\n.note-editor .nav-tabs.nav-justified > .active > a:focus {\n  border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n  .note-editor .nav-tabs.nav-justified > li > a {\n    border-bottom: 1px solid #dddddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .note-editor .nav-tabs.nav-justified > .active > a,\n  .note-editor .nav-tabs.nav-justified > .active > a:hover,\n  .note-editor .nav-tabs.nav-justified > .active > a:focus {\n    border-bottom-color: #ffffff;\n  }\n}\n.note-editor .nav-pills > li {\n  float: left;\n}\n.note-editor .nav-pills > li > a {\n  border-radius: 4px;\n}\n.note-editor .nav-pills > li + li {\n  margin-left: 2px;\n}\n.note-editor .nav-pills > li.active > a,\n.note-editor .nav-pills > li.active > a:hover,\n.note-editor .nav-pills > li.active > a:focus {\n  color: #ffffff;\n  background-color: #428bca;\n}\n.note-editor .nav-pills > li.active > a .caret,\n.note-editor .nav-pills > li.active > a:hover .caret,\n.note-editor .nav-pills > li.active > a:focus .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n}\n.note-editor .nav-stacked > li {\n  float: none;\n}\n.note-editor .nav-stacked > li + li {\n  margin-top: 2px;\n  margin-left: 0;\n}\n.note-editor .nav-justified {\n  width: 100%;\n}\n.note-editor .nav-justified > li {\n  float: none;\n}\n.note-editor .nav-justified > li > a {\n  text-align: center;\n  margin-bottom: 5px;\n}\n@media (min-width: 768px) {\n  .note-editor .nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .note-editor .nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.note-editor .nav-tabs-justified {\n  border-bottom: 0;\n}\n.note-editor .nav-tabs-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.note-editor .nav-tabs-justified > .active > a,\n.note-editor .nav-tabs-justified > .active > a:hover,\n.note-editor .nav-tabs-justified > .active > a:focus {\n  border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n  .note-editor .nav-tabs-justified > li > a {\n    border-bottom: 1px solid #dddddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .note-editor .nav-tabs-justified > .active > a,\n  .note-editor .nav-tabs-justified > .active > a:hover,\n  .note-editor .nav-tabs-justified > .active > a:focus {\n    border-bottom-color: #ffffff;\n  }\n}\n.note-editor .tab-content > .tab-pane {\n  display: none;\n}\n.note-editor .tab-content > .active {\n  display: block;\n}\n.note-editor .nav .caret {\n  border-top-color: #428bca;\n  border-bottom-color: #428bca;\n}\n.note-editor .nav a:hover .caret {\n  border-top-color: #2a6496;\n  border-bottom-color: #2a6496;\n}\n.note-editor .nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.note-editor .navbar {\n  position: relative;\n  z-index: 1000;\n  min-height: 50px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n}\n.note-editor .navbar:before,\n.note-editor .navbar:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .navbar:after {\n  clear: both;\n}\n.note-editor .navbar:before,\n.note-editor .navbar:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .navbar:after {\n  clear: both;\n}\n@media (min-width: 768px) {\n  .note-editor .navbar {\n    border-radius: 4px;\n  }\n}\n.note-editor .navbar-header:before,\n.note-editor .navbar-header:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .navbar-header:after {\n  clear: both;\n}\n.note-editor .navbar-header:before,\n.note-editor .navbar-header:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .navbar-header:after {\n  clear: both;\n}\n@media (min-width: 768px) {\n  .note-editor .navbar-header {\n    float: left;\n  }\n}\n.note-editor .navbar-collapse {\n  max-height: 340px;\n  overflow-x: visible;\n  padding-right: 15px;\n  padding-left: 15px;\n  border-top: 1px solid transparent;\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n  -webkit-overflow-scrolling: touch;\n}\n.note-editor .navbar-collapse:before,\n.note-editor .navbar-collapse:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .navbar-collapse:after {\n  clear: both;\n}\n.note-editor .navbar-collapse:before,\n.note-editor .navbar-collapse:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .navbar-collapse:after {\n  clear: both;\n}\n.note-editor .navbar-collapse.in {\n  overflow-y: auto;\n}\n@media (min-width: 768px) {\n  .note-editor .navbar-collapse {\n    width: auto;\n    border-top: 0;\n    box-shadow: none;\n  }\n  .note-editor .navbar-collapse.collapse {\n    display: block !important;\n    height: auto !important;\n    padding-bottom: 0;\n    overflow: visible !important;\n  }\n  .note-editor .navbar-collapse.in {\n    overflow-y: visible;\n  }\n  .note-editor .navbar-collapse .navbar-nav.navbar-left:first-child {\n    margin-left: -15px;\n  }\n  .note-editor .navbar-collapse .navbar-nav.navbar-right:last-child {\n    margin-right: -15px;\n  }\n  .note-editor .navbar-collapse .navbar-text:last-child {\n    margin-right: 0;\n  }\n}\n.note-editor .container > .navbar-header,\n.note-editor .container > .navbar-collapse {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .note-editor .container > .navbar-header,\n  .note-editor .container > .navbar-collapse {\n    margin-right: 0;\n    margin-left: 0;\n  }\n}\n.note-editor .navbar-static-top {\n  border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n  .note-editor .navbar-static-top {\n    border-radius: 0;\n  }\n}\n.note-editor .navbar-fixed-top,\n.note-editor .navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n  .note-editor .navbar-fixed-top,\n  .note-editor .navbar-fixed-bottom {\n    border-radius: 0;\n  }\n}\n.note-editor .navbar-fixed-top {\n  z-index: 1030;\n  top: 0;\n}\n.note-editor .navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0;\n}\n.note-editor .navbar-brand {\n  float: left;\n  padding: 15px 15px;\n  font-size: 18px;\n  line-height: 20px;\n}\n.note-editor .navbar-brand:hover,\n.note-editor .navbar-brand:focus {\n  text-decoration: none;\n}\n@media (min-width: 768px) {\n  .navbar > .container .note-editor .navbar-brand {\n    margin-left: -15px;\n  }\n}\n.note-editor .navbar-toggle {\n  position: relative;\n  float: right;\n  margin-right: 15px;\n  padding: 9px 10px;\n  margin-top: 8px;\n  margin-bottom: 8px;\n  background-color: transparent;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.note-editor .navbar-toggle .icon-bar {\n  display: block;\n  width: 22px;\n  height: 2px;\n  border-radius: 1px;\n}\n.note-editor .navbar-toggle .icon-bar + .icon-bar {\n  margin-top: 4px;\n}\n@media (min-width: 768px) {\n  .note-editor .navbar-toggle {\n    display: none;\n  }\n}\n.note-editor .navbar-nav {\n  margin: 7.5px -15px;\n}\n.note-editor .navbar-nav > li > a {\n  padding-top: 10px;\n  padding-bottom: 10px;\n  line-height: 20px;\n}\n@media (max-width: 767px) {\n  .note-editor .navbar-nav .open .dropdown-menu {\n    position: static;\n    float: none;\n    width: auto;\n    margin-top: 0;\n    background-color: transparent;\n    border: 0;\n    box-shadow: none;\n  }\n  .note-editor .navbar-nav .open .dropdown-menu > li > a,\n  .note-editor .navbar-nav .open .dropdown-menu .dropdown-header {\n    padding: 5px 15px 5px 25px;\n  }\n  .note-editor .navbar-nav .open .dropdown-menu > li > a {\n    line-height: 20px;\n  }\n  .note-editor .navbar-nav .open .dropdown-menu > li > a:hover,\n  .note-editor .navbar-nav .open .dropdown-menu > li > a:focus {\n    background-image: none;\n  }\n}\n@media (min-width: 768px) {\n  .note-editor .navbar-nav {\n    float: left;\n    margin: 0;\n  }\n  .note-editor .navbar-nav > li {\n    float: left;\n  }\n  .note-editor .navbar-nav > li > a {\n    padding-top: 15px;\n    padding-bottom: 15px;\n  }\n}\n@media (min-width: 768px) {\n  .note-editor .navbar-left {\n    float: left !important;\n  }\n  .note-editor .navbar-right {\n    float: right !important;\n  }\n}\n.note-editor .navbar-form {\n  margin-left: -15px;\n  margin-right: -15px;\n  padding: 10px 15px;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n  .note-editor .navbar-form .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .note-editor .navbar-form .form-control {\n    display: inline-block;\n  }\n  .note-editor .navbar-form .radio,\n  .note-editor .navbar-form .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    padding-left: 0;\n  }\n  .note-editor .navbar-form .radio input[type=\"radio\"],\n  .note-editor .navbar-form .checkbox input[type=\"checkbox\"] {\n    float: none;\n    margin-left: 0;\n  }\n}\n@media (max-width: 767px) {\n  .note-editor .navbar-form .form-group {\n    margin-bottom: 5px;\n  }\n}\n@media (min-width: 768px) {\n  .note-editor .navbar-form {\n    width: auto;\n    border: 0;\n    margin-left: 0;\n    margin-right: 0;\n    padding-top: 0;\n    padding-bottom: 0;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n  }\n}\n.note-editor .navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.note-editor .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.note-editor .navbar-nav.pull-right > li > .dropdown-menu,\n.note-editor .navbar-nav > li > .dropdown-menu.pull-right {\n  left: auto;\n  right: 0;\n}\n.note-editor .navbar-btn {\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n.note-editor .navbar-text {\n  float: left;\n  margin-top: 15px;\n  margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n  .note-editor .navbar-text {\n    margin-left: 15px;\n    margin-right: 15px;\n  }\n}\n.note-editor .navbar-default {\n  background-color: #f8f8f8;\n  border-color: #e7e7e7;\n}\n.note-editor .navbar-default .navbar-brand {\n  color: #777777;\n}\n.note-editor .navbar-default .navbar-brand:hover,\n.note-editor .navbar-default .navbar-brand:focus {\n  color: #5e5e5e;\n  background-color: transparent;\n}\n.note-editor .navbar-default .navbar-text {\n  color: #777777;\n}\n.note-editor .navbar-default .navbar-nav > li > a {\n  color: #777777;\n}\n.note-editor .navbar-default .navbar-nav > li > a:hover,\n.note-editor .navbar-default .navbar-nav > li > a:focus {\n  color: #333333;\n  background-color: transparent;\n}\n.note-editor .navbar-default .navbar-nav > .active > a,\n.note-editor .navbar-default .navbar-nav > .active > a:hover,\n.note-editor .navbar-default .navbar-nav > .active > a:focus {\n  color: #555555;\n  background-color: #e7e7e7;\n}\n.note-editor .navbar-default .navbar-nav > .disabled > a,\n.note-editor .navbar-default .navbar-nav > .disabled > a:hover,\n.note-editor .navbar-default .navbar-nav > .disabled > a:focus {\n  color: #cccccc;\n  background-color: transparent;\n}\n.note-editor .navbar-default .navbar-toggle {\n  border-color: #dddddd;\n}\n.note-editor .navbar-default .navbar-toggle:hover,\n.note-editor .navbar-default .navbar-toggle:focus {\n  background-color: #dddddd;\n}\n.note-editor .navbar-default .navbar-toggle .icon-bar {\n  background-color: #cccccc;\n}\n.note-editor .navbar-default .navbar-collapse,\n.note-editor .navbar-default .navbar-form {\n  border-color: #e7e7e7;\n}\n.note-editor .navbar-default .navbar-nav > .dropdown > a:hover .caret,\n.note-editor .navbar-default .navbar-nav > .dropdown > a:focus .caret {\n  border-top-color: #333333;\n  border-bottom-color: #333333;\n}\n.note-editor .navbar-default .navbar-nav > .open > a,\n.note-editor .navbar-default .navbar-nav > .open > a:hover,\n.note-editor .navbar-default .navbar-nav > .open > a:focus {\n  background-color: #e7e7e7;\n  color: #555555;\n}\n.note-editor .navbar-default .navbar-nav > .open > a .caret,\n.note-editor .navbar-default .navbar-nav > .open > a:hover .caret,\n.note-editor .navbar-default .navbar-nav > .open > a:focus .caret {\n  border-top-color: #555555;\n  border-bottom-color: #555555;\n}\n.note-editor .navbar-default .navbar-nav > .dropdown > a .caret {\n  border-top-color: #777777;\n  border-bottom-color: #777777;\n}\n@media (max-width: 767px) {\n  .note-editor .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n    color: #777777;\n  }\n  .note-editor .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n  .note-editor .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #333333;\n    background-color: transparent;\n  }\n  .note-editor .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n  .note-editor .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .note-editor .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #555555;\n    background-color: #e7e7e7;\n  }\n  .note-editor .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n  .note-editor .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .note-editor .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #cccccc;\n    background-color: transparent;\n  }\n}\n.note-editor .navbar-default .navbar-link {\n  color: #777777;\n}\n.note-editor .navbar-default .navbar-link:hover {\n  color: #333333;\n}\n.note-editor .navbar-inverse {\n  background-color: #222222;\n  border-color: #080808;\n}\n.note-editor .navbar-inverse .navbar-brand {\n  color: #999999;\n}\n.note-editor .navbar-inverse .navbar-brand:hover,\n.note-editor .navbar-inverse .navbar-brand:focus {\n  color: #ffffff;\n  background-color: transparent;\n}\n.note-editor .navbar-inverse .navbar-text {\n  color: #999999;\n}\n.note-editor .navbar-inverse .navbar-nav > li > a {\n  color: #999999;\n}\n.note-editor .navbar-inverse .navbar-nav > li > a:hover,\n.note-editor .navbar-inverse .navbar-nav > li > a:focus {\n  color: #ffffff;\n  background-color: transparent;\n}\n.note-editor .navbar-inverse .navbar-nav > .active > a,\n.note-editor .navbar-inverse .navbar-nav > .active > a:hover,\n.note-editor .navbar-inverse .navbar-nav > .active > a:focus {\n  color: #ffffff;\n  background-color: #080808;\n}\n.note-editor .navbar-inverse .navbar-nav > .disabled > a,\n.note-editor .navbar-inverse .navbar-nav > .disabled > a:hover,\n.note-editor .navbar-inverse .navbar-nav > .disabled > a:focus {\n  color: #444444;\n  background-color: transparent;\n}\n.note-editor .navbar-inverse .navbar-toggle {\n  border-color: #333333;\n}\n.note-editor .navbar-inverse .navbar-toggle:hover,\n.note-editor .navbar-inverse .navbar-toggle:focus {\n  background-color: #333333;\n}\n.note-editor .navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #ffffff;\n}\n.note-editor .navbar-inverse .navbar-collapse,\n.note-editor .navbar-inverse .navbar-form {\n  border-color: #101010;\n}\n.note-editor .navbar-inverse .navbar-nav > .open > a,\n.note-editor .navbar-inverse .navbar-nav > .open > a:hover,\n.note-editor .navbar-inverse .navbar-nav > .open > a:focus {\n  background-color: #080808;\n  color: #ffffff;\n}\n.note-editor .navbar-inverse .navbar-nav > .dropdown > a:hover .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n}\n.note-editor .navbar-inverse .navbar-nav > .dropdown > a .caret {\n  border-top-color: #999999;\n  border-bottom-color: #999999;\n}\n.note-editor .navbar-inverse .navbar-nav > .open > a .caret,\n.note-editor .navbar-inverse .navbar-nav > .open > a:hover .caret,\n.note-editor .navbar-inverse .navbar-nav > .open > a:focus .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n}\n@media (max-width: 767px) {\n  .note-editor .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n    border-color: #080808;\n  }\n  .note-editor .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n    color: #999999;\n  }\n  .note-editor .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n  .note-editor .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #ffffff;\n    background-color: transparent;\n  }\n  .note-editor .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n  .note-editor .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .note-editor .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #ffffff;\n    background-color: #080808;\n  }\n  .note-editor .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n  .note-editor .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .note-editor .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #444444;\n    background-color: transparent;\n  }\n}\n.note-editor .navbar-inverse .navbar-link {\n  color: #999999;\n}\n.note-editor .navbar-inverse .navbar-link:hover {\n  color: #ffffff;\n}\n.note-editor .breadcrumb {\n  padding: 8px 15px;\n  margin-bottom: 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n}\n.note-editor .breadcrumb > li {\n  display: inline-block;\n}\n.note-editor .breadcrumb > li + li:before {\n  content: \"/\\00a0\";\n  padding: 0 5px;\n  color: #cccccc;\n}\n.note-editor .breadcrumb > .active {\n  color: #999999;\n}\n.note-editor .pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: 20px 0;\n  border-radius: 4px;\n}\n.note-editor .pagination > li {\n  display: inline;\n}\n.note-editor .pagination > li > a,\n.note-editor .pagination > li > span {\n  position: relative;\n  float: left;\n  padding: 6px 12px;\n  line-height: 1.428571429;\n  text-decoration: none;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  margin-left: -1px;\n}\n.note-editor .pagination > li:first-child > a,\n.note-editor .pagination > li:first-child > span {\n  margin-left: 0;\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 4px;\n}\n.note-editor .pagination > li:last-child > a,\n.note-editor .pagination > li:last-child > span {\n  border-bottom-right-radius: 4px;\n  border-top-right-radius: 4px;\n}\n.note-editor .pagination > li > a:hover,\n.note-editor .pagination > li > span:hover,\n.note-editor .pagination > li > a:focus,\n.note-editor .pagination > li > span:focus {\n  background-color: #eeeeee;\n}\n.note-editor .pagination > .active > a,\n.note-editor .pagination > .active > span,\n.note-editor .pagination > .active > a:hover,\n.note-editor .pagination > .active > span:hover,\n.note-editor .pagination > .active > a:focus,\n.note-editor .pagination > .active > span:focus {\n  z-index: 2;\n  color: #ffffff;\n  background-color: #428bca;\n  border-color: #428bca;\n  cursor: default;\n}\n.note-editor .pagination > .disabled > span,\n.note-editor .pagination > .disabled > span:hover,\n.note-editor .pagination > .disabled > span:focus,\n.note-editor .pagination > .disabled > a,\n.note-editor .pagination > .disabled > a:hover,\n.note-editor .pagination > .disabled > a:focus {\n  color: #999999;\n  background-color: #ffffff;\n  border-color: #dddddd;\n  cursor: not-allowed;\n}\n.note-editor .pagination-lg > li > a,\n.note-editor .pagination-lg > li > span {\n  padding: 10px 16px;\n  font-size: 18px;\n}\n.note-editor .pagination-lg > li:first-child > a,\n.note-editor .pagination-lg > li:first-child > span {\n  border-bottom-left-radius: 6px;\n  border-top-left-radius: 6px;\n}\n.note-editor .pagination-lg > li:last-child > a,\n.note-editor .pagination-lg > li:last-child > span {\n  border-bottom-right-radius: 6px;\n  border-top-right-radius: 6px;\n}\n.note-editor .pagination-sm > li > a,\n.note-editor .pagination-sm > li > span {\n  padding: 5px 10px;\n  font-size: 12px;\n}\n.note-editor .pagination-sm > li:first-child > a,\n.note-editor .pagination-sm > li:first-child > span {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.note-editor .pagination-sm > li:last-child > a,\n.note-editor .pagination-sm > li:last-child > span {\n  border-bottom-right-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.note-editor .pager {\n  padding-left: 0;\n  margin: 20px 0;\n  list-style: none;\n  text-align: center;\n}\n.note-editor .pager:before,\n.note-editor .pager:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .pager:after {\n  clear: both;\n}\n.note-editor .pager:before,\n.note-editor .pager:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .pager:after {\n  clear: both;\n}\n.note-editor .pager li {\n  display: inline;\n}\n.note-editor .pager li > a,\n.note-editor .pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 15px;\n}\n.note-editor .pager li > a:hover,\n.note-editor .pager li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n.note-editor .pager .next > a,\n.note-editor .pager .next > span {\n  float: right;\n}\n.note-editor .pager .previous > a,\n.note-editor .pager .previous > span {\n  float: left;\n}\n.note-editor .pager .disabled > a,\n.note-editor .pager .disabled > a:hover,\n.note-editor .pager .disabled > a:focus,\n.note-editor .pager .disabled > span {\n  color: #999999;\n  background-color: #ffffff;\n  cursor: not-allowed;\n}\n.note-editor .label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: #ffffff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n}\n.note-editor .label[href]:hover,\n.note-editor .label[href]:focus {\n  color: #ffffff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.note-editor .label:empty {\n  display: none;\n}\n.note-editor .label-default {\n  background-color: #999999;\n}\n.note-editor .label-default[href]:hover,\n.note-editor .label-default[href]:focus {\n  background-color: #808080;\n}\n.note-editor .label-primary {\n  background-color: #428bca;\n}\n.note-editor .label-primary[href]:hover,\n.note-editor .label-primary[href]:focus {\n  background-color: #3071a9;\n}\n.note-editor .label-success {\n  background-color: #5cb85c;\n}\n.note-editor .label-success[href]:hover,\n.note-editor .label-success[href]:focus {\n  background-color: #449d44;\n}\n.note-editor .label-info {\n  background-color: #5bc0de;\n}\n.note-editor .label-info[href]:hover,\n.note-editor .label-info[href]:focus {\n  background-color: #31b0d5;\n}\n.note-editor .label-warning {\n  background-color: #f0ad4e;\n}\n.note-editor .label-warning[href]:hover,\n.note-editor .label-warning[href]:focus {\n  background-color: #ec971f;\n}\n.note-editor .label-danger {\n  background-color: #d9534f;\n}\n.note-editor .label-danger[href]:hover,\n.note-editor .label-danger[href]:focus {\n  background-color: #c9302c;\n}\n.note-editor .badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: 12px;\n  font-weight: bold;\n  color: #ffffff;\n  line-height: 1;\n  vertical-align: baseline;\n  white-space: nowrap;\n  text-align: center;\n  background-color: #999999;\n  border-radius: 10px;\n}\n.note-editor .badge:empty {\n  display: none;\n}\n.note-editor a.badge:hover,\n.note-editor a.badge:focus {\n  color: #ffffff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.note-editor .btn .badge {\n  position: relative;\n  top: -1px;\n}\n.note-editor a.list-group-item.active > .badge,\n.note-editor .nav-pills > .active > a > .badge {\n  color: #428bca;\n  background-color: #ffffff;\n}\n.note-editor .nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n.note-editor .jumbotron {\n  padding: 30px;\n  margin-bottom: 30px;\n  font-size: 21px;\n  font-weight: 200;\n  line-height: 2.1428571435;\n  color: inherit;\n  background-color: #eeeeee;\n}\n.note-editor .jumbotron h1 {\n  line-height: 1;\n  color: inherit;\n}\n.note-editor .jumbotron p {\n  line-height: 1.4;\n}\n.container .note-editor .jumbotron {\n  border-radius: 6px;\n}\n@media screen and (min-width: 768px) {\n  .note-editor .jumbotron {\n    padding-top: 48px;\n    padding-bottom: 48px;\n  }\n  .container .note-editor .jumbotron {\n    padding-left: 60px;\n    padding-right: 60px;\n  }\n  .note-editor .jumbotron h1 {\n    font-size: 63px;\n  }\n}\n.note-editor .thumbnail {\n  padding: 4px;\n  line-height: 1.428571429;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 4px;\n  -webkit-transition: all 0.2s ease-in-out;\n  transition: all 0.2s ease-in-out;\n  display: inline-block;\n  max-width: 100%;\n  height: auto;\n  display: block;\n  margin-bottom: 20px;\n}\n.note-editor .thumbnail > img {\n  display: block;\n  max-width: 100%;\n  height: auto;\n}\n.note-editor a.thumbnail:hover,\n.note-editor a.thumbnail:focus,\n.note-editor a.thumbnail.active {\n  border-color: #428bca;\n}\n.note-editor .thumbnail > img {\n  margin-left: auto;\n  margin-right: auto;\n}\n.note-editor .thumbnail .caption {\n  padding: 9px;\n  color: #333333;\n}\n.note-editor .alert {\n  padding: 15px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.note-editor .alert h4 {\n  margin-top: 0;\n  color: inherit;\n}\n.note-editor .alert .alert-link {\n  font-weight: bold;\n}\n.note-editor .alert > p,\n.note-editor .alert > ul {\n  margin-bottom: 0;\n}\n.note-editor .alert > p + p {\n  margin-top: 5px;\n}\n.note-editor .alert-dismissable {\n  padding-right: 35px;\n}\n.note-editor .alert-dismissable .close {\n  position: relative;\n  top: -2px;\n  right: -21px;\n  color: inherit;\n}\n.note-editor .alert-success {\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n  color: #468847;\n}\n.note-editor .alert-success hr {\n  border-top-color: #c9e2b3;\n}\n.note-editor .alert-success .alert-link {\n  color: #356635;\n}\n.note-editor .alert-info {\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n  color: #3a87ad;\n}\n.note-editor .alert-info hr {\n  border-top-color: #a6e1ec;\n}\n.note-editor .alert-info .alert-link {\n  color: #2d6987;\n}\n.note-editor .alert-warning {\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n  color: #c09853;\n}\n.note-editor .alert-warning hr {\n  border-top-color: #f7e1b5;\n}\n.note-editor .alert-warning .alert-link {\n  color: #a47e3c;\n}\n.note-editor .alert-danger {\n  background-color: #f2dede;\n  border-color: #ebccd1;\n  color: #b94a48;\n}\n.note-editor .alert-danger hr {\n  border-top-color: #e4b9c0;\n}\n.note-editor .alert-danger .alert-link {\n  color: #953b39;\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@-moz-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: 0 0;\n  }\n  to {\n    background-position: 40px 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.note-editor .progress {\n  overflow: hidden;\n  height: 20px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.note-editor .progress-bar {\n  float: left;\n  width: 0%;\n  height: 100%;\n  font-size: 12px;\n  line-height: 20px;\n  color: #ffffff;\n  text-align: center;\n  background-color: #428bca;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n  -webkit-transition: width 0.6s ease;\n  transition: width 0.6s ease;\n}\n.note-editor .progress-striped .progress-bar {\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-size: 40px 40px;\n}\n.note-editor .progress.active .progress-bar {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n  -moz-animation: progress-bar-stripes 2s linear infinite;\n  -ms-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.note-editor .progress-bar-success {\n  background-color: #5cb85c;\n}\n.progress-striped .note-editor .progress-bar-success {\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.note-editor .progress-bar-info {\n  background-color: #5bc0de;\n}\n.progress-striped .note-editor .progress-bar-info {\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.note-editor .progress-bar-warning {\n  background-color: #f0ad4e;\n}\n.progress-striped .note-editor .progress-bar-warning {\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.note-editor .progress-bar-danger {\n  background-color: #d9534f;\n}\n.progress-striped .note-editor .progress-bar-danger {\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.note-editor .media,\n.note-editor .media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n.note-editor .media,\n.note-editor .media .media {\n  margin-top: 15px;\n}\n.note-editor .media:first-child {\n  margin-top: 0;\n}\n.note-editor .media-object {\n  display: block;\n}\n.note-editor .media-heading {\n  margin: 0 0 5px;\n}\n.note-editor .media > .pull-left {\n  margin-right: 10px;\n}\n.note-editor .media > .pull-right {\n  margin-left: 10px;\n}\n.note-editor .media-list {\n  padding-left: 0;\n  list-style: none;\n}\n.note-editor .list-group {\n  margin-bottom: 20px;\n  padding-left: 0;\n}\n.note-editor .list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  margin-bottom: -1px;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n}\n.note-editor .list-group-item:first-child {\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n}\n.note-editor .list-group-item:last-child {\n  margin-bottom: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n.note-editor .list-group-item > .badge {\n  float: right;\n}\n.note-editor .list-group-item > .badge + .badge {\n  margin-right: 5px;\n}\n.note-editor a.list-group-item {\n  color: #555555;\n}\n.note-editor a.list-group-item .list-group-item-heading {\n  color: #333333;\n}\n.note-editor a.list-group-item:hover,\n.note-editor a.list-group-item:focus {\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n.note-editor a.list-group-item.active,\n.note-editor a.list-group-item.active:hover,\n.note-editor a.list-group-item.active:focus {\n  z-index: 2;\n  color: #ffffff;\n  background-color: #428bca;\n  border-color: #428bca;\n}\n.note-editor a.list-group-item.active .list-group-item-heading,\n.note-editor a.list-group-item.active:hover .list-group-item-heading,\n.note-editor a.list-group-item.active:focus .list-group-item-heading {\n  color: inherit;\n}\n.note-editor a.list-group-item.active .list-group-item-text,\n.note-editor a.list-group-item.active:hover .list-group-item-text,\n.note-editor a.list-group-item.active:focus .list-group-item-text {\n  color: #e1edf7;\n}\n.note-editor .list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.note-editor .list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n.note-editor .panel {\n  margin-bottom: 20px;\n  background-color: #ffffff;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.note-editor .panel-body {\n  padding: 15px;\n}\n.note-editor .panel-body:before,\n.note-editor .panel-body:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .panel-body:after {\n  clear: both;\n}\n.note-editor .panel-body:before,\n.note-editor .panel-body:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.note-editor .panel-body:after {\n  clear: both;\n}\n.note-editor .panel > .list-group {\n  margin-bottom: 0;\n}\n.note-editor .panel > .list-group .list-group-item {\n  border-width: 1px 0;\n}\n.note-editor .panel > .list-group .list-group-item:first-child {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.note-editor .panel > .list-group .list-group-item:last-child {\n  border-bottom: 0;\n}\n.note-editor .panel-heading + .list-group .list-group-item:first-child {\n  border-top-width: 0;\n}\n.note-editor .panel > .table,\n.note-editor .panel > .table-responsive {\n  margin-bottom: 0;\n}\n.note-editor .panel > .panel-body + .table,\n.note-editor .panel > .panel-body + .table-responsive {\n  border-top: 1px solid #dddddd;\n}\n.note-editor .panel > .table-bordered,\n.note-editor .panel > .table-responsive > .table-bordered {\n  border: 0;\n}\n.note-editor .panel > .table-bordered > thead > tr > th:first-child,\n.note-editor .panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.note-editor .panel > .table-bordered > tbody > tr > th:first-child,\n.note-editor .panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.note-editor .panel > .table-bordered > tfoot > tr > th:first-child,\n.note-editor .panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.note-editor .panel > .table-bordered > thead > tr > td:first-child,\n.note-editor .panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.note-editor .panel > .table-bordered > tbody > tr > td:first-child,\n.note-editor .panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.note-editor .panel > .table-bordered > tfoot > tr > td:first-child,\n.note-editor .panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n  border-left: 0;\n}\n.note-editor .panel > .table-bordered > thead > tr > th:last-child,\n.note-editor .panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.note-editor .panel > .table-bordered > tbody > tr > th:last-child,\n.note-editor .panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.note-editor .panel > .table-bordered > tfoot > tr > th:last-child,\n.note-editor .panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.note-editor .panel > .table-bordered > thead > tr > td:last-child,\n.note-editor .panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.note-editor .panel > .table-bordered > tbody > tr > td:last-child,\n.note-editor .panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.note-editor .panel > .table-bordered > tfoot > tr > td:last-child,\n.note-editor .panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n  border-right: 0;\n}\n.note-editor .panel > .table-bordered > thead > tr:last-child > th,\n.note-editor .panel > .table-responsive > .table-bordered > thead > tr:last-child > th,\n.note-editor .panel > .table-bordered > tbody > tr:last-child > th,\n.note-editor .panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.note-editor .panel > .table-bordered > tfoot > tr:last-child > th,\n.note-editor .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n.note-editor .panel > .table-bordered > thead > tr:last-child > td,\n.note-editor .panel > .table-responsive > .table-bordered > thead > tr:last-child > td,\n.note-editor .panel > .table-bordered > tbody > tr:last-child > td,\n.note-editor .panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.note-editor .panel > .table-bordered > tfoot > tr:last-child > td,\n.note-editor .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n  border-bottom: 0;\n}\n.note-editor .panel-heading {\n  padding: 10px 15px;\n  border-bottom: 1px solid transparent;\n  border-top-right-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.note-editor .panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: 16px;\n}\n.note-editor .panel-title > a {\n  color: inherit;\n}\n.note-editor .panel-footer {\n  padding: 10px 15px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #dddddd;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.note-editor .panel-group .panel {\n  margin-bottom: 0;\n  border-radius: 4px;\n  overflow: hidden;\n}\n.note-editor .panel-group .panel + .panel {\n  margin-top: 5px;\n}\n.note-editor .panel-group .panel-heading {\n  border-bottom: 0;\n}\n.note-editor .panel-group .panel-heading + .panel-collapse .panel-body {\n  border-top: 1px solid #dddddd;\n}\n.note-editor .panel-group .panel-footer {\n  border-top: 0;\n}\n.note-editor .panel-group .panel-footer + .panel-collapse .panel-body {\n  border-bottom: 1px solid #dddddd;\n}\n.note-editor .panel-default {\n  border-color: #dddddd;\n}\n.note-editor .panel-default > .panel-heading {\n  color: #333333;\n  background-color: #f5f5f5;\n  border-color: #dddddd;\n}\n.note-editor .panel-default > .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #dddddd;\n}\n.note-editor .panel-default > .panel-footer + .panel-collapse .panel-body {\n  border-bottom-color: #dddddd;\n}\n.note-editor .panel-primary {\n  border-color: #428bca;\n}\n.note-editor .panel-primary > .panel-heading {\n  color: #ffffff;\n  background-color: #428bca;\n  border-color: #428bca;\n}\n.note-editor .panel-primary > .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #428bca;\n}\n.note-editor .panel-primary > .panel-footer + .panel-collapse .panel-body {\n  border-bottom-color: #428bca;\n}\n.note-editor .panel-success {\n  border-color: #d6e9c6;\n}\n.note-editor .panel-success > .panel-heading {\n  color: #468847;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.note-editor .panel-success > .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #d6e9c6;\n}\n.note-editor .panel-success > .panel-footer + .panel-collapse .panel-body {\n  border-bottom-color: #d6e9c6;\n}\n.note-editor .panel-warning {\n  border-color: #faebcc;\n}\n.note-editor .panel-warning > .panel-heading {\n  color: #c09853;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.note-editor .panel-warning > .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #faebcc;\n}\n.note-editor .panel-warning > .panel-footer + .panel-collapse .panel-body {\n  border-bottom-color: #faebcc;\n}\n.note-editor .panel-danger {\n  border-color: #ebccd1;\n}\n.note-editor .panel-danger > .panel-heading {\n  color: #b94a48;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.note-editor .panel-danger > .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #ebccd1;\n}\n.note-editor .panel-danger > .panel-footer + .panel-collapse .panel-body {\n  border-bottom-color: #ebccd1;\n}\n.note-editor .panel-info {\n  border-color: #bce8f1;\n}\n.note-editor .panel-info > .panel-heading {\n  color: #3a87ad;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.note-editor .panel-info > .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #bce8f1;\n}\n.note-editor .panel-info > .panel-footer + .panel-collapse .panel-body {\n  border-bottom-color: #bce8f1;\n}\n.note-editor .well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.note-editor .well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, 0.15);\n}\n.note-editor .well-lg {\n  padding: 24px;\n  border-radius: 6px;\n}\n.note-editor .well-sm {\n  padding: 9px;\n  border-radius: 3px;\n}\n.note-editor .close {\n  float: right;\n  font-size: 21px;\n  font-weight: bold;\n  line-height: 1;\n  color: #000000;\n  text-shadow: 0 1px 0 #ffffff;\n  opacity: 0.2;\n  filter: alpha(opacity=20);\n}\n.note-editor .close:hover,\n.note-editor .close:focus {\n  color: #000000;\n  text-decoration: none;\n  cursor: pointer;\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\nbutton.note-editor .close {\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n  -webkit-appearance: none;\n}\n.modal-open {\n  overflow: hidden;\n}\n.modal {\n  display: none;\n  overflow: auto;\n  overflow-y: scroll;\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n}\n.modal.fade .modal-dialog {\n  -webkit-transform: translate(0, -25%);\n  -ms-transform: translate(0, -25%);\n  transform: translate(0, -25%);\n  -webkit-transition: -webkit-transform 0.3s ease-out;\n  -moz-transition: -moz-transform 0.3s ease-out;\n  -o-transition: -o-transform 0.3s ease-out;\n  transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n  -webkit-transform: translate(0, 0);\n  -ms-transform: translate(0, 0);\n  transform: translate(0, 0);\n}\n.modal-dialog {\n  margin-left: auto;\n  margin-right: auto;\n  width: auto;\n  padding: 10px;\n  z-index: 1050;\n}\n.modal-content {\n  position: relative;\n  background-color: #ffffff;\n  border: 1px solid #999999;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n  box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n  background-clip: padding-box;\n  outline: none;\n}\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1030;\n  background-color: #000000;\n}\n.modal-backdrop.fade {\n  opacity: 0;\n  filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n.modal-header {\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\n  min-height: 16.428571429px;\n}\n.modal-header .close {\n  margin-top: -2px;\n}\n.modal-title {\n  margin: 0;\n  line-height: 1.428571429;\n}\n.modal-body {\n  position: relative;\n  padding: 20px;\n}\n.modal-footer {\n  margin-top: 15px;\n  padding: 19px 20px 20px;\n  text-align: right;\n  border-top: 1px solid #e5e5e5;\n}\n.modal-footer:before,\n.modal-footer:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.modal-footer:after {\n  clear: both;\n}\n.modal-footer:before,\n.modal-footer:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.modal-footer:after {\n  clear: both;\n}\n.modal-footer .btn + .btn {\n  margin-left: 5px;\n  margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n@media screen and (min-width: 768px) {\n  .modal-dialog {\n    width: 600px;\n    padding-top: 30px;\n    padding-bottom: 30px;\n  }\n  .modal-content {\n    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n  }\n}\n.tooltip {\n  position: absolute;\n  z-index: 1030;\n  display: block;\n  visibility: visible;\n  font-size: 12px;\n  line-height: 1.4;\n  opacity: 0;\n  filter: alpha(opacity=0);\n}\n.tooltip.in {\n  opacity: 0.9;\n  filter: alpha(opacity=90);\n}\n.tooltip.top {\n  margin-top: -3px;\n  padding: 5px 0;\n}\n.tooltip.right {\n  margin-left: 3px;\n  padding: 0 5px;\n}\n.tooltip.bottom {\n  margin-top: 3px;\n  padding: 5px 0;\n}\n.tooltip.left {\n  margin-left: -3px;\n  padding: 0 5px;\n}\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #ffffff;\n  text-align: center;\n  text-decoration: none;\n  background-color: #000000;\n  border-radius: 4px;\n}\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000000;\n}\n.tooltip.top-left .tooltip-arrow {\n  bottom: 0;\n  left: 5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000000;\n}\n.tooltip.top-right .tooltip-arrow {\n  bottom: 0;\n  right: 5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000000;\n}\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-width: 5px 5px 5px 0;\n  border-right-color: #000000;\n}\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-width: 5px 0 5px 5px;\n  border-left-color: #000000;\n}\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n  top: 0;\n  left: 5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n  top: 0;\n  right: 5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000000;\n}\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1010;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  text-align: left;\n  background-color: #ffffff;\n  background-clip: padding-box;\n  border: 1px solid #cccccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  white-space: normal;\n}\n.popover.top {\n  margin-top: -10px;\n}\n.popover.right {\n  margin-left: 10px;\n}\n.popover.bottom {\n  margin-top: 10px;\n}\n.popover.left {\n  margin-left: -10px;\n}\n.popover-title {\n  margin: 0;\n  padding: 8px 14px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 18px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  border-radius: 5px 5px 0 0;\n}\n.popover-content {\n  padding: 9px 14px;\n}\n.popover .arrow,\n.popover .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.popover .arrow {\n  border-width: 11px;\n}\n.popover .arrow:after {\n  border-width: 10px;\n  content: \"\";\n}\n.popover.top .arrow {\n  left: 50%;\n  margin-left: -11px;\n  border-bottom-width: 0;\n  border-top-color: #999999;\n  border-top-color: rgba(0, 0, 0, 0.25);\n  bottom: -11px;\n}\n.popover.top .arrow:after {\n  content: \" \";\n  bottom: 1px;\n  margin-left: -10px;\n  border-bottom-width: 0;\n  border-top-color: #ffffff;\n}\n.popover.right .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-left-width: 0;\n  border-right-color: #999999;\n  border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right .arrow:after {\n  content: \" \";\n  left: 1px;\n  bottom: -10px;\n  border-left-width: 0;\n  border-right-color: #ffffff;\n}\n.popover.bottom .arrow {\n  left: 50%;\n  margin-left: -11px;\n  border-top-width: 0;\n  border-bottom-color: #999999;\n  border-bottom-color: rgba(0, 0, 0, 0.25);\n  top: -11px;\n}\n.popover.bottom .arrow:after {\n  content: \" \";\n  top: 1px;\n  margin-left: -10px;\n  border-top-width: 0;\n  border-bottom-color: #ffffff;\n}\n.popover.left .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-right-width: 0;\n  border-left-color: #999999;\n  border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left .arrow:after {\n  content: \" \";\n  right: 1px;\n  border-right-width: 0;\n  border-left-color: #ffffff;\n  bottom: -10px;\n}\n.carousel {\n  position: relative;\n}\n.carousel-inner {\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n}\n.carousel-inner > .item {\n  display: none;\n  position: relative;\n  -webkit-transition: 0.6s ease-in-out left;\n  transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  max-width: 100%;\n  height: auto;\n  line-height: 1;\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n.carousel-inner > .active {\n  left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n.carousel-inner > .next {\n  left: 100%;\n}\n.carousel-inner > .prev {\n  left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n.carousel-inner > .active.left {\n  left: -100%;\n}\n.carousel-inner > .active.right {\n  left: 100%;\n}\n.carousel-control {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  width: 15%;\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n  font-size: 20px;\n  color: #ffffff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-control.left {\n  background-image: -webkit-gradient(linear, 0% top, 100% top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001)));\n  background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.5) 0%), color-stop(rgba(0, 0, 0, 0.0001) 100%));\n  background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n  left: auto;\n  right: 0;\n  background-image: -webkit-gradient(linear, 0% top, 100% top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5)));\n  background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.0001) 0%), color-stop(rgba(0, 0, 0, 0.5) 100%));\n  background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n  color: #ffffff;\n  text-decoration: none;\n  opacity: 0.9;\n  filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n  position: absolute;\n  top: 50%;\n  z-index: 5;\n  display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n  left: 50%;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n  right: 50%;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n  width: 20px;\n  height: 20px;\n  margin-top: -10px;\n  margin-left: -10px;\n  font-family: serif;\n}\n.carousel-control .icon-prev:before {\n  content: '\\2039';\n}\n.carousel-control .icon-next:before {\n  content: '\\203a';\n}\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  margin-left: -30%;\n  padding-left: 0;\n  list-style: none;\n  text-align: center;\n}\n.carousel-indicators li {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin: 1px;\n  text-indent: -999px;\n  border: 1px solid #ffffff;\n  border-radius: 10px;\n  cursor: pointer;\n}\n.carousel-indicators .active {\n  margin: 0;\n  width: 12px;\n  height: 12px;\n  background-color: #ffffff;\n}\n.carousel-caption {\n  position: absolute;\n  left: 15%;\n  right: 15%;\n  bottom: 20px;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #ffffff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n  text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n  .carousel-control .glyphicons-chevron-left,\n  .carousel-control .glyphicons-chevron-right,\n  .carousel-control .icon-prev,\n  .carousel-control .icon-next {\n    width: 30px;\n    height: 30px;\n    margin-top: -15px;\n    margin-left: -15px;\n    font-size: 30px;\n  }\n  .carousel-caption {\n    left: 20%;\n    right: 20%;\n    padding-bottom: 30px;\n  }\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n.clearfix:before,\n.clearfix:after {\n  content: \" \";\n  /* 1 */\n\n  display: table;\n  /* 2 */\n\n}\n.clearfix:after {\n  clear: both;\n}\n.center-block {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n.hidden {\n  display: none !important;\n  visibility: hidden !important;\n}\n.affix {\n  position: fixed;\n}\n@-ms-viewport {\n  width: device-width;\n}\n.visible-xs,\ntr.visible-xs,\nth.visible-xs,\ntd.visible-xs {\n  display: none !important;\n}\n@media (max-width: 767px) {\n  .visible-xs {\n    display: block !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 (min-width: 768px) and (max-width: 991px) {\n  .visible-xs.visible-sm {\n    display: block !important;\n  }\n  tr.visible-xs.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-xs.visible-sm,\n  td.visible-xs.visible-sm {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-xs.visible-md {\n    display: block !important;\n  }\n  tr.visible-xs.visible-md {\n    display: table-row !important;\n  }\n  th.visible-xs.visible-md,\n  td.visible-xs.visible-md {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-xs.visible-lg {\n    display: block !important;\n  }\n  tr.visible-xs.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-xs.visible-lg,\n  td.visible-xs.visible-lg {\n    display: table-cell !important;\n  }\n}\n.visible-sm,\ntr.visible-sm,\nth.visible-sm,\ntd.visible-sm {\n  display: none !important;\n}\n@media (max-width: 767px) {\n  .visible-sm.visible-xs {\n    display: block !important;\n  }\n  tr.visible-sm.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-sm.visible-xs,\n  td.visible-sm.visible-xs {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm {\n    display: block !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: 992px) and (max-width: 1199px) {\n  .visible-sm.visible-md {\n    display: block !important;\n  }\n  tr.visible-sm.visible-md {\n    display: table-row !important;\n  }\n  th.visible-sm.visible-md,\n  td.visible-sm.visible-md {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-sm.visible-lg {\n    display: block !important;\n  }\n  tr.visible-sm.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-sm.visible-lg,\n  td.visible-sm.visible-lg {\n    display: table-cell !important;\n  }\n}\n.visible-md,\ntr.visible-md,\nth.visible-md,\ntd.visible-md {\n  display: none !important;\n}\n@media (max-width: 767px) {\n  .visible-md.visible-xs {\n    display: block !important;\n  }\n  tr.visible-md.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-md.visible-xs,\n  td.visible-md.visible-xs {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-md.visible-sm {\n    display: block !important;\n  }\n  tr.visible-md.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-md.visible-sm,\n  td.visible-md.visible-sm {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md {\n    display: block !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: 1200px) {\n  .visible-md.visible-lg {\n    display: block !important;\n  }\n  tr.visible-md.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-md.visible-lg,\n  td.visible-md.visible-lg {\n    display: table-cell !important;\n  }\n}\n.visible-lg,\ntr.visible-lg,\nth.visible-lg,\ntd.visible-lg {\n  display: none !important;\n}\n@media (max-width: 767px) {\n  .visible-lg.visible-xs {\n    display: block !important;\n  }\n  tr.visible-lg.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-lg.visible-xs,\n  td.visible-lg.visible-xs {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-lg.visible-sm {\n    display: block !important;\n  }\n  tr.visible-lg.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-lg.visible-sm,\n  td.visible-lg.visible-sm {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-lg.visible-md {\n    display: block !important;\n  }\n  tr.visible-lg.visible-md {\n    display: table-row !important;\n  }\n  th.visible-lg.visible-md,\n  td.visible-lg.visible-md {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg {\n    display: block !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.hidden-xs {\n  display: block !important;\n}\ntr.hidden-xs {\n  display: table-row !important;\n}\nth.hidden-xs,\ntd.hidden-xs {\n  display: table-cell !important;\n}\n@media (max-width: 767px) {\n  .hidden-xs,\n  tr.hidden-xs,\n  th.hidden-xs,\n  td.hidden-xs {\n    display: none !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-xs.hidden-sm,\n  tr.hidden-xs.hidden-sm,\n  th.hidden-xs.hidden-sm,\n  td.hidden-xs.hidden-sm {\n    display: none !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-xs.hidden-md,\n  tr.hidden-xs.hidden-md,\n  th.hidden-xs.hidden-md,\n  td.hidden-xs.hidden-md {\n    display: none !important;\n  }\n}\n@media (min-width: 1200px) {\n  .hidden-xs.hidden-lg,\n  tr.hidden-xs.hidden-lg,\n  th.hidden-xs.hidden-lg,\n  td.hidden-xs.hidden-lg {\n    display: none !important;\n  }\n}\n.hidden-sm {\n  display: block !important;\n}\ntr.hidden-sm {\n  display: table-row !important;\n}\nth.hidden-sm,\ntd.hidden-sm {\n  display: table-cell !important;\n}\n@media (max-width: 767px) {\n  .hidden-sm.hidden-xs,\n  tr.hidden-sm.hidden-xs,\n  th.hidden-sm.hidden-xs,\n  td.hidden-sm.hidden-xs {\n    display: none !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-sm,\n  tr.hidden-sm,\n  th.hidden-sm,\n  td.hidden-sm {\n    display: none !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-sm.hidden-md,\n  tr.hidden-sm.hidden-md,\n  th.hidden-sm.hidden-md,\n  td.hidden-sm.hidden-md {\n    display: none !important;\n  }\n}\n@media (min-width: 1200px) {\n  .hidden-sm.hidden-lg,\n  tr.hidden-sm.hidden-lg,\n  th.hidden-sm.hidden-lg,\n  td.hidden-sm.hidden-lg {\n    display: none !important;\n  }\n}\n.hidden-md {\n  display: block !important;\n}\ntr.hidden-md {\n  display: table-row !important;\n}\nth.hidden-md,\ntd.hidden-md {\n  display: table-cell !important;\n}\n@media (max-width: 767px) {\n  .hidden-md.hidden-xs,\n  tr.hidden-md.hidden-xs,\n  th.hidden-md.hidden-xs,\n  td.hidden-md.hidden-xs {\n    display: none !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-md.hidden-sm,\n  tr.hidden-md.hidden-sm,\n  th.hidden-md.hidden-sm,\n  td.hidden-md.hidden-sm {\n    display: none !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-md,\n  tr.hidden-md,\n  th.hidden-md,\n  td.hidden-md {\n    display: none !important;\n  }\n}\n@media (min-width: 1200px) {\n  .hidden-md.hidden-lg,\n  tr.hidden-md.hidden-lg,\n  th.hidden-md.hidden-lg,\n  td.hidden-md.hidden-lg {\n    display: none !important;\n  }\n}\n.hidden-lg {\n  display: block !important;\n}\ntr.hidden-lg {\n  display: table-row !important;\n}\nth.hidden-lg,\ntd.hidden-lg {\n  display: table-cell !important;\n}\n@media (max-width: 767px) {\n  .hidden-lg.hidden-xs,\n  tr.hidden-lg.hidden-xs,\n  th.hidden-lg.hidden-xs,\n  td.hidden-lg.hidden-xs {\n    display: none !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-lg.hidden-sm,\n  tr.hidden-lg.hidden-sm,\n  th.hidden-lg.hidden-sm,\n  td.hidden-lg.hidden-sm {\n    display: none !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-lg.hidden-md,\n  tr.hidden-lg.hidden-md,\n  th.hidden-lg.hidden-md,\n  td.hidden-lg.hidden-md {\n    display: none !important;\n  }\n}\n@media (min-width: 1200px) {\n  .hidden-lg,\n  tr.hidden-lg,\n  th.hidden-lg,\n  td.hidden-lg {\n    display: none !important;\n  }\n}\n.visible-print,\ntr.visible-print,\nth.visible-print,\ntd.visible-print {\n  display: none !important;\n}\n@media print {\n  .visible-print {\n    display: block !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  .hidden-print,\n  tr.hidden-print,\n  th.hidden-print,\n  td.hidden-print {\n    display: none !important;\n  }\n}\n"
  },
  {
    "path": "static/assets/plugins/summernote/dist/summernote.css",
    "content": ".note-editor{position:relative;overflow:hidden;border:1px solid #a9a9a9}.note-editor .note-dropzone{position:absolute;z-index:100;display:none;color:#87cefa;background-color:white;opacity:.95;pointer-event:none}.note-editor .note-dropzone .note-dropzone-message{display:table-cell;font-size:28px;font-weight:bold;text-align:center;vertical-align:middle}.note-editor .note-dropzone.hover{color:#098ddf}.note-editor.dragover .note-dropzone{display:table}.note-editor.codeview .note-editing-area .note-editable{display:none}.note-editor.codeview .note-editing-area .note-codable{display:block}.note-editor.fullscreen{position:fixed;top:0;left:0;z-index:1050;width:100%}.note-editor.fullscreen .note-editable{background-color:white}.note-editor.fullscreen .note-resizebar{display:none}.note-editor .note-editing-area{position:relative;overflow:hidden}.note-editor .note-editing-area .note-editable{padding:10px;overflow:auto;color:#000;background-color:#fff;outline:0}.note-editor .note-editing-area .note-editable[contenteditable=true]:empty:not(:focus):before{content:attr(data-placeholder)}.note-editor .note-editing-area .note-editable[contenteditable=\"false\"]{background-color:#e5e5e5}.note-editor .note-editing-area .note-codable{display:none;width:100%;padding:10px;margin-bottom:0;font-family:Menlo,Monaco,monospace,sans-serif;font-size:14px;color:#ccc;background-color:#222;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;box-shadow:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;resize:none}.note-editor .note-statusbar{background-color:#f5f5f5}.note-editor .note-statusbar .note-resizebar{width:100%;height:8px;padding-top:1px;cursor:ns-resize}.note-editor .note-statusbar .note-resizebar .note-icon-bar{width:20px;margin:1px auto;border-top:1px solid #a9a9a9}.note-air-editor{outline:0}.note-popover .popover{max-width:none}.note-popover .popover .popover-content a{display:inline-block;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle}.note-popover .popover .arrow{left:20px}.note-popover .popover .popover-content,.panel-heading.note-toolbar{padding:0 0 5px 5px;margin:0}.note-popover .popover .popover-content>.btn-group,.panel-heading.note-toolbar>.btn-group{margin-top:5px;margin-right:5px;margin-left:0}.note-popover .popover .popover-content .btn-group .note-table,.panel-heading.note-toolbar .btn-group .note-table{min-width:0;padding:5px}.note-popover .popover .popover-content .btn-group .note-table .note-dimension-picker,.panel-heading.note-toolbar .btn-group .note-table .note-dimension-picker{font-size:18px}.note-popover .popover .popover-content .btn-group .note-table .note-dimension-picker .note-dimension-picker-mousecatcher,.panel-heading.note-toolbar .btn-group .note-table .note-dimension-picker .note-dimension-picker-mousecatcher{position:absolute!important;z-index:3;width:10em;height:10em;cursor:pointer}.note-popover .popover .popover-content .btn-group .note-table .note-dimension-picker .note-dimension-picker-unhighlighted,.panel-heading.note-toolbar .btn-group .note-table .note-dimension-picker .note-dimension-picker-unhighlighted{position:relative!important;z-index:1;width:5em;height:5em;background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIj4+Pjp6ekKlAqjAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKhmnaJzPAAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC') repeat}.note-popover .popover .popover-content .btn-group .note-table .note-dimension-picker .note-dimension-picker-highlighted,.panel-heading.note-toolbar .btn-group .note-table .note-dimension-picker .note-dimension-picker-highlighted{position:absolute!important;z-index:2;width:1em;height:1em;background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIjd6vvD2f9LKLW+AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKwNDEVT0AAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC') repeat}.note-popover .popover .popover-content .note-style h1,.panel-heading.note-toolbar .note-style h1,.note-popover .popover .popover-content .note-style h2,.panel-heading.note-toolbar .note-style h2,.note-popover .popover .popover-content .note-style h3,.panel-heading.note-toolbar .note-style h3,.note-popover .popover .popover-content .note-style h4,.panel-heading.note-toolbar .note-style h4,.note-popover .popover .popover-content .note-style h5,.panel-heading.note-toolbar .note-style h5,.note-popover .popover .popover-content .note-style h6,.panel-heading.note-toolbar .note-style h6,.note-popover .popover .popover-content .note-style blockquote,.panel-heading.note-toolbar .note-style blockquote{margin:0}.note-popover .popover .popover-content .note-color .dropdown-toggle,.panel-heading.note-toolbar .note-color .dropdown-toggle{width:20px;padding-left:5px}.note-popover .popover .popover-content .note-color .dropdown-menu,.panel-heading.note-toolbar .note-color .dropdown-menu{min-width:340px}.note-popover .popover .popover-content .note-color .dropdown-menu .btn-group,.panel-heading.note-toolbar .note-color .dropdown-menu .btn-group{margin:0}.note-popover .popover .popover-content .note-color .dropdown-menu .btn-group:first-child,.panel-heading.note-toolbar .note-color .dropdown-menu .btn-group:first-child{margin:0 5px}.note-popover .popover .popover-content .note-color .dropdown-menu .btn-group .note-palette-title,.panel-heading.note-toolbar .note-color .dropdown-menu .btn-group .note-palette-title{margin:2px 7px;font-size:12px;text-align:center;border-bottom:1px solid #eee}.note-popover .popover .popover-content .note-color .dropdown-menu .btn-group .note-color-reset,.panel-heading.note-toolbar .note-color .dropdown-menu .btn-group .note-color-reset{padding:0 3px;margin:3px;font-size:11px;cursor:pointer;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.note-popover .popover .popover-content .note-color .dropdown-menu .btn-group .note-color-row,.panel-heading.note-toolbar .note-color .dropdown-menu .btn-group .note-color-row{height:20px}.note-popover .popover .popover-content .note-color .dropdown-menu .btn-group .note-color-reset:hover,.panel-heading.note-toolbar .note-color .dropdown-menu .btn-group .note-color-reset:hover{background:#eee}.note-popover .popover .popover-content .note-para .dropdown-menu,.panel-heading.note-toolbar .note-para .dropdown-menu{min-width:216px;padding:5px}.note-popover .popover .popover-content .note-para .dropdown-menu>div:first-child,.panel-heading.note-toolbar .note-para .dropdown-menu>div:first-child{margin-right:5px}.note-popover .popover .popover-content .dropdown-menu,.panel-heading.note-toolbar .dropdown-menu{min-width:90px}.note-popover .popover .popover-content .dropdown-menu.right,.panel-heading.note-toolbar .dropdown-menu.right{right:0;left:auto}.note-popover .popover .popover-content .dropdown-menu.right::before,.panel-heading.note-toolbar .dropdown-menu.right::before{right:9px;left:auto!important}.note-popover .popover .popover-content .dropdown-menu.right::after,.panel-heading.note-toolbar .dropdown-menu.right::after{right:10px;left:auto!important}.note-popover .popover .popover-content .dropdown-menu.note-check li a i,.panel-heading.note-toolbar .dropdown-menu.note-check li a i{color:deepskyblue;visibility:hidden}.note-popover .popover .popover-content .dropdown-menu.note-check li a.checked i,.panel-heading.note-toolbar .dropdown-menu.note-check li a.checked i{visibility:visible}.note-popover .popover .popover-content .note-fontsize-10,.panel-heading.note-toolbar .note-fontsize-10{font-size:10px}.note-popover .popover .popover-content .note-color-palette,.panel-heading.note-toolbar .note-color-palette{line-height:1}.note-popover .popover .popover-content .note-color-palette div .note-color-btn,.panel-heading.note-toolbar .note-color-palette div .note-color-btn{width:20px;height:20px;padding:0;margin:0;border:1px solid #fff}.note-popover .popover .popover-content .note-color-palette div .note-color-btn:hover,.panel-heading.note-toolbar .note-color-palette div .note-color-btn:hover{border:1px solid #000}.note-dialog>div{display:none}.note-dialog .form-group{margin-right:0;margin-left:0}.note-dialog .note-modal-form{margin:0}.note-dialog .note-image-dialog .note-dropzone{min-height:100px;margin-bottom:10px;font-size:30px;line-height:4;color:lightgray;text-align:center;border:4px dashed lightgray}.note-dialog .note-help-dialog{font-size:12px;color:#ccc;background:transparent;background-color:#222!important;border:0;-webkit-opacity:.9;-khtml-opacity:.9;-moz-opacity:.9;opacity:.9;-ms-filter:alpha(opacity=90);filter:alpha(opacity=90)}.note-dialog .note-help-dialog .modal-content{background:transparent;border:1px solid white;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.note-dialog .note-help-dialog a{font-size:12px;color:white}.note-dialog .note-help-dialog .title{padding-bottom:5px;margin-bottom:10px;font-size:14px;font-weight:bold;color:white;border-bottom:white 1px solid}.note-dialog .note-help-dialog .modal-close{font-size:14px;color:#dd0;cursor:pointer}.note-dialog .note-help-dialog .text-center{margin:10px 0 0}.note-dialog .note-help-dialog .note-shortcut{padding-top:8px;padding-bottom:8px}.note-dialog .note-help-dialog .note-shortcut-row{margin-right:-5px;margin-left:-5px}.note-dialog .note-help-dialog .note-shortcut-col{padding-right:5px;padding-left:5px}.note-dialog .note-help-dialog .note-shortcut-title{font-size:13px;font-weight:bold;color:#dd0}.note-dialog .note-help-dialog .note-shortcut-key{font-family:\"Courier New\";color:#dd0;text-align:right}.note-handle .note-control-selection{position:absolute;display:none;border:1px solid black}.note-handle .note-control-selection>div{position:absolute}.note-handle .note-control-selection .note-control-selection-bg{width:100%;height:100%;background-color:black;-webkit-opacity:.3;-khtml-opacity:.3;-moz-opacity:.3;opacity:.3;-ms-filter:alpha(opacity=30);filter:alpha(opacity=30)}.note-handle .note-control-selection .note-control-handle{width:7px;height:7px;border:1px solid black}.note-handle .note-control-selection .note-control-holder{width:7px;height:7px;border:1px solid black}.note-handle .note-control-selection .note-control-sizing{width:7px;height:7px;background-color:white;border:1px solid black}.note-handle .note-control-selection .note-control-nw{top:-5px;left:-5px;border-right:0;border-bottom:0}.note-handle .note-control-selection .note-control-ne{top:-5px;right:-5px;border-bottom:0;border-left:none}.note-handle .note-control-selection .note-control-sw{bottom:-5px;left:-5px;border-top:0;border-right:0}.note-handle .note-control-selection .note-control-se{right:-5px;bottom:-5px;cursor:se-resize}.note-handle .note-control-selection .note-control-se.note-control-holder{cursor:default;border-top:0;border-left:none}.note-handle .note-control-selection .note-control-selection-info{right:0;bottom:0;padding:5px;margin:5px;font-size:12px;color:white;background-color:black;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-opacity:.7;-khtml-opacity:.7;-moz-opacity:.7;opacity:.7;-ms-filter:alpha(opacity=70);filter:alpha(opacity=70)}"
  },
  {
    "path": "static/assets/plugins/summernote/dist/summernote.js",
    "content": "/**\n * Super simple wysiwyg editor on Bootstrap v0.6.16\n * http://summernote.org/\n *\n * summernote.js\n * Copyright 2013-2015 Alan Hong. and other contributors\n * summernote may be freely distributed under the MIT license./\n *\n * Date: 2015-08-03T16:41Z\n */\n(function (factory) {\n  /* global define */\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define(['jquery'], factory);\n  } else {\n    // Browser globals: jQuery\n    factory(window.jQuery);\n  }\n}(function ($) {\n  \n\n\n  if (!Array.prototype.reduce) {\n    /**\n     * Array.prototype.reduce polyfill\n     *\n     * @param {Function} callback\n     * @param {Value} [initialValue]\n     * @return {Value}\n     *\n     * @see http://goo.gl/WNriQD\n     */\n    Array.prototype.reduce = function (callback) {\n      var t = Object(this), len = t.length >>> 0, k = 0, value;\n      if (arguments.length === 2) {\n        value = arguments[1];\n      } else {\n        while (k < len && !(k in t)) {\n          k++;\n        }\n        if (k >= len) {\n          throw new TypeError('Reduce of empty array with no initial value');\n        }\n        value = t[k++];\n      }\n      for (; k < len; k++) {\n        if (k in t) {\n          value = callback(value, t[k], k, t);\n        }\n      }\n      return value;\n    };\n  }\n\n  if ('function' !== typeof Array.prototype.filter) {\n    /**\n     * Array.prototype.filter polyfill\n     *\n     * @param {Function} func\n     * @return {Array}\n     *\n     * @see http://goo.gl/T1KFnq\n     */\n    Array.prototype.filter = function (func) {\n      var t = Object(this), len = t.length >>> 0;\n\n      var res = [];\n      var thisArg = arguments.length >= 2 ? arguments[1] : void 0;\n      for (var i = 0; i < len; i++) {\n        if (i in t) {\n          var val = t[i];\n          if (func.call(thisArg, val, i, t)) {\n            res.push(val);\n          }\n        }\n      }\n  \n      return res;\n    };\n  }\n\n  if (!Array.prototype.map) {\n    /**\n     * Array.prototype.map polyfill\n     *\n     * @param {Function} callback\n     * @return {Array}\n     *\n     * @see https://goo.gl/SMWaMK\n     */\n    Array.prototype.map = function (callback, thisArg) {\n      var T, A, k;\n      if (this === null) {\n        throw new TypeError(' this is null or not defined');\n      }\n\n      var O = Object(this);\n      var len = O.length >>> 0;\n      if (typeof callback !== 'function') {\n        throw new TypeError(callback + ' is not a function');\n      }\n  \n      if (arguments.length > 1) {\n        T = thisArg;\n      }\n  \n      A = new Array(len);\n      k = 0;\n  \n      while (k < len) {\n        var kValue, mappedValue;\n        if (k in O) {\n          kValue = O[k];\n          mappedValue = callback.call(T, kValue, k, O);\n          A[k] = mappedValue;\n        }\n        k++;\n      }\n      return A;\n    };\n  }\n\n  var isSupportAmd = typeof define === 'function' && define.amd;\n\n  /**\n   * returns whether font is installed or not.\n   *\n   * @param {String} fontName\n   * @return {Boolean}\n   */\n  var isFontInstalled = function (fontName) {\n    var testFontName = fontName === 'Comic Sans MS' ? 'Courier New' : 'Comic Sans MS';\n    var $tester = $('<div>').css({\n      position: 'absolute',\n      left: '-9999px',\n      top: '-9999px',\n      fontSize: '200px'\n    }).text('mmmmmmmmmwwwwwww').appendTo(document.body);\n\n    var originalWidth = $tester.css('fontFamily', testFontName).width();\n    var width = $tester.css('fontFamily', fontName + ',' + testFontName).width();\n\n    $tester.remove();\n\n    return originalWidth !== width;\n  };\n\n  var userAgent = navigator.userAgent;\n  var isMSIE = /MSIE|Trident/i.test(userAgent);\n  var browserVersion;\n  if (isMSIE) {\n    var matches = /MSIE (\\d+[.]\\d+)/.exec(userAgent);\n    if (matches) {\n      browserVersion = parseFloat(matches[1]);\n    }\n    matches = /Trident\\/.*rv:([0-9]{1,}[\\.0-9]{0,})/.exec(userAgent);\n    if (matches) {\n      browserVersion = parseFloat(matches[1]);\n    }\n  }\n\n  /**\n   * @class core.agent\n   *\n   * Object which check platform and agent\n   *\n   * @singleton\n   * @alternateClassName agent\n   */\n  var agent = {\n    /** @property {Boolean} [isMac=false] true if this agent is Mac  */\n    isMac: navigator.appVersion.indexOf('Mac') > -1,\n    /** @property {Boolean} [isMSIE=false] true if this agent is a Internet Explorer  */\n    isMSIE: isMSIE,\n    /** @property {Boolean} [isFF=false] true if this agent is a Firefox  */\n    isFF: /firefox/i.test(userAgent),\n    isWebkit: /webkit/i.test(userAgent),\n    /** @property {Boolean} [isSafari=false] true if this agent is a Safari  */\n    isSafari: /safari/i.test(userAgent),\n    /** @property {Float} browserVersion current browser version  */\n    browserVersion: browserVersion,\n    /** @property {String} jqueryVersion current jQuery version string  */\n    jqueryVersion: parseFloat($.fn.jquery),\n    isSupportAmd: isSupportAmd,\n    hasCodeMirror: isSupportAmd ? require.specified('CodeMirror') : !!window.CodeMirror,\n    isFontInstalled: isFontInstalled,\n    isW3CRangeSupport: !!document.createRange\n  };\n\n  /**\n   * @class core.func\n   *\n   * func utils (for high-order func's arg)\n   *\n   * @singleton\n   * @alternateClassName func\n   */\n  var func = (function () {\n    var eq = function (itemA) {\n      return function (itemB) {\n        return itemA === itemB;\n      };\n    };\n\n    var eq2 = function (itemA, itemB) {\n      return itemA === itemB;\n    };\n\n    var peq2 = function (propName) {\n      return function (itemA, itemB) {\n        return itemA[propName] === itemB[propName];\n      };\n    };\n\n    var ok = function () {\n      return true;\n    };\n\n    var fail = function () {\n      return false;\n    };\n\n    var not = function (f) {\n      return function () {\n        return !f.apply(f, arguments);\n      };\n    };\n\n    var and = function (fA, fB) {\n      return function (item) {\n        return fA(item) && fB(item);\n      };\n    };\n\n    var self = function (a) {\n      return a;\n    };\n\n    var idCounter = 0;\n\n    /**\n     * generate a globally-unique id\n     *\n     * @param {String} [prefix]\n     */\n    var uniqueId = function (prefix) {\n      var id = ++idCounter + '';\n      return prefix ? prefix + id : id;\n    };\n\n    /**\n     * returns bnd (bounds) from rect\n     *\n     * - IE Compatability Issue: http://goo.gl/sRLOAo\n     * - Scroll Issue: http://goo.gl/sNjUc\n     *\n     * @param {Rect} rect\n     * @return {Object} bounds\n     * @return {Number} bounds.top\n     * @return {Number} bounds.left\n     * @return {Number} bounds.width\n     * @return {Number} bounds.height\n     */\n    var rect2bnd = function (rect) {\n      var $document = $(document);\n      return {\n        top: rect.top + $document.scrollTop(),\n        left: rect.left + $document.scrollLeft(),\n        width: rect.right - rect.left,\n        height: rect.bottom - rect.top\n      };\n    };\n\n    /**\n     * returns a copy of the object where the keys have become the values and the values the keys.\n     * @param {Object} obj\n     * @return {Object}\n     */\n    var invertObject = function (obj) {\n      var inverted = {};\n      for (var key in obj) {\n        if (obj.hasOwnProperty(key)) {\n          inverted[obj[key]] = key;\n        }\n      }\n      return inverted;\n    };\n\n    /**\n     * @param {String} namespace\n     * @param {String} [prefix]\n     * @return {String}\n     */\n    var namespaceToCamel = function (namespace, prefix) {\n      prefix = prefix || '';\n      return prefix + namespace.split('.').map(function (name) {\n        return name.substring(0, 1).toUpperCase() + name.substring(1);\n      }).join('');\n    };\n\n    return {\n      eq: eq,\n      eq2: eq2,\n      peq2: peq2,\n      ok: ok,\n      fail: fail,\n      self: self,\n      not: not,\n      and: and,\n      uniqueId: uniqueId,\n      rect2bnd: rect2bnd,\n      invertObject: invertObject,\n      namespaceToCamel: namespaceToCamel\n    };\n  })();\n\n  /**\n   * @class core.list\n   *\n   * list utils\n   *\n   * @singleton\n   * @alternateClassName list\n   */\n  var list = (function () {\n    /**\n     * returns the first item of an array.\n     *\n     * @param {Array} array\n     */\n    var head = function (array) {\n      return array[0];\n    };\n\n    /**\n     * returns the last item of an array.\n     *\n     * @param {Array} array\n     */\n    var last = function (array) {\n      return array[array.length - 1];\n    };\n\n    /**\n     * returns everything but the last entry of the array.\n     *\n     * @param {Array} array\n     */\n    var initial = function (array) {\n      return array.slice(0, array.length - 1);\n    };\n\n    /**\n     * returns the rest of the items in an array.\n     *\n     * @param {Array} array\n     */\n    var tail = function (array) {\n      return array.slice(1);\n    };\n\n    /**\n     * returns item of array\n     */\n    var find = function (array, pred) {\n      for (var idx = 0, len = array.length; idx < len; idx ++) {\n        var item = array[idx];\n        if (pred(item)) {\n          return item;\n        }\n      }\n    };\n\n    /**\n     * returns true if all of the values in the array pass the predicate truth test.\n     */\n    var all = function (array, pred) {\n      for (var idx = 0, len = array.length; idx < len; idx ++) {\n        if (!pred(array[idx])) {\n          return false;\n        }\n      }\n      return true;\n    };\n\n    /**\n     * returns index of item\n     */\n    var indexOf = function (array, item) {\n      return $.inArray(item, array);\n    };\n\n    /**\n     * returns true if the value is present in the list.\n     */\n    var contains = function (array, item) {\n      return indexOf(array, item) !== -1;\n    };\n\n    /**\n     * get sum from a list\n     *\n     * @param {Array} array - array\n     * @param {Function} fn - iterator\n     */\n    var sum = function (array, fn) {\n      fn = fn || func.self;\n      return array.reduce(function (memo, v) {\n        return memo + fn(v);\n      }, 0);\n    };\n  \n    /**\n     * returns a copy of the collection with array type.\n     * @param {Collection} collection - collection eg) node.childNodes, ...\n     */\n    var from = function (collection) {\n      var result = [], idx = -1, length = collection.length;\n      while (++idx < length) {\n        result[idx] = collection[idx];\n      }\n      return result;\n    };\n  \n    /**\n     * cluster elements by predicate function.\n     *\n     * @param {Array} array - array\n     * @param {Function} fn - predicate function for cluster rule\n     * @param {Array[]}\n     */\n    var clusterBy = function (array, fn) {\n      if (!array.length) { return []; }\n      var aTail = tail(array);\n      return aTail.reduce(function (memo, v) {\n        var aLast = last(memo);\n        if (fn(last(aLast), v)) {\n          aLast[aLast.length] = v;\n        } else {\n          memo[memo.length] = [v];\n        }\n        return memo;\n      }, [[head(array)]]);\n    };\n  \n    /**\n     * returns a copy of the array with all falsy values removed\n     *\n     * @param {Array} array - array\n     * @param {Function} fn - predicate function for cluster rule\n     */\n    var compact = function (array) {\n      var aResult = [];\n      for (var idx = 0, len = array.length; idx < len; idx ++) {\n        if (array[idx]) { aResult.push(array[idx]); }\n      }\n      return aResult;\n    };\n\n    /**\n     * produces a duplicate-free version of the array\n     *\n     * @param {Array} array\n     */\n    var unique = function (array) {\n      var results = [];\n\n      for (var idx = 0, len = array.length; idx < len; idx ++) {\n        if (!contains(results, array[idx])) {\n          results.push(array[idx]);\n        }\n      }\n\n      return results;\n    };\n\n    /**\n     * returns next item.\n     * @param {Array} array\n     */\n    var next = function (array, item) {\n      var idx = indexOf(array, item);\n      if (idx === -1) { return null; }\n\n      return array[idx + 1];\n    };\n\n    /**\n     * returns prev item.\n     * @param {Array} array\n     */\n    var prev = function (array, item) {\n      var idx = indexOf(array, item);\n      if (idx === -1) { return null; }\n\n      return array[idx - 1];\n    };\n  \n    return { head: head, last: last, initial: initial, tail: tail,\n             prev: prev, next: next, find: find, contains: contains,\n             all: all, sum: sum, from: from,\n             clusterBy: clusterBy, compact: compact, unique: unique };\n  })();\n\n\n  var NBSP_CHAR = String.fromCharCode(160);\n  var ZERO_WIDTH_NBSP_CHAR = '\\ufeff';\n\n  /**\n   * @class core.dom\n   *\n   * Dom functions\n   *\n   * @singleton\n   * @alternateClassName dom\n   */\n  var dom = (function () {\n    /**\n     * @method isEditable\n     *\n     * returns whether node is `note-editable` or not.\n     *\n     * @param {Node} node\n     * @return {Boolean}\n     */\n    var isEditable = function (node) {\n      return node && $(node).hasClass('note-editable');\n    };\n\n    /**\n     * @method isControlSizing\n     *\n     * returns whether node is `note-control-sizing` or not.\n     *\n     * @param {Node} node\n     * @return {Boolean}\n     */\n    var isControlSizing = function (node) {\n      return node && $(node).hasClass('note-control-sizing');\n    };\n\n    /**\n     * @method  buildLayoutInfo\n     *\n     * build layoutInfo from $editor(.note-editor)\n     *\n     * @param {jQuery} $editor\n     * @return {Object}\n     * @return {Function} return.editor\n     * @return {Node} return.dropzone\n     * @return {Node} return.toolbar\n     * @return {Node} return.editable\n     * @return {Node} return.codable\n     * @return {Node} return.popover\n     * @return {Node} return.handle\n     * @return {Node} return.dialog\n     */\n    var buildLayoutInfo = function ($editor) {\n      var makeFinder;\n\n      // air mode\n      if ($editor.hasClass('note-air-editor')) {\n        var id = list.last($editor.attr('id').split('-'));\n        makeFinder = function (sIdPrefix) {\n          return function () { return $(sIdPrefix + id); };\n        };\n\n        return {\n          editor: function () { return $editor; },\n          holder : function () { return $editor.data('holder'); },\n          editable: function () { return $editor; },\n          popover: makeFinder('#note-popover-'),\n          handle: makeFinder('#note-handle-'),\n          dialog: makeFinder('#note-dialog-')\n        };\n\n        // frame mode\n      } else {\n        makeFinder = function (className, $base) {\n          $base = $base || $editor;\n          return function () { return $base.find(className); };\n        };\n\n        var options = $editor.data('options');\n        var $dialogHolder = (options && options.dialogsInBody) ? $(document.body) : null;\n\n        return {\n          editor: function () { return $editor; },\n          holder : function () { return $editor.data('holder'); },\n          dropzone: makeFinder('.note-dropzone'),\n          toolbar: makeFinder('.note-toolbar'),\n          editable: makeFinder('.note-editable'),\n          codable: makeFinder('.note-codable'),\n          statusbar: makeFinder('.note-statusbar'),\n          popover: makeFinder('.note-popover'),\n          handle: makeFinder('.note-handle'),\n          dialog: makeFinder('.note-dialog', $dialogHolder)\n        };\n      }\n    };\n\n    /**\n     * returns makeLayoutInfo from editor's descendant node.\n     *\n     * @private\n     * @param {Node} descendant\n     * @return {Object}\n     */\n    var makeLayoutInfo = function (descendant) {\n      var $target = $(descendant).closest('.note-editor, .note-air-editor, .note-air-layout');\n\n      if (!$target.length) {\n        return null;\n      }\n\n      var $editor;\n      if ($target.is('.note-editor, .note-air-editor')) {\n        $editor = $target;\n      } else {\n        $editor = $('#note-editor-' + list.last($target.attr('id').split('-')));\n      }\n\n      return buildLayoutInfo($editor);\n    };\n\n    /**\n     * @method makePredByNodeName\n     *\n     * returns predicate which judge whether nodeName is same\n     *\n     * @param {String} nodeName\n     * @return {Function}\n     */\n    var makePredByNodeName = function (nodeName) {\n      nodeName = nodeName.toUpperCase();\n      return function (node) {\n        return node && node.nodeName.toUpperCase() === nodeName;\n      };\n    };\n\n    /**\n     * @method isText\n     *\n     *\n     *\n     * @param {Node} node\n     * @return {Boolean} true if node's type is text(3)\n     */\n    var isText = function (node) {\n      return node && node.nodeType === 3;\n    };\n\n    /**\n     * ex) br, col, embed, hr, img, input, ...\n     * @see http://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements\n     */\n    var isVoid = function (node) {\n      return node && /^BR|^IMG|^HR|^IFRAME|^BUTTON/.test(node.nodeName.toUpperCase());\n    };\n\n    var isPara = function (node) {\n      if (isEditable(node)) {\n        return false;\n      }\n\n      // Chrome(v31.0), FF(v25.0.1) use DIV for paragraph\n      return node && /^DIV|^P|^LI|^H[1-7]/.test(node.nodeName.toUpperCase());\n    };\n\n    var isLi = makePredByNodeName('LI');\n\n    var isPurePara = function (node) {\n      return isPara(node) && !isLi(node);\n    };\n\n    var isTable = makePredByNodeName('TABLE');\n\n    var isInline = function (node) {\n      return !isBodyContainer(node) &&\n             !isList(node) &&\n             !isHr(node) &&\n             !isPara(node) &&\n             !isTable(node) &&\n             !isBlockquote(node);\n    };\n\n    var isList = function (node) {\n      return node && /^UL|^OL/.test(node.nodeName.toUpperCase());\n    };\n\n    var isHr = makePredByNodeName('HR');\n\n    var isCell = function (node) {\n      return node && /^TD|^TH/.test(node.nodeName.toUpperCase());\n    };\n\n    var isBlockquote = makePredByNodeName('BLOCKQUOTE');\n\n    var isBodyContainer = function (node) {\n      return isCell(node) || isBlockquote(node) || isEditable(node);\n    };\n\n    var isAnchor = makePredByNodeName('A');\n\n    var isParaInline = function (node) {\n      return isInline(node) && !!ancestor(node, isPara);\n    };\n\n    var isBodyInline = function (node) {\n      return isInline(node) && !ancestor(node, isPara);\n    };\n\n    var isBody = makePredByNodeName('BODY');\n\n    /**\n     * returns whether nodeB is closest sibling of nodeA\n     *\n     * @param {Node} nodeA\n     * @param {Node} nodeB\n     * @return {Boolean}\n     */\n    var isClosestSibling = function (nodeA, nodeB) {\n      return nodeA.nextSibling === nodeB ||\n             nodeA.previousSibling === nodeB;\n    };\n\n    /**\n     * returns array of closest siblings with node\n     *\n     * @param {Node} node\n     * @param {function} [pred] - predicate function\n     * @return {Node[]}\n     */\n    var withClosestSiblings = function (node, pred) {\n      pred = pred || func.ok;\n\n      var siblings = [];\n      if (node.previousSibling && pred(node.previousSibling)) {\n        siblings.push(node.previousSibling);\n      }\n      siblings.push(node);\n      if (node.nextSibling && pred(node.nextSibling)) {\n        siblings.push(node.nextSibling);\n      }\n      return siblings;\n    };\n\n    /**\n     * blank HTML for cursor position\n     * - [workaround] old IE only works with &nbsp;\n     * - [workaround] IE11 and other browser works with bogus br\n     */\n    var blankHTML = agent.isMSIE && agent.browserVersion < 11 ? '&nbsp;' : '<br>';\n\n    /**\n     * @method nodeLength\n     *\n     * returns #text's text size or element's childNodes size\n     *\n     * @param {Node} node\n     */\n    var nodeLength = function (node) {\n      if (isText(node)) {\n        return node.nodeValue.length;\n      }\n\n      return node.childNodes.length;\n    };\n\n    /**\n     * returns whether node is empty or not.\n     *\n     * @param {Node} node\n     * @return {Boolean}\n     */\n    var isEmpty = function (node) {\n      var len = nodeLength(node);\n\n      if (len === 0) {\n        return true;\n      } else if (!isText(node) && len === 1 && node.innerHTML === blankHTML) {\n        // ex) <p><br></p>, <span><br></span>\n        return true;\n      } else if (list.all(node.childNodes, isText) && node.innerHTML === '') {\n        // ex) <p></p>, <span></span>\n        return true;\n      }\n\n      return false;\n    };\n\n    /**\n     * padding blankHTML if node is empty (for cursor position)\n     */\n    var paddingBlankHTML = function (node) {\n      if (!isVoid(node) && !nodeLength(node)) {\n        node.innerHTML = blankHTML;\n      }\n    };\n\n    /**\n     * find nearest ancestor predicate hit\n     *\n     * @param {Node} node\n     * @param {Function} pred - predicate function\n     */\n    var ancestor = function (node, pred) {\n      while (node) {\n        if (pred(node)) { return node; }\n        if (isEditable(node)) { break; }\n\n        node = node.parentNode;\n      }\n      return null;\n    };\n\n    /**\n     * find nearest ancestor only single child blood line and predicate hit\n     *\n     * @param {Node} node\n     * @param {Function} pred - predicate function\n     */\n    var singleChildAncestor = function (node, pred) {\n      node = node.parentNode;\n\n      while (node) {\n        if (nodeLength(node) !== 1) { break; }\n        if (pred(node)) { return node; }\n        if (isEditable(node)) { break; }\n\n        node = node.parentNode;\n      }\n      return null;\n    };\n\n    /**\n     * returns new array of ancestor nodes (until predicate hit).\n     *\n     * @param {Node} node\n     * @param {Function} [optional] pred - predicate function\n     */\n    var listAncestor = function (node, pred) {\n      pred = pred || func.fail;\n\n      var ancestors = [];\n      ancestor(node, function (el) {\n        if (!isEditable(el)) {\n          ancestors.push(el);\n        }\n\n        return pred(el);\n      });\n      return ancestors;\n    };\n\n    /**\n     * find farthest ancestor predicate hit\n     */\n    var lastAncestor = function (node, pred) {\n      var ancestors = listAncestor(node);\n      return list.last(ancestors.filter(pred));\n    };\n\n    /**\n     * returns common ancestor node between two nodes.\n     *\n     * @param {Node} nodeA\n     * @param {Node} nodeB\n     */\n    var commonAncestor = function (nodeA, nodeB) {\n      var ancestors = listAncestor(nodeA);\n      for (var n = nodeB; n; n = n.parentNode) {\n        if ($.inArray(n, ancestors) > -1) { return n; }\n      }\n      return null; // difference document area\n    };\n\n    /**\n     * listing all previous siblings (until predicate hit).\n     *\n     * @param {Node} node\n     * @param {Function} [optional] pred - predicate function\n     */\n    var listPrev = function (node, pred) {\n      pred = pred || func.fail;\n\n      var nodes = [];\n      while (node) {\n        if (pred(node)) { break; }\n        nodes.push(node);\n        node = node.previousSibling;\n      }\n      return nodes;\n    };\n\n    /**\n     * listing next siblings (until predicate hit).\n     *\n     * @param {Node} node\n     * @param {Function} [pred] - predicate function\n     */\n    var listNext = function (node, pred) {\n      pred = pred || func.fail;\n\n      var nodes = [];\n      while (node) {\n        if (pred(node)) { break; }\n        nodes.push(node);\n        node = node.nextSibling;\n      }\n      return nodes;\n    };\n\n    /**\n     * listing descendant nodes\n     *\n     * @param {Node} node\n     * @param {Function} [pred] - predicate function\n     */\n    var listDescendant = function (node, pred) {\n      var descendents = [];\n      pred = pred || func.ok;\n\n      // start DFS(depth first search) with node\n      (function fnWalk(current) {\n        if (node !== current && pred(current)) {\n          descendents.push(current);\n        }\n        for (var idx = 0, len = current.childNodes.length; idx < len; idx++) {\n          fnWalk(current.childNodes[idx]);\n        }\n      })(node);\n\n      return descendents;\n    };\n\n    /**\n     * wrap node with new tag.\n     *\n     * @param {Node} node\n     * @param {Node} tagName of wrapper\n     * @return {Node} - wrapper\n     */\n    var wrap = function (node, wrapperName) {\n      var parent = node.parentNode;\n      var wrapper = $('<' + wrapperName + '>')[0];\n\n      parent.insertBefore(wrapper, node);\n      wrapper.appendChild(node);\n\n      return wrapper;\n    };\n\n    /**\n     * insert node after preceding\n     *\n     * @param {Node} node\n     * @param {Node} preceding - predicate function\n     */\n    var insertAfter = function (node, preceding) {\n      var next = preceding.nextSibling, parent = preceding.parentNode;\n      if (next) {\n        parent.insertBefore(node, next);\n      } else {\n        parent.appendChild(node);\n      }\n      return node;\n    };\n\n    /**\n     * append elements.\n     *\n     * @param {Node} node\n     * @param {Collection} aChild\n     */\n    var appendChildNodes = function (node, aChild) {\n      $.each(aChild, function (idx, child) {\n        node.appendChild(child);\n      });\n      return node;\n    };\n\n    /**\n     * returns whether boundaryPoint is left edge or not.\n     *\n     * @param {BoundaryPoint} point\n     * @return {Boolean}\n     */\n    var isLeftEdgePoint = function (point) {\n      return point.offset === 0;\n    };\n\n    /**\n     * returns whether boundaryPoint is right edge or not.\n     *\n     * @param {BoundaryPoint} point\n     * @return {Boolean}\n     */\n    var isRightEdgePoint = function (point) {\n      return point.offset === nodeLength(point.node);\n    };\n\n    /**\n     * returns whether boundaryPoint is edge or not.\n     *\n     * @param {BoundaryPoint} point\n     * @return {Boolean}\n     */\n    var isEdgePoint = function (point) {\n      return isLeftEdgePoint(point) || isRightEdgePoint(point);\n    };\n\n    /**\n     * returns wheter node is left edge of ancestor or not.\n     *\n     * @param {Node} node\n     * @param {Node} ancestor\n     * @return {Boolean}\n     */\n    var isLeftEdgeOf = function (node, ancestor) {\n      while (node && node !== ancestor) {\n        if (position(node) !== 0) {\n          return false;\n        }\n        node = node.parentNode;\n      }\n\n      return true;\n    };\n\n    /**\n     * returns whether node is right edge of ancestor or not.\n     *\n     * @param {Node} node\n     * @param {Node} ancestor\n     * @return {Boolean}\n     */\n    var isRightEdgeOf = function (node, ancestor) {\n      while (node && node !== ancestor) {\n        if (position(node) !== nodeLength(node.parentNode) - 1) {\n          return false;\n        }\n        node = node.parentNode;\n      }\n\n      return true;\n    };\n\n    /**\n     * returns whether point is left edge of ancestor or not.\n     * @param {BoundaryPoint} point\n     * @param {Node} ancestor\n     * @return {Boolean}\n     */\n    var isLeftEdgePointOf = function (point, ancestor) {\n      return isLeftEdgePoint(point) && isLeftEdgeOf(point.node, ancestor);\n    };\n\n    /**\n     * returns whether point is right edge of ancestor or not.\n     * @param {BoundaryPoint} point\n     * @param {Node} ancestor\n     * @return {Boolean}\n     */\n    var isRightEdgePointOf = function (point, ancestor) {\n      return isRightEdgePoint(point) && isRightEdgeOf(point.node, ancestor);\n    };\n\n    /**\n     * returns offset from parent.\n     *\n     * @param {Node} node\n     */\n    var position = function (node) {\n      var offset = 0;\n      while ((node = node.previousSibling)) {\n        offset += 1;\n      }\n      return offset;\n    };\n\n    var hasChildren = function (node) {\n      return !!(node && node.childNodes && node.childNodes.length);\n    };\n\n    /**\n     * returns previous boundaryPoint\n     *\n     * @param {BoundaryPoint} point\n     * @param {Boolean} isSkipInnerOffset\n     * @return {BoundaryPoint}\n     */\n    var prevPoint = function (point, isSkipInnerOffset) {\n      var node, offset;\n\n      if (point.offset === 0) {\n        if (isEditable(point.node)) {\n          return null;\n        }\n\n        node = point.node.parentNode;\n        offset = position(point.node);\n      } else if (hasChildren(point.node)) {\n        node = point.node.childNodes[point.offset - 1];\n        offset = nodeLength(node);\n      } else {\n        node = point.node;\n        offset = isSkipInnerOffset ? 0 : point.offset - 1;\n      }\n\n      return {\n        node: node,\n        offset: offset\n      };\n    };\n\n    /**\n     * returns next boundaryPoint\n     *\n     * @param {BoundaryPoint} point\n     * @param {Boolean} isSkipInnerOffset\n     * @return {BoundaryPoint}\n     */\n    var nextPoint = function (point, isSkipInnerOffset) {\n      var node, offset;\n\n      if (nodeLength(point.node) === point.offset) {\n        if (isEditable(point.node)) {\n          return null;\n        }\n\n        node = point.node.parentNode;\n        offset = position(point.node) + 1;\n      } else if (hasChildren(point.node)) {\n        node = point.node.childNodes[point.offset];\n        offset = 0;\n      } else {\n        node = point.node;\n        offset = isSkipInnerOffset ? nodeLength(point.node) : point.offset + 1;\n      }\n\n      return {\n        node: node,\n        offset: offset\n      };\n    };\n\n    /**\n     * returns whether pointA and pointB is same or not.\n     *\n     * @param {BoundaryPoint} pointA\n     * @param {BoundaryPoint} pointB\n     * @return {Boolean}\n     */\n    var isSamePoint = function (pointA, pointB) {\n      return pointA.node === pointB.node && pointA.offset === pointB.offset;\n    };\n\n    /**\n     * returns whether point is visible (can set cursor) or not.\n     * \n     * @param {BoundaryPoint} point\n     * @return {Boolean}\n     */\n    var isVisiblePoint = function (point) {\n      if (isText(point.node) || !hasChildren(point.node) || isEmpty(point.node)) {\n        return true;\n      }\n\n      var leftNode = point.node.childNodes[point.offset - 1];\n      var rightNode = point.node.childNodes[point.offset];\n      if ((!leftNode || isVoid(leftNode)) && (!rightNode || isVoid(rightNode))) {\n        return true;\n      }\n\n      return false;\n    };\n\n    /**\n     * @method prevPointUtil\n     *\n     * @param {BoundaryPoint} point\n     * @param {Function} pred\n     * @return {BoundaryPoint}\n     */\n    var prevPointUntil = function (point, pred) {\n      while (point) {\n        if (pred(point)) {\n          return point;\n        }\n\n        point = prevPoint(point);\n      }\n\n      return null;\n    };\n\n    /**\n     * @method nextPointUntil\n     *\n     * @param {BoundaryPoint} point\n     * @param {Function} pred\n     * @return {BoundaryPoint}\n     */\n    var nextPointUntil = function (point, pred) {\n      while (point) {\n        if (pred(point)) {\n          return point;\n        }\n\n        point = nextPoint(point);\n      }\n\n      return null;\n    };\n\n    /**\n     * returns whether point has character or not.\n     *\n     * @param {Point} point\n     * @return {Boolean}\n     */\n    var isCharPoint = function (point) {\n      if (!isText(point.node)) {\n        return false;\n      }\n\n      var ch = point.node.nodeValue.charAt(point.offset - 1);\n      return ch && (ch !== ' ' && ch !== NBSP_CHAR);\n    };\n\n    /**\n     * @method walkPoint\n     *\n     * @param {BoundaryPoint} startPoint\n     * @param {BoundaryPoint} endPoint\n     * @param {Function} handler\n     * @param {Boolean} isSkipInnerOffset\n     */\n    var walkPoint = function (startPoint, endPoint, handler, isSkipInnerOffset) {\n      var point = startPoint;\n\n      while (point) {\n        handler(point);\n\n        if (isSamePoint(point, endPoint)) {\n          break;\n        }\n\n        var isSkipOffset = isSkipInnerOffset &&\n                           startPoint.node !== point.node &&\n                           endPoint.node !== point.node;\n        point = nextPoint(point, isSkipOffset);\n      }\n    };\n\n    /**\n     * @method makeOffsetPath\n     *\n     * return offsetPath(array of offset) from ancestor\n     *\n     * @param {Node} ancestor - ancestor node\n     * @param {Node} node\n     */\n    var makeOffsetPath = function (ancestor, node) {\n      var ancestors = listAncestor(node, func.eq(ancestor));\n      return ancestors.map(position).reverse();\n    };\n\n    /**\n     * @method fromOffsetPath\n     *\n     * return element from offsetPath(array of offset)\n     *\n     * @param {Node} ancestor - ancestor node\n     * @param {array} offsets - offsetPath\n     */\n    var fromOffsetPath = function (ancestor, offsets) {\n      var current = ancestor;\n      for (var i = 0, len = offsets.length; i < len; i++) {\n        if (current.childNodes.length <= offsets[i]) {\n          current = current.childNodes[current.childNodes.length - 1];\n        } else {\n          current = current.childNodes[offsets[i]];\n        }\n      }\n      return current;\n    };\n\n    /**\n     * @method splitNode\n     *\n     * split element or #text\n     *\n     * @param {BoundaryPoint} point\n     * @param {Object} [options]\n     * @param {Boolean} [options.isSkipPaddingBlankHTML] - default: false\n     * @param {Boolean} [options.isNotSplitEdgePoint] - default: false\n     * @return {Node} right node of boundaryPoint\n     */\n    var splitNode = function (point, options) {\n      var isSkipPaddingBlankHTML = options && options.isSkipPaddingBlankHTML;\n      var isNotSplitEdgePoint = options && options.isNotSplitEdgePoint;\n\n      // edge case\n      if (isEdgePoint(point) && (isText(point.node) || isNotSplitEdgePoint)) {\n        if (isLeftEdgePoint(point)) {\n          return point.node;\n        } else if (isRightEdgePoint(point)) {\n          return point.node.nextSibling;\n        }\n      }\n\n      // split #text\n      if (isText(point.node)) {\n        return point.node.splitText(point.offset);\n      } else {\n        var childNode = point.node.childNodes[point.offset];\n        var clone = insertAfter(point.node.cloneNode(false), point.node);\n        appendChildNodes(clone, listNext(childNode));\n\n        if (!isSkipPaddingBlankHTML) {\n          paddingBlankHTML(point.node);\n          paddingBlankHTML(clone);\n        }\n\n        return clone;\n      }\n    };\n\n    /**\n     * @method splitTree\n     *\n     * split tree by point\n     *\n     * @param {Node} root - split root\n     * @param {BoundaryPoint} point\n     * @param {Object} [options]\n     * @param {Boolean} [options.isSkipPaddingBlankHTML] - default: false\n     * @param {Boolean} [options.isNotSplitEdgePoint] - default: false\n     * @return {Node} right node of boundaryPoint\n     */\n    var splitTree = function (root, point, options) {\n      // ex) [#text, <span>, <p>]\n      var ancestors = listAncestor(point.node, func.eq(root));\n\n      if (!ancestors.length) {\n        return null;\n      } else if (ancestors.length === 1) {\n        return splitNode(point, options);\n      }\n\n      return ancestors.reduce(function (node, parent) {\n        if (node === point.node) {\n          node = splitNode(point, options);\n        }\n\n        return splitNode({\n          node: parent,\n          offset: node ? dom.position(node) : nodeLength(parent)\n        }, options);\n      });\n    };\n\n    /**\n     * split point\n     *\n     * @param {Point} point\n     * @param {Boolean} isInline\n     * @return {Object}\n     */\n    var splitPoint = function (point, isInline) {\n      // find splitRoot, container\n      //  - inline: splitRoot is a child of paragraph\n      //  - block: splitRoot is a child of bodyContainer\n      var pred = isInline ? isPara : isBodyContainer;\n      var ancestors = listAncestor(point.node, pred);\n      var topAncestor = list.last(ancestors) || point.node;\n\n      var splitRoot, container;\n      if (pred(topAncestor)) {\n        splitRoot = ancestors[ancestors.length - 2];\n        container = topAncestor;\n      } else {\n        splitRoot = topAncestor;\n        container = splitRoot.parentNode;\n      }\n\n      // if splitRoot is exists, split with splitTree\n      var pivot = splitRoot && splitTree(splitRoot, point, {\n        isSkipPaddingBlankHTML: isInline,\n        isNotSplitEdgePoint: isInline\n      });\n\n      // if container is point.node, find pivot with point.offset\n      if (!pivot && container === point.node) {\n        pivot = point.node.childNodes[point.offset];\n      }\n\n      return {\n        rightNode: pivot,\n        container: container\n      };\n    };\n\n    var create = function (nodeName) {\n      return document.createElement(nodeName);\n    };\n\n    var createText = function (text) {\n      return document.createTextNode(text);\n    };\n\n    /**\n     * @method remove\n     *\n     * remove node, (isRemoveChild: remove child or not)\n     *\n     * @param {Node} node\n     * @param {Boolean} isRemoveChild\n     */\n    var remove = function (node, isRemoveChild) {\n      if (!node || !node.parentNode) { return; }\n      if (node.removeNode) { return node.removeNode(isRemoveChild); }\n\n      var parent = node.parentNode;\n      if (!isRemoveChild) {\n        var nodes = [];\n        var i, len;\n        for (i = 0, len = node.childNodes.length; i < len; i++) {\n          nodes.push(node.childNodes[i]);\n        }\n\n        for (i = 0, len = nodes.length; i < len; i++) {\n          parent.insertBefore(nodes[i], node);\n        }\n      }\n\n      parent.removeChild(node);\n    };\n\n    /**\n     * @method removeWhile\n     *\n     * @param {Node} node\n     * @param {Function} pred\n     */\n    var removeWhile = function (node, pred) {\n      while (node) {\n        if (isEditable(node) || !pred(node)) {\n          break;\n        }\n\n        var parent = node.parentNode;\n        remove(node);\n        node = parent;\n      }\n    };\n\n    /**\n     * @method replace\n     *\n     * replace node with provided nodeName\n     *\n     * @param {Node} node\n     * @param {String} nodeName\n     * @return {Node} - new node\n     */\n    var replace = function (node, nodeName) {\n      if (node.nodeName.toUpperCase() === nodeName.toUpperCase()) {\n        return node;\n      }\n\n      var newNode = create(nodeName);\n\n      if (node.style.cssText) {\n        newNode.style.cssText = node.style.cssText;\n      }\n\n      appendChildNodes(newNode, list.from(node.childNodes));\n      insertAfter(newNode, node);\n      remove(node);\n\n      return newNode;\n    };\n\n    var isTextarea = makePredByNodeName('TEXTAREA');\n\n    /**\n     * @param {jQuery} $node\n     * @param {Boolean} [stripLinebreaks] - default: false\n     */\n    var value = function ($node, stripLinebreaks) {\n      var val = isTextarea($node[0]) ? $node.val() : $node.html();\n      if (stripLinebreaks) {\n        return val.replace(/[\\n\\r]/g, '');\n      }\n      return val;\n    };\n\n    /**\n     * @method html\n     *\n     * get the HTML contents of node\n     *\n     * @param {jQuery} $node\n     * @param {Boolean} [isNewlineOnBlock]\n     */\n    var html = function ($node, isNewlineOnBlock) {\n      var markup = value($node);\n\n      if (isNewlineOnBlock) {\n        var regexTag = /<(\\/?)(\\b(?!!)[^>\\s]*)(.*?)(\\s*\\/?>)/g;\n        markup = markup.replace(regexTag, function (match, endSlash, name) {\n          name = name.toUpperCase();\n          var isEndOfInlineContainer = /^DIV|^TD|^TH|^P|^LI|^H[1-7]/.test(name) &&\n                                       !!endSlash;\n          var isBlockNode = /^BLOCKQUOTE|^TABLE|^TBODY|^TR|^HR|^UL|^OL/.test(name);\n\n          return match + ((isEndOfInlineContainer || isBlockNode) ? '\\n' : '');\n        });\n        markup = $.trim(markup);\n      }\n\n      return markup;\n    };\n\n    return {\n      /** @property {String} NBSP_CHAR */\n      NBSP_CHAR: NBSP_CHAR,\n      /** @property {String} ZERO_WIDTH_NBSP_CHAR */\n      ZERO_WIDTH_NBSP_CHAR: ZERO_WIDTH_NBSP_CHAR,\n      /** @property {String} blank */\n      blank: blankHTML,\n      /** @property {String} emptyPara */\n      emptyPara: '<p>' + blankHTML + '</p>',\n      makePredByNodeName: makePredByNodeName,\n      isEditable: isEditable,\n      isControlSizing: isControlSizing,\n      buildLayoutInfo: buildLayoutInfo,\n      makeLayoutInfo: makeLayoutInfo,\n      isText: isText,\n      isVoid: isVoid,\n      isPara: isPara,\n      isPurePara: isPurePara,\n      isInline: isInline,\n      isBlock: func.not(isInline),\n      isBodyInline: isBodyInline,\n      isBody: isBody,\n      isParaInline: isParaInline,\n      isList: isList,\n      isTable: isTable,\n      isCell: isCell,\n      isBlockquote: isBlockquote,\n      isBodyContainer: isBodyContainer,\n      isAnchor: isAnchor,\n      isDiv: makePredByNodeName('DIV'),\n      isLi: isLi,\n      isBR: makePredByNodeName('BR'),\n      isSpan: makePredByNodeName('SPAN'),\n      isB: makePredByNodeName('B'),\n      isU: makePredByNodeName('U'),\n      isS: makePredByNodeName('S'),\n      isI: makePredByNodeName('I'),\n      isImg: makePredByNodeName('IMG'),\n      isTextarea: isTextarea,\n      isEmpty: isEmpty,\n      isEmptyAnchor: func.and(isAnchor, isEmpty),\n      isClosestSibling: isClosestSibling,\n      withClosestSiblings: withClosestSiblings,\n      nodeLength: nodeLength,\n      isLeftEdgePoint: isLeftEdgePoint,\n      isRightEdgePoint: isRightEdgePoint,\n      isEdgePoint: isEdgePoint,\n      isLeftEdgeOf: isLeftEdgeOf,\n      isRightEdgeOf: isRightEdgeOf,\n      isLeftEdgePointOf: isLeftEdgePointOf,\n      isRightEdgePointOf: isRightEdgePointOf,\n      prevPoint: prevPoint,\n      nextPoint: nextPoint,\n      isSamePoint: isSamePoint,\n      isVisiblePoint: isVisiblePoint,\n      prevPointUntil: prevPointUntil,\n      nextPointUntil: nextPointUntil,\n      isCharPoint: isCharPoint,\n      walkPoint: walkPoint,\n      ancestor: ancestor,\n      singleChildAncestor: singleChildAncestor,\n      listAncestor: listAncestor,\n      lastAncestor: lastAncestor,\n      listNext: listNext,\n      listPrev: listPrev,\n      listDescendant: listDescendant,\n      commonAncestor: commonAncestor,\n      wrap: wrap,\n      insertAfter: insertAfter,\n      appendChildNodes: appendChildNodes,\n      position: position,\n      hasChildren: hasChildren,\n      makeOffsetPath: makeOffsetPath,\n      fromOffsetPath: fromOffsetPath,\n      splitTree: splitTree,\n      splitPoint: splitPoint,\n      create: create,\n      createText: createText,\n      remove: remove,\n      removeWhile: removeWhile,\n      replace: replace,\n      html: html,\n      value: value\n    };\n  })();\n\n\n  var range = (function () {\n\n    /**\n     * return boundaryPoint from TextRange, inspired by Andy Na's HuskyRange.js\n     *\n     * @param {TextRange} textRange\n     * @param {Boolean} isStart\n     * @return {BoundaryPoint}\n     *\n     * @see http://msdn.microsoft.com/en-us/library/ie/ms535872(v=vs.85).aspx\n     */\n    var textRangeToPoint = function (textRange, isStart) {\n      var container = textRange.parentElement(), offset;\n  \n      var tester = document.body.createTextRange(), prevContainer;\n      var childNodes = list.from(container.childNodes);\n      for (offset = 0; offset < childNodes.length; offset++) {\n        if (dom.isText(childNodes[offset])) {\n          continue;\n        }\n        tester.moveToElementText(childNodes[offset]);\n        if (tester.compareEndPoints('StartToStart', textRange) >= 0) {\n          break;\n        }\n        prevContainer = childNodes[offset];\n      }\n  \n      if (offset !== 0 && dom.isText(childNodes[offset - 1])) {\n        var textRangeStart = document.body.createTextRange(), curTextNode = null;\n        textRangeStart.moveToElementText(prevContainer || container);\n        textRangeStart.collapse(!prevContainer);\n        curTextNode = prevContainer ? prevContainer.nextSibling : container.firstChild;\n  \n        var pointTester = textRange.duplicate();\n        pointTester.setEndPoint('StartToStart', textRangeStart);\n        var textCount = pointTester.text.replace(/[\\r\\n]/g, '').length;\n  \n        while (textCount > curTextNode.nodeValue.length && curTextNode.nextSibling) {\n          textCount -= curTextNode.nodeValue.length;\n          curTextNode = curTextNode.nextSibling;\n        }\n  \n        /* jshint ignore:start */\n        var dummy = curTextNode.nodeValue; // enforce IE to re-reference curTextNode, hack\n        /* jshint ignore:end */\n  \n        if (isStart && curTextNode.nextSibling && dom.isText(curTextNode.nextSibling) &&\n            textCount === curTextNode.nodeValue.length) {\n          textCount -= curTextNode.nodeValue.length;\n          curTextNode = curTextNode.nextSibling;\n        }\n  \n        container = curTextNode;\n        offset = textCount;\n      }\n  \n      return {\n        cont: container,\n        offset: offset\n      };\n    };\n    \n    /**\n     * return TextRange from boundary point (inspired by google closure-library)\n     * @param {BoundaryPoint} point\n     * @return {TextRange}\n     */\n    var pointToTextRange = function (point) {\n      var textRangeInfo = function (container, offset) {\n        var node, isCollapseToStart;\n  \n        if (dom.isText(container)) {\n          var prevTextNodes = dom.listPrev(container, func.not(dom.isText));\n          var prevContainer = list.last(prevTextNodes).previousSibling;\n          node =  prevContainer || container.parentNode;\n          offset += list.sum(list.tail(prevTextNodes), dom.nodeLength);\n          isCollapseToStart = !prevContainer;\n        } else {\n          node = container.childNodes[offset] || container;\n          if (dom.isText(node)) {\n            return textRangeInfo(node, 0);\n          }\n  \n          offset = 0;\n          isCollapseToStart = false;\n        }\n  \n        return {\n          node: node,\n          collapseToStart: isCollapseToStart,\n          offset: offset\n        };\n      };\n  \n      var textRange = document.body.createTextRange();\n      var info = textRangeInfo(point.node, point.offset);\n  \n      textRange.moveToElementText(info.node);\n      textRange.collapse(info.collapseToStart);\n      textRange.moveStart('character', info.offset);\n      return textRange;\n    };\n    \n    /**\n     * Wrapped Range\n     *\n     * @constructor\n     * @param {Node} sc - start container\n     * @param {Number} so - start offset\n     * @param {Node} ec - end container\n     * @param {Number} eo - end offset\n     */\n    var WrappedRange = function (sc, so, ec, eo) {\n      this.sc = sc;\n      this.so = so;\n      this.ec = ec;\n      this.eo = eo;\n  \n      // nativeRange: get nativeRange from sc, so, ec, eo\n      var nativeRange = function () {\n        if (agent.isW3CRangeSupport) {\n          var w3cRange = document.createRange();\n          w3cRange.setStart(sc, so);\n          w3cRange.setEnd(ec, eo);\n\n          return w3cRange;\n        } else {\n          var textRange = pointToTextRange({\n            node: sc,\n            offset: so\n          });\n\n          textRange.setEndPoint('EndToEnd', pointToTextRange({\n            node: ec,\n            offset: eo\n          }));\n\n          return textRange;\n        }\n      };\n\n      this.getPoints = function () {\n        return {\n          sc: sc,\n          so: so,\n          ec: ec,\n          eo: eo\n        };\n      };\n\n      this.getStartPoint = function () {\n        return {\n          node: sc,\n          offset: so\n        };\n      };\n\n      this.getEndPoint = function () {\n        return {\n          node: ec,\n          offset: eo\n        };\n      };\n\n      /**\n       * select update visible range\n       */\n      this.select = function () {\n        var nativeRng = nativeRange();\n        if (agent.isW3CRangeSupport) {\n          var selection = document.getSelection();\n          if (selection.rangeCount > 0) {\n            selection.removeAllRanges();\n          }\n          selection.addRange(nativeRng);\n        } else {\n          nativeRng.select();\n        }\n        \n        return this;\n      };\n\n      /**\n       * @return {WrappedRange}\n       */\n      this.normalize = function () {\n\n        /**\n         * @param {BoundaryPoint} point\n         * @param {Boolean} isLeftToRight\n         * @return {BoundaryPoint}\n         */\n        var getVisiblePoint = function (point, isLeftToRight) {\n          if ((dom.isVisiblePoint(point) && !dom.isEdgePoint(point)) ||\n              (dom.isVisiblePoint(point) && dom.isRightEdgePoint(point) && !isLeftToRight) ||\n              (dom.isVisiblePoint(point) && dom.isLeftEdgePoint(point) && isLeftToRight) ||\n              (dom.isVisiblePoint(point) && dom.isBlock(point.node) && dom.isEmpty(point.node))) {\n            return point;\n          }\n\n          // point on block's edge\n          var block = dom.ancestor(point.node, dom.isBlock);\n          if (((dom.isLeftEdgePointOf(point, block) || dom.isVoid(dom.prevPoint(point).node)) && !isLeftToRight) ||\n              ((dom.isRightEdgePointOf(point, block) || dom.isVoid(dom.nextPoint(point).node)) && isLeftToRight)) {\n\n            // returns point already on visible point\n            if (dom.isVisiblePoint(point)) {\n              return point;\n            }\n            // reverse direction \n            isLeftToRight = !isLeftToRight;\n          }\n\n          var nextPoint = isLeftToRight ? dom.nextPointUntil(dom.nextPoint(point), dom.isVisiblePoint) :\n                                          dom.prevPointUntil(dom.prevPoint(point), dom.isVisiblePoint);\n          return nextPoint || point;\n        };\n\n        var endPoint = getVisiblePoint(this.getEndPoint(), false);\n        var startPoint = this.isCollapsed() ? endPoint : getVisiblePoint(this.getStartPoint(), true);\n\n        return new WrappedRange(\n          startPoint.node,\n          startPoint.offset,\n          endPoint.node,\n          endPoint.offset\n        );\n      };\n\n      /**\n       * returns matched nodes on range\n       *\n       * @param {Function} [pred] - predicate function\n       * @param {Object} [options]\n       * @param {Boolean} [options.includeAncestor]\n       * @param {Boolean} [options.fullyContains]\n       * @return {Node[]}\n       */\n      this.nodes = function (pred, options) {\n        pred = pred || func.ok;\n\n        var includeAncestor = options && options.includeAncestor;\n        var fullyContains = options && options.fullyContains;\n\n        // TODO compare points and sort\n        var startPoint = this.getStartPoint();\n        var endPoint = this.getEndPoint();\n\n        var nodes = [];\n        var leftEdgeNodes = [];\n\n        dom.walkPoint(startPoint, endPoint, function (point) {\n          if (dom.isEditable(point.node)) {\n            return;\n          }\n\n          var node;\n          if (fullyContains) {\n            if (dom.isLeftEdgePoint(point)) {\n              leftEdgeNodes.push(point.node);\n            }\n            if (dom.isRightEdgePoint(point) && list.contains(leftEdgeNodes, point.node)) {\n              node = point.node;\n            }\n          } else if (includeAncestor) {\n            node = dom.ancestor(point.node, pred);\n          } else {\n            node = point.node;\n          }\n\n          if (node && pred(node)) {\n            nodes.push(node);\n          }\n        }, true);\n\n        return list.unique(nodes);\n      };\n\n      /**\n       * returns commonAncestor of range\n       * @return {Element} - commonAncestor\n       */\n      this.commonAncestor = function () {\n        return dom.commonAncestor(sc, ec);\n      };\n\n      /**\n       * returns expanded range by pred\n       *\n       * @param {Function} pred - predicate function\n       * @return {WrappedRange}\n       */\n      this.expand = function (pred) {\n        var startAncestor = dom.ancestor(sc, pred);\n        var endAncestor = dom.ancestor(ec, pred);\n\n        if (!startAncestor && !endAncestor) {\n          return new WrappedRange(sc, so, ec, eo);\n        }\n\n        var boundaryPoints = this.getPoints();\n\n        if (startAncestor) {\n          boundaryPoints.sc = startAncestor;\n          boundaryPoints.so = 0;\n        }\n\n        if (endAncestor) {\n          boundaryPoints.ec = endAncestor;\n          boundaryPoints.eo = dom.nodeLength(endAncestor);\n        }\n\n        return new WrappedRange(\n          boundaryPoints.sc,\n          boundaryPoints.so,\n          boundaryPoints.ec,\n          boundaryPoints.eo\n        );\n      };\n\n      /**\n       * @param {Boolean} isCollapseToStart\n       * @return {WrappedRange}\n       */\n      this.collapse = function (isCollapseToStart) {\n        if (isCollapseToStart) {\n          return new WrappedRange(sc, so, sc, so);\n        } else {\n          return new WrappedRange(ec, eo, ec, eo);\n        }\n      };\n\n      /**\n       * splitText on range\n       */\n      this.splitText = function () {\n        var isSameContainer = sc === ec;\n        var boundaryPoints = this.getPoints();\n\n        if (dom.isText(ec) && !dom.isEdgePoint(this.getEndPoint())) {\n          ec.splitText(eo);\n        }\n\n        if (dom.isText(sc) && !dom.isEdgePoint(this.getStartPoint())) {\n          boundaryPoints.sc = sc.splitText(so);\n          boundaryPoints.so = 0;\n\n          if (isSameContainer) {\n            boundaryPoints.ec = boundaryPoints.sc;\n            boundaryPoints.eo = eo - so;\n          }\n        }\n\n        return new WrappedRange(\n          boundaryPoints.sc,\n          boundaryPoints.so,\n          boundaryPoints.ec,\n          boundaryPoints.eo\n        );\n      };\n\n      /**\n       * delete contents on range\n       * @return {WrappedRange}\n       */\n      this.deleteContents = function () {\n        if (this.isCollapsed()) {\n          return this;\n        }\n\n        var rng = this.splitText();\n        var nodes = rng.nodes(null, {\n          fullyContains: true\n        });\n\n        // find new cursor point\n        var point = dom.prevPointUntil(rng.getStartPoint(), function (point) {\n          return !list.contains(nodes, point.node);\n        });\n\n        var emptyParents = [];\n        $.each(nodes, function (idx, node) {\n          // find empty parents\n          var parent = node.parentNode;\n          if (point.node !== parent && dom.nodeLength(parent) === 1) {\n            emptyParents.push(parent);\n          }\n          dom.remove(node, false);\n        });\n\n        // remove empty parents\n        $.each(emptyParents, function (idx, node) {\n          dom.remove(node, false);\n        });\n\n        return new WrappedRange(\n          point.node,\n          point.offset,\n          point.node,\n          point.offset\n        ).normalize();\n      };\n      \n      /**\n       * makeIsOn: return isOn(pred) function\n       */\n      var makeIsOn = function (pred) {\n        return function () {\n          var ancestor = dom.ancestor(sc, pred);\n          return !!ancestor && (ancestor === dom.ancestor(ec, pred));\n        };\n      };\n  \n      // isOnEditable: judge whether range is on editable or not\n      this.isOnEditable = makeIsOn(dom.isEditable);\n      // isOnList: judge whether range is on list node or not\n      this.isOnList = makeIsOn(dom.isList);\n      // isOnAnchor: judge whether range is on anchor node or not\n      this.isOnAnchor = makeIsOn(dom.isAnchor);\n      // isOnAnchor: judge whether range is on cell node or not\n      this.isOnCell = makeIsOn(dom.isCell);\n\n      /**\n       * @param {Function} pred\n       * @return {Boolean}\n       */\n      this.isLeftEdgeOf = function (pred) {\n        if (!dom.isLeftEdgePoint(this.getStartPoint())) {\n          return false;\n        }\n\n        var node = dom.ancestor(this.sc, pred);\n        return node && dom.isLeftEdgeOf(this.sc, node);\n      };\n\n      /**\n       * returns whether range was collapsed or not\n       */\n      this.isCollapsed = function () {\n        return sc === ec && so === eo;\n      };\n\n      /**\n       * wrap inline nodes which children of body with paragraph\n       *\n       * @return {WrappedRange}\n       */\n      this.wrapBodyInlineWithPara = function () {\n        if (dom.isBodyContainer(sc) && dom.isEmpty(sc)) {\n          sc.innerHTML = dom.emptyPara;\n          return new WrappedRange(sc.firstChild, 0, sc.firstChild, 0);\n        }\n\n        /**\n         * [workaround] firefox often create range on not visible point. so normalize here.\n         *  - firefox: |<p>text</p>|\n         *  - chrome: <p>|text|</p>\n         */\n        var rng = this.normalize();\n        if (dom.isParaInline(sc) || dom.isPara(sc)) {\n          return rng;\n        }\n\n        // find inline top ancestor\n        var topAncestor;\n        if (dom.isInline(rng.sc)) {\n          var ancestors = dom.listAncestor(rng.sc, func.not(dom.isInline));\n          topAncestor = list.last(ancestors);\n          if (!dom.isInline(topAncestor)) {\n            topAncestor = ancestors[ancestors.length - 2] || rng.sc.childNodes[rng.so];\n          }\n        } else {\n          topAncestor = rng.sc.childNodes[rng.so > 0 ? rng.so - 1 : 0];\n        }\n\n        // siblings not in paragraph\n        var inlineSiblings = dom.listPrev(topAncestor, dom.isParaInline).reverse();\n        inlineSiblings = inlineSiblings.concat(dom.listNext(topAncestor.nextSibling, dom.isParaInline));\n\n        // wrap with paragraph\n        if (inlineSiblings.length) {\n          var para = dom.wrap(list.head(inlineSiblings), 'p');\n          dom.appendChildNodes(para, list.tail(inlineSiblings));\n        }\n\n        return this.normalize();\n      };\n\n      /**\n       * insert node at current cursor\n       *\n       * @param {Node} node\n       * @return {Node}\n       */\n      this.insertNode = function (node) {\n        var rng = this.wrapBodyInlineWithPara().deleteContents();\n        var info = dom.splitPoint(rng.getStartPoint(), dom.isInline(node));\n\n        if (info.rightNode) {\n          info.rightNode.parentNode.insertBefore(node, info.rightNode);\n        } else {\n          info.container.appendChild(node);\n        }\n\n        return node;\n      };\n\n      /**\n       * insert html at current cursor\n       */\n      this.pasteHTML = function (markup) {\n        var contentsContainer = $('<div></div>').html(markup)[0];\n        var childNodes = list.from(contentsContainer.childNodes);\n\n        var rng = this.wrapBodyInlineWithPara().deleteContents();\n\n        return childNodes.reverse().map(function (childNode) {\n          return rng.insertNode(childNode);\n        }).reverse();\n      };\n  \n      /**\n       * returns text in range\n       *\n       * @return {String}\n       */\n      this.toString = function () {\n        var nativeRng = nativeRange();\n        return agent.isW3CRangeSupport ? nativeRng.toString() : nativeRng.text;\n      };\n\n      /**\n       * returns range for word before cursor\n       *\n       * @param {Boolean} [findAfter] - find after cursor, default: false\n       * @return {WrappedRange}\n       */\n      this.getWordRange = function (findAfter) {\n        var endPoint = this.getEndPoint();\n\n        if (!dom.isCharPoint(endPoint)) {\n          return this;\n        }\n\n        var startPoint = dom.prevPointUntil(endPoint, function (point) {\n          return !dom.isCharPoint(point);\n        });\n\n        if (findAfter) {\n          endPoint = dom.nextPointUntil(endPoint, function (point) {\n            return !dom.isCharPoint(point);\n          });\n        }\n\n        return new WrappedRange(\n          startPoint.node,\n          startPoint.offset,\n          endPoint.node,\n          endPoint.offset\n        );\n      };\n  \n      /**\n       * create offsetPath bookmark\n       *\n       * @param {Node} editable\n       */\n      this.bookmark = function (editable) {\n        return {\n          s: {\n            path: dom.makeOffsetPath(editable, sc),\n            offset: so\n          },\n          e: {\n            path: dom.makeOffsetPath(editable, ec),\n            offset: eo\n          }\n        };\n      };\n\n      /**\n       * create offsetPath bookmark base on paragraph\n       *\n       * @param {Node[]} paras\n       */\n      this.paraBookmark = function (paras) {\n        return {\n          s: {\n            path: list.tail(dom.makeOffsetPath(list.head(paras), sc)),\n            offset: so\n          },\n          e: {\n            path: list.tail(dom.makeOffsetPath(list.last(paras), ec)),\n            offset: eo\n          }\n        };\n      };\n\n      /**\n       * getClientRects\n       * @return {Rect[]}\n       */\n      this.getClientRects = function () {\n        var nativeRng = nativeRange();\n        return nativeRng.getClientRects();\n      };\n    };\n\n  /**\n   * @class core.range\n   *\n   * Data structure\n   *  * BoundaryPoint: a point of dom tree\n   *  * BoundaryPoints: two boundaryPoints corresponding to the start and the end of the Range\n   *\n   * See to http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Position\n   *\n   * @singleton\n   * @alternateClassName range\n   */\n    return {\n      /**\n       * @method\n       * \n       * create Range Object From arguments or Browser Selection\n       *\n       * @param {Node} sc - start container\n       * @param {Number} so - start offset\n       * @param {Node} ec - end container\n       * @param {Number} eo - end offset\n       * @return {WrappedRange}\n       */\n      create : function (sc, so, ec, eo) {\n        if (!arguments.length) { // from Browser Selection\n          if (agent.isW3CRangeSupport) {\n            var selection = document.getSelection();\n            if (!selection || selection.rangeCount === 0) {\n              return null;\n            } else if (dom.isBody(selection.anchorNode)) {\n              // Firefox: returns entire body as range on initialization. We won't never need it.\n              return null;\n            }\n  \n            var nativeRng = selection.getRangeAt(0);\n            sc = nativeRng.startContainer;\n            so = nativeRng.startOffset;\n            ec = nativeRng.endContainer;\n            eo = nativeRng.endOffset;\n          } else { // IE8: TextRange\n            var textRange = document.selection.createRange();\n            var textRangeEnd = textRange.duplicate();\n            textRangeEnd.collapse(false);\n            var textRangeStart = textRange;\n            textRangeStart.collapse(true);\n  \n            var startPoint = textRangeToPoint(textRangeStart, true),\n            endPoint = textRangeToPoint(textRangeEnd, false);\n\n            // same visible point case: range was collapsed.\n            if (dom.isText(startPoint.node) && dom.isLeftEdgePoint(startPoint) &&\n                dom.isTextNode(endPoint.node) && dom.isRightEdgePoint(endPoint) &&\n                endPoint.node.nextSibling === startPoint.node) {\n              startPoint = endPoint;\n            }\n\n            sc = startPoint.cont;\n            so = startPoint.offset;\n            ec = endPoint.cont;\n            eo = endPoint.offset;\n          }\n        } else if (arguments.length === 2) { //collapsed\n          ec = sc;\n          eo = so;\n        }\n        return new WrappedRange(sc, so, ec, eo);\n      },\n\n      /**\n       * @method \n       * \n       * create WrappedRange from node\n       *\n       * @param {Node} node\n       * @return {WrappedRange}\n       */\n      createFromNode: function (node) {\n        var sc = node;\n        var so = 0;\n        var ec = node;\n        var eo = dom.nodeLength(ec);\n\n        // browsers can't target a picture or void node\n        if (dom.isVoid(sc)) {\n          so = dom.listPrev(sc).length - 1;\n          sc = sc.parentNode;\n        }\n        if (dom.isBR(ec)) {\n          eo = dom.listPrev(ec).length - 1;\n          ec = ec.parentNode;\n        } else if (dom.isVoid(ec)) {\n          eo = dom.listPrev(ec).length;\n          ec = ec.parentNode;\n        }\n\n        return this.create(sc, so, ec, eo);\n      },\n\n      /**\n       * create WrappedRange from node after position\n       *\n       * @param {Node} node\n       * @return {WrappedRange}\n       */\n      createFromNodeBefore: function (node) {\n        return this.createFromNode(node).collapse(true);\n      },\n\n      /**\n       * create WrappedRange from node after position\n       *\n       * @param {Node} node\n       * @return {WrappedRange}\n       */\n      createFromNodeAfter: function (node) {\n        return this.createFromNode(node).collapse();\n      },\n\n      /**\n       * @method \n       * \n       * create WrappedRange from bookmark\n       *\n       * @param {Node} editable\n       * @param {Object} bookmark\n       * @return {WrappedRange}\n       */\n      createFromBookmark : function (editable, bookmark) {\n        var sc = dom.fromOffsetPath(editable, bookmark.s.path);\n        var so = bookmark.s.offset;\n        var ec = dom.fromOffsetPath(editable, bookmark.e.path);\n        var eo = bookmark.e.offset;\n        return new WrappedRange(sc, so, ec, eo);\n      },\n\n      /**\n       * @method \n       *\n       * create WrappedRange from paraBookmark\n       *\n       * @param {Object} bookmark\n       * @param {Node[]} paras\n       * @return {WrappedRange}\n       */\n      createFromParaBookmark: function (bookmark, paras) {\n        var so = bookmark.s.offset;\n        var eo = bookmark.e.offset;\n        var sc = dom.fromOffsetPath(list.head(paras), bookmark.s.path);\n        var ec = dom.fromOffsetPath(list.last(paras), bookmark.e.path);\n\n        return new WrappedRange(sc, so, ec, eo);\n      }\n    };\n  })();\n\n  /**\n   * @class defaults \n   * \n   * @singleton\n   */\n  var defaults = {\n    /** @property */\n    version: '0.6.16',\n\n    /**\n     * \n     * for event options, reference to EventHandler.attach\n     * \n     * @property {Object} options \n     * @property {String/Number} [options.width=null] set editor width \n     * @property {String/Number} [options.height=null] set editor height, ex) 300\n     * @property {String/Number} options.minHeight set minimum height of editor\n     * @property {String/Number} options.maxHeight\n     * @property {String/Number} options.focus \n     * @property {Number} options.tabsize \n     * @property {Boolean} options.styleWithSpan\n     * @property {Object} options.codemirror\n     * @property {Object} [options.codemirror.mode='text/html']\n     * @property {Object} [options.codemirror.htmlMode=true]\n     * @property {Object} [options.codemirror.lineNumbers=true]\n     * @property {String} [options.lang=en-US] language 'en-US', 'ko-KR', ...\n     * @property {String} [options.direction=null] text direction, ex) 'rtl'\n     * @property {Array} [options.toolbar]\n     * @property {Boolean} [options.airMode=false]\n     * @property {Array} [options.airPopover]\n     * @property {Fucntion} [options.onInit] initialize\n     * @property {Fucntion} [options.onsubmit]\n     */\n    options: {\n      width: null,                  // set editor width\n      height: null,                 // set editor height, ex) 300\n\n      minHeight: null,              // set minimum height of editor\n      maxHeight: null,              // set maximum height of editor\n\n      focus: false,                 // set focus to editable area after initializing summernote\n\n      tabsize: 4,                   // size of tab ex) 2 or 4\n      styleWithSpan: true,          // style with span (Chrome and FF only)\n\n      disableLinkTarget: false,     // hide link Target Checkbox\n      disableDragAndDrop: false,    // disable drag and drop event\n      disableResizeEditor: false,   // disable resizing editor\n      disableResizeImage: false,    // disable resizing image\n\n      shortcuts: true,              // enable keyboard shortcuts\n\n      textareaAutoSync: true,       // enable textarea auto sync\n\n      placeholder: false,           // enable placeholder text\n      prettifyHtml: true,           // enable prettifying html while toggling codeview\n\n      iconPrefix: 'fa fa-',         // prefix for css icon classes\n\n      icons: {\n        font: {\n          bold: 'bold',\n          italic: 'italic',\n          underline: 'underline',\n          clear: 'eraser',\n          height: 'text-height',\n          strikethrough: 'strikethrough',\n          superscript: 'superscript',\n          subscript: 'subscript'\n        },\n        image: {\n          image: 'picture-o',\n          floatLeft: 'align-left',\n          floatRight: 'align-right',\n          floatNone: 'align-justify',\n          shapeRounded: 'square',\n          shapeCircle: 'circle-o',\n          shapeThumbnail: 'picture-o',\n          shapeNone: 'times',\n          remove: 'trash-o'\n        },\n        link: {\n          link: 'link',\n          unlink: 'unlink',\n          edit: 'edit'\n        },\n        table: {\n          table: 'table'\n        },\n        hr: {\n          insert: 'minus'\n        },\n        style: {\n          style: 'magic'\n        },\n        lists: {\n          unordered: 'list-ul',\n          ordered: 'list-ol'\n        },\n        options: {\n          help: 'question',\n          fullscreen: 'arrows-alt',\n          codeview: 'code'\n        },\n        paragraph: {\n          paragraph: 'align-left',\n          outdent: 'outdent',\n          indent: 'indent',\n          left: 'align-left',\n          center: 'align-center',\n          right: 'align-right',\n          justify: 'align-justify'\n        },\n        color: {\n          recent: 'font'\n        },\n        history: {\n          undo: 'undo',\n          redo: 'repeat'\n        },\n        misc: {\n          check: 'check'\n        }\n      },\n\n      dialogsInBody: false,          // false will add dialogs into editor\n\n      codemirror: {                 // codemirror options\n        mode: 'text/html',\n        htmlMode: true,\n        lineNumbers: true\n      },\n\n      // language\n      lang: 'en-US',                // language 'en-US', 'ko-KR', ...\n      direction: null,              // text direction, ex) 'rtl'\n\n      // toolbar\n      toolbar: [\n        ['style', ['style']],\n        ['font', ['bold', 'italic', 'underline', 'clear']],\n        // ['font', ['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 'clear']],\n        ['fontname', ['fontname']],\n        ['fontsize', ['fontsize']],\n        ['color', ['color']],\n        ['para', ['ul', 'ol', 'paragraph']],\n        ['height', ['height']],\n        ['table', ['table']],\n        ['insert', ['link', 'picture', 'hr']],\n        ['view', ['fullscreen', 'codeview']],\n        ['help', ['help']]\n      ],\n\n      plugin : { },\n\n      // air mode: inline editor\n      airMode: false,\n      // airPopover: [\n      //   ['style', ['style']],\n      //   ['font', ['bold', 'italic', 'underline', 'clear']],\n      //   ['fontname', ['fontname']],\n      //   ['color', ['color']],\n      //   ['para', ['ul', 'ol', 'paragraph']],\n      //   ['height', ['height']],\n      //   ['table', ['table']],\n      //   ['insert', ['link', 'picture']],\n      //   ['help', ['help']]\n      // ],\n      airPopover: [\n        ['color', ['color']],\n        ['font', ['bold', 'underline', 'clear']],\n        ['para', ['ul', 'paragraph']],\n        ['table', ['table']],\n        ['insert', ['link', 'picture']]\n      ],\n\n      // style tag\n      styleTags: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'],\n\n      // default fontName\n      defaultFontName: 'Helvetica Neue',\n\n      // fontName\n      fontNames: [\n        'Arial', 'Arial Black', 'Comic Sans MS', 'Courier New',\n        'Helvetica Neue', 'Helvetica', 'Impact', 'Lucida Grande',\n        'Tahoma', 'Times New Roman', 'Verdana'\n      ],\n      fontNamesIgnoreCheck: [],\n\n      fontSizes: ['8', '9', '10', '11', '12', '14', '18', '24', '36'],\n\n      // pallete colors(n x n)\n      colors: [\n        ['#000000', '#424242', '#636363', '#9C9C94', '#CEC6CE', '#EFEFEF', '#F7F7F7', '#FFFFFF'],\n        ['#FF0000', '#FF9C00', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF', '#9C00FF', '#FF00FF'],\n        ['#F7C6CE', '#FFE7CE', '#FFEFC6', '#D6EFD6', '#CEDEE7', '#CEE7F7', '#D6D6E7', '#E7D6DE'],\n        ['#E79C9C', '#FFC69C', '#FFE79C', '#B5D6A5', '#A5C6CE', '#9CC6EF', '#B5A5D6', '#D6A5BD'],\n        ['#E76363', '#F7AD6B', '#FFD663', '#94BD7B', '#73A5AD', '#6BADDE', '#8C7BC6', '#C67BA5'],\n        ['#CE0000', '#E79439', '#EFC631', '#6BA54A', '#4A7B8C', '#3984C6', '#634AA5', '#A54A7B'],\n        ['#9C0000', '#B56308', '#BD9400', '#397B21', '#104A5A', '#085294', '#311873', '#731842'],\n        ['#630000', '#7B3900', '#846300', '#295218', '#083139', '#003163', '#21104A', '#4A1031']\n      ],\n\n      // lineHeight\n      lineHeights: ['1.0', '1.2', '1.4', '1.5', '1.6', '1.8', '2.0', '3.0'],\n\n      // insertTable max size\n      insertTableMaxSize: {\n        col: 10,\n        row: 10\n      },\n\n      // image\n      maximumImageFileSize: null, // size in bytes, null = no limit\n\n      // callbacks\n      oninit: null,             // initialize\n      onfocus: null,            // editable has focus\n      onblur: null,             // editable out of focus\n      onenter: null,            // enter key pressed\n      onkeyup: null,            // keyup\n      onkeydown: null,          // keydown\n      onImageUpload: null,      // imageUpload\n      onImageUploadError: null, // imageUploadError\n      onMediaDelete: null,      // media delete\n      onToolbarClick: null,\n      onsubmit: null,\n\n      /**\n       * manipulate link address when user create link\n       * @param {String} sLinkUrl\n       * @return {String}\n       */\n      onCreateLink: function (sLinkUrl) {\n        if (sLinkUrl.indexOf('@') !== -1 && sLinkUrl.indexOf(':') === -1) {\n          sLinkUrl =  'mailto:' + sLinkUrl;\n        }\n\n        return sLinkUrl;\n      },\n\n      keyMap: {\n        pc: {\n          'ENTER': 'insertParagraph',\n          'CTRL+Z': 'undo',\n          'CTRL+Y': 'redo',\n          'TAB': 'tab',\n          'SHIFT+TAB': 'untab',\n          'CTRL+B': 'bold',\n          'CTRL+I': 'italic',\n          'CTRL+U': 'underline',\n          'CTRL+SHIFT+S': 'strikethrough',\n          'CTRL+BACKSLASH': 'removeFormat',\n          'CTRL+SHIFT+L': 'justifyLeft',\n          'CTRL+SHIFT+E': 'justifyCenter',\n          'CTRL+SHIFT+R': 'justifyRight',\n          'CTRL+SHIFT+J': 'justifyFull',\n          'CTRL+SHIFT+NUM7': 'insertUnorderedList',\n          'CTRL+SHIFT+NUM8': 'insertOrderedList',\n          'CTRL+LEFTBRACKET': 'outdent',\n          'CTRL+RIGHTBRACKET': 'indent',\n          'CTRL+NUM0': 'formatPara',\n          'CTRL+NUM1': 'formatH1',\n          'CTRL+NUM2': 'formatH2',\n          'CTRL+NUM3': 'formatH3',\n          'CTRL+NUM4': 'formatH4',\n          'CTRL+NUM5': 'formatH5',\n          'CTRL+NUM6': 'formatH6',\n          'CTRL+ENTER': 'insertHorizontalRule',\n          'CTRL+K': 'showLinkDialog'\n        },\n\n        mac: {\n          'ENTER': 'insertParagraph',\n          'CMD+Z': 'undo',\n          'CMD+SHIFT+Z': 'redo',\n          'TAB': 'tab',\n          'SHIFT+TAB': 'untab',\n          'CMD+B': 'bold',\n          'CMD+I': 'italic',\n          'CMD+U': 'underline',\n          'CMD+SHIFT+S': 'strikethrough',\n          'CMD+BACKSLASH': 'removeFormat',\n          'CMD+SHIFT+L': 'justifyLeft',\n          'CMD+SHIFT+E': 'justifyCenter',\n          'CMD+SHIFT+R': 'justifyRight',\n          'CMD+SHIFT+J': 'justifyFull',\n          'CMD+SHIFT+NUM7': 'insertUnorderedList',\n          'CMD+SHIFT+NUM8': 'insertOrderedList',\n          'CMD+LEFTBRACKET': 'outdent',\n          'CMD+RIGHTBRACKET': 'indent',\n          'CMD+NUM0': 'formatPara',\n          'CMD+NUM1': 'formatH1',\n          'CMD+NUM2': 'formatH2',\n          'CMD+NUM3': 'formatH3',\n          'CMD+NUM4': 'formatH4',\n          'CMD+NUM5': 'formatH5',\n          'CMD+NUM6': 'formatH6',\n          'CMD+ENTER': 'insertHorizontalRule',\n          'CMD+K': 'showLinkDialog'\n        }\n      }\n    },\n\n    // default language: en-US\n    lang: {\n      'en-US': {\n        font: {\n          bold: 'Bold',\n          italic: 'Italic',\n          underline: 'Underline',\n          clear: 'Remove Font Style',\n          height: 'Line Height',\n          name: 'Font Family',\n          strikethrough: 'Strikethrough',\n          subscript: 'Subscript',\n          superscript: 'Superscript',\n          size: 'Font Size'\n        },\n        image: {\n          image: 'Picture',\n          insert: 'Insert Image',\n          resizeFull: 'Resize Full',\n          resizeHalf: 'Resize Half',\n          resizeQuarter: 'Resize Quarter',\n          floatLeft: 'Float Left',\n          floatRight: 'Float Right',\n          floatNone: 'Float None',\n          shapeRounded: 'Shape: Rounded',\n          shapeCircle: 'Shape: Circle',\n          shapeThumbnail: 'Shape: Thumbnail',\n          shapeNone: 'Shape: None',\n          dragImageHere: 'Drag image or text here',\n          dropImage: 'Drop image or Text',\n          selectFromFiles: 'Select from files',\n          maximumFileSize: 'Maximum file size',\n          maximumFileSizeError: 'Maximum file size exceeded.',\n          url: 'Image URL',\n          remove: 'Remove Image'\n        },\n        link: {\n          link: 'Link',\n          insert: 'Insert Link',\n          unlink: 'Unlink',\n          edit: 'Edit',\n          textToDisplay: 'Text to display',\n          url: 'To what URL should this link go?',\n          openInNewWindow: 'Open in new window'\n        },\n        table: {\n          table: 'Table'\n        },\n        hr: {\n          insert: 'Insert Horizontal Rule'\n        },\n        style: {\n          style: 'Style',\n          normal: 'Normal',\n          blockquote: 'Quote',\n          pre: 'Code',\n          h1: 'Header 1',\n          h2: 'Header 2',\n          h3: 'Header 3',\n          h4: 'Header 4',\n          h5: 'Header 5',\n          h6: 'Header 6'\n        },\n        lists: {\n          unordered: 'Unordered list',\n          ordered: 'Ordered list'\n        },\n        options: {\n          help: 'Help',\n          fullscreen: 'Full Screen',\n          codeview: 'Code View'\n        },\n        paragraph: {\n          paragraph: 'Paragraph',\n          outdent: 'Outdent',\n          indent: 'Indent',\n          left: 'Align left',\n          center: 'Align center',\n          right: 'Align right',\n          justify: 'Justify full'\n        },\n        color: {\n          recent: 'Recent Color',\n          more: 'More Color',\n          background: 'Background Color',\n          foreground: 'Foreground Color',\n          transparent: 'Transparent',\n          setTransparent: 'Set transparent',\n          reset: 'Reset',\n          resetToDefault: 'Reset to default'\n        },\n        shortcut: {\n          shortcuts: 'Keyboard shortcuts',\n          close: 'Close',\n          textFormatting: 'Text formatting',\n          action: 'Action',\n          paragraphFormatting: 'Paragraph formatting',\n          documentStyle: 'Document Style',\n          extraKeys: 'Extra keys'\n        },\n        history: {\n          undo: 'Undo',\n          redo: 'Redo'\n        }\n      }\n    }\n  };\n\n  /**\n   * @class core.async\n   *\n   * Async functions which returns `Promise`\n   *\n   * @singleton\n   * @alternateClassName async\n   */\n  var async = (function () {\n    /**\n     * @method readFileAsDataURL\n     *\n     * read contents of file as representing URL\n     *\n     * @param {File} file\n     * @return {Promise} - then: sDataUrl\n     */\n    var readFileAsDataURL = function (file) {\n      return $.Deferred(function (deferred) {\n        $.extend(new FileReader(), {\n          onload: function (e) {\n            var sDataURL = e.target.result;\n            deferred.resolve(sDataURL);\n          },\n          onerror: function () {\n            deferred.reject(this);\n          }\n        }).readAsDataURL(file);\n      }).promise();\n    };\n  \n    /**\n     * @method createImage\n     *\n     * create `<image>` from url string\n     *\n     * @param {String} sUrl\n     * @param {String} filename\n     * @return {Promise} - then: $image\n     */\n    var createImage = function (sUrl, filename) {\n      return $.Deferred(function (deferred) {\n        var $img = $('<img>');\n\n        $img.one('load', function () {\n          $img.off('error abort');\n          deferred.resolve($img);\n        }).one('error abort', function () {\n          $img.off('load').detach();\n          deferred.reject($img);\n        }).css({\n          display: 'none'\n        }).appendTo(document.body).attr({\n          'src': sUrl,\n          'data-filename': filename\n        });\n      }).promise();\n    };\n\n    return {\n      readFileAsDataURL: readFileAsDataURL,\n      createImage: createImage\n    };\n  })();\n\n  /**\n   * @class core.key\n   *\n   * Object for keycodes.\n   *\n   * @singleton\n   * @alternateClassName key\n   */\n  var key = (function () {\n    var keyMap = {\n      'BACKSPACE': 8,\n      'TAB': 9,\n      'ENTER': 13,\n      'SPACE': 32,\n\n      // Number: 0-9\n      'NUM0': 48,\n      'NUM1': 49,\n      'NUM2': 50,\n      'NUM3': 51,\n      'NUM4': 52,\n      'NUM5': 53,\n      'NUM6': 54,\n      'NUM7': 55,\n      'NUM8': 56,\n\n      // Alphabet: a-z\n      'B': 66,\n      'E': 69,\n      'I': 73,\n      'J': 74,\n      'K': 75,\n      'L': 76,\n      'R': 82,\n      'S': 83,\n      'U': 85,\n      'V': 86,\n      'Y': 89,\n      'Z': 90,\n\n      'SLASH': 191,\n      'LEFTBRACKET': 219,\n      'BACKSLASH': 220,\n      'RIGHTBRACKET': 221\n    };\n\n    return {\n      /**\n       * @method isEdit\n       *\n       * @param {Number} keyCode\n       * @return {Boolean}\n       */\n      isEdit: function (keyCode) {\n        return list.contains([8, 9, 13, 32], keyCode);\n      },\n      /**\n       * @method isMove\n       *\n       * @param {Number} keyCode\n       * @return {Boolean}\n       */\n      isMove: function (keyCode) {\n        return list.contains([37, 38, 39, 40], keyCode);\n      },\n      /**\n       * @property {Object} nameFromCode\n       * @property {String} nameFromCode.8 \"BACKSPACE\"\n       */\n      nameFromCode: func.invertObject(keyMap),\n      code: keyMap\n    };\n  })();\n\n  /**\n   * @class editing.History\n   *\n   * Editor History\n   *\n   */\n  var History = function ($editable) {\n    var stack = [], stackOffset = -1;\n    var editable = $editable[0];\n\n    var makeSnapshot = function () {\n      var rng = range.create();\n      var emptyBookmark = {s: {path: [], offset: 0}, e: {path: [], offset: 0}};\n\n      return {\n        contents: $editable.html(),\n        bookmark: (rng ? rng.bookmark(editable) : emptyBookmark)\n      };\n    };\n\n    var applySnapshot = function (snapshot) {\n      if (snapshot.contents !== null) {\n        $editable.html(snapshot.contents);\n      }\n      if (snapshot.bookmark !== null) {\n        range.createFromBookmark(editable, snapshot.bookmark).select();\n      }\n    };\n\n    /**\n     * undo\n     */\n    this.undo = function () {\n      // Create snap shot if not yet recorded\n      if ($editable.html() !== stack[stackOffset].contents) {\n        this.recordUndo();\n      }\n\n      if (0 < stackOffset) {\n        stackOffset--;\n        applySnapshot(stack[stackOffset]);\n      }\n    };\n\n    /**\n     * redo\n     */\n    this.redo = function () {\n      if (stack.length - 1 > stackOffset) {\n        stackOffset++;\n        applySnapshot(stack[stackOffset]);\n      }\n    };\n\n    /**\n     * recorded undo\n     */\n    this.recordUndo = function () {\n      stackOffset++;\n\n      // Wash out stack after stackOffset\n      if (stack.length > stackOffset) {\n        stack = stack.slice(0, stackOffset);\n      }\n\n      // Create new snapshot and push it to the end\n      stack.push(makeSnapshot());\n    };\n\n    // Create first undo stack\n    this.recordUndo();\n  };\n\n  /**\n   * @class editing.Style\n   *\n   * Style\n   *\n   */\n  var Style = function () {\n    /**\n     * @method jQueryCSS\n     *\n     * [workaround] for old jQuery\n     * passing an array of style properties to .css()\n     * will result in an object of property-value pairs.\n     * (compability with version < 1.9)\n     *\n     * @private\n     * @param  {jQuery} $obj\n     * @param  {Array} propertyNames - An array of one or more CSS properties.\n     * @return {Object}\n     */\n    var jQueryCSS = function ($obj, propertyNames) {\n      if (agent.jqueryVersion < 1.9) {\n        var result = {};\n        $.each(propertyNames, function (idx, propertyName) {\n          result[propertyName] = $obj.css(propertyName);\n        });\n        return result;\n      }\n      return $obj.css.call($obj, propertyNames);\n    };\n\n    /**\n     * returns style object from node\n     *\n     * @param {jQuery} $node\n     * @return {Object}\n     */\n    this.fromNode = function ($node) {\n      var properties = ['font-family', 'font-size', 'text-align', 'list-style-type', 'line-height'];\n      var styleInfo = jQueryCSS($node, properties) || {};\n      styleInfo['font-size'] = parseInt(styleInfo['font-size'], 10);\n      return styleInfo;\n    };\n\n    /**\n     * paragraph level style\n     *\n     * @param {WrappedRange} rng\n     * @param {Object} styleInfo\n     */\n    this.stylePara = function (rng, styleInfo) {\n      $.each(rng.nodes(dom.isPara, {\n        includeAncestor: true\n      }), function (idx, para) {\n        $(para).css(styleInfo);\n      });\n    };\n\n    /**\n     * insert and returns styleNodes on range.\n     *\n     * @param {WrappedRange} rng\n     * @param {Object} [options] - options for styleNodes\n     * @param {String} [options.nodeName] - default: `SPAN`\n     * @param {Boolean} [options.expandClosestSibling] - default: `false`\n     * @param {Boolean} [options.onlyPartialContains] - default: `false`\n     * @return {Node[]}\n     */\n    this.styleNodes = function (rng, options) {\n      rng = rng.splitText();\n\n      var nodeName = options && options.nodeName || 'SPAN';\n      var expandClosestSibling = !!(options && options.expandClosestSibling);\n      var onlyPartialContains = !!(options && options.onlyPartialContains);\n\n      if (rng.isCollapsed()) {\n        return [rng.insertNode(dom.create(nodeName))];\n      }\n\n      var pred = dom.makePredByNodeName(nodeName);\n      var nodes = rng.nodes(dom.isText, {\n        fullyContains: true\n      }).map(function (text) {\n        return dom.singleChildAncestor(text, pred) || dom.wrap(text, nodeName);\n      });\n\n      if (expandClosestSibling) {\n        if (onlyPartialContains) {\n          var nodesInRange = rng.nodes();\n          // compose with partial contains predication\n          pred = func.and(pred, function (node) {\n            return list.contains(nodesInRange, node);\n          });\n        }\n\n        return nodes.map(function (node) {\n          var siblings = dom.withClosestSiblings(node, pred);\n          var head = list.head(siblings);\n          var tails = list.tail(siblings);\n          $.each(tails, function (idx, elem) {\n            dom.appendChildNodes(head, elem.childNodes);\n            dom.remove(elem);\n          });\n          return list.head(siblings);\n        });\n      } else {\n        return nodes;\n      }\n    };\n\n    /**\n     * get current style on cursor\n     *\n     * @param {WrappedRange} rng\n     * @return {Object} - object contains style properties.\n     */\n    this.current = function (rng) {\n      var $cont = $(dom.isText(rng.sc) ? rng.sc.parentNode : rng.sc);\n      var styleInfo = this.fromNode($cont);\n\n      // document.queryCommandState for toggle state\n      styleInfo['font-bold'] = document.queryCommandState('bold') ? 'bold' : 'normal';\n      styleInfo['font-italic'] = document.queryCommandState('italic') ? 'italic' : 'normal';\n      styleInfo['font-underline'] = document.queryCommandState('underline') ? 'underline' : 'normal';\n      styleInfo['font-strikethrough'] = document.queryCommandState('strikeThrough') ? 'strikethrough' : 'normal';\n      styleInfo['font-superscript'] = document.queryCommandState('superscript') ? 'superscript' : 'normal';\n      styleInfo['font-subscript'] = document.queryCommandState('subscript') ? 'subscript' : 'normal';\n\n      // list-style-type to list-style(unordered, ordered)\n      if (!rng.isOnList()) {\n        styleInfo['list-style'] = 'none';\n      } else {\n        var aOrderedType = ['circle', 'disc', 'disc-leading-zero', 'square'];\n        var isUnordered = $.inArray(styleInfo['list-style-type'], aOrderedType) > -1;\n        styleInfo['list-style'] = isUnordered ? 'unordered' : 'ordered';\n      }\n\n      var para = dom.ancestor(rng.sc, dom.isPara);\n      if (para && para.style['line-height']) {\n        styleInfo['line-height'] = para.style.lineHeight;\n      } else {\n        var lineHeight = parseInt(styleInfo['line-height'], 10) / parseInt(styleInfo['font-size'], 10);\n        styleInfo['line-height'] = lineHeight.toFixed(1);\n      }\n\n      styleInfo.anchor = rng.isOnAnchor() && dom.ancestor(rng.sc, dom.isAnchor);\n      styleInfo.ancestors = dom.listAncestor(rng.sc, dom.isEditable);\n      styleInfo.range = rng;\n\n      return styleInfo;\n    };\n  };\n\n\n  /**\n   * @class editing.Bullet\n   *\n   * @alternateClassName Bullet\n   */\n  var Bullet = function () {\n    /**\n     * @method insertOrderedList\n     *\n     * toggle ordered list\n     *\n     * @type command\n     */\n    this.insertOrderedList = function () {\n      this.toggleList('OL');\n    };\n\n    /**\n     * @method insertUnorderedList\n     *\n     * toggle unordered list\n     *\n     * @type command\n     */\n    this.insertUnorderedList = function () {\n      this.toggleList('UL');\n    };\n\n    /**\n     * @method indent\n     *\n     * indent\n     *\n     * @type command\n     */\n    this.indent = function () {\n      var self = this;\n      var rng = range.create().wrapBodyInlineWithPara();\n\n      var paras = rng.nodes(dom.isPara, { includeAncestor: true });\n      var clustereds = list.clusterBy(paras, func.peq2('parentNode'));\n\n      $.each(clustereds, function (idx, paras) {\n        var head = list.head(paras);\n        if (dom.isLi(head)) {\n          self.wrapList(paras, head.parentNode.nodeName);\n        } else {\n          $.each(paras, function (idx, para) {\n            $(para).css('marginLeft', function (idx, val) {\n              return (parseInt(val, 10) || 0) + 25;\n            });\n          });\n        }\n      });\n\n      rng.select();\n    };\n\n    /**\n     * @method outdent\n     *\n     * outdent\n     *\n     * @type command\n     */\n    this.outdent = function () {\n      var self = this;\n      var rng = range.create().wrapBodyInlineWithPara();\n\n      var paras = rng.nodes(dom.isPara, { includeAncestor: true });\n      var clustereds = list.clusterBy(paras, func.peq2('parentNode'));\n\n      $.each(clustereds, function (idx, paras) {\n        var head = list.head(paras);\n        if (dom.isLi(head)) {\n          self.releaseList([paras]);\n        } else {\n          $.each(paras, function (idx, para) {\n            $(para).css('marginLeft', function (idx, val) {\n              val = (parseInt(val, 10) || 0);\n              return val > 25 ? val - 25 : '';\n            });\n          });\n        }\n      });\n\n      rng.select();\n    };\n\n    /**\n     * @method toggleList\n     *\n     * toggle list\n     *\n     * @param {String} listName - OL or UL\n     */\n    this.toggleList = function (listName) {\n      var self = this;\n      var rng = range.create().wrapBodyInlineWithPara();\n\n      var paras = rng.nodes(dom.isPara, { includeAncestor: true });\n      var bookmark = rng.paraBookmark(paras);\n      var clustereds = list.clusterBy(paras, func.peq2('parentNode'));\n\n      // paragraph to list\n      if (list.find(paras, dom.isPurePara)) {\n        var wrappedParas = [];\n        $.each(clustereds, function (idx, paras) {\n          wrappedParas = wrappedParas.concat(self.wrapList(paras, listName));\n        });\n        paras = wrappedParas;\n      // list to paragraph or change list style\n      } else {\n        var diffLists = rng.nodes(dom.isList, {\n          includeAncestor: true\n        }).filter(function (listNode) {\n          return !$.nodeName(listNode, listName);\n        });\n\n        if (diffLists.length) {\n          $.each(diffLists, function (idx, listNode) {\n            dom.replace(listNode, listName);\n          });\n        } else {\n          paras = this.releaseList(clustereds, true);\n        }\n      }\n\n      range.createFromParaBookmark(bookmark, paras).select();\n    };\n\n    /**\n     * @method wrapList\n     *\n     * @param {Node[]} paras\n     * @param {String} listName\n     * @return {Node[]}\n     */\n    this.wrapList = function (paras, listName) {\n      var head = list.head(paras);\n      var last = list.last(paras);\n\n      var prevList = dom.isList(head.previousSibling) && head.previousSibling;\n      var nextList = dom.isList(last.nextSibling) && last.nextSibling;\n\n      var listNode = prevList || dom.insertAfter(dom.create(listName || 'UL'), last);\n\n      // P to LI\n      paras = paras.map(function (para) {\n        return dom.isPurePara(para) ? dom.replace(para, 'LI') : para;\n      });\n\n      // append to list(<ul>, <ol>)\n      dom.appendChildNodes(listNode, paras);\n\n      if (nextList) {\n        dom.appendChildNodes(listNode, list.from(nextList.childNodes));\n        dom.remove(nextList);\n      }\n\n      return paras;\n    };\n\n    /**\n     * @method releaseList\n     *\n     * @param {Array[]} clustereds\n     * @param {Boolean} isEscapseToBody\n     * @return {Node[]}\n     */\n    this.releaseList = function (clustereds, isEscapseToBody) {\n      var releasedParas = [];\n\n      $.each(clustereds, function (idx, paras) {\n        var head = list.head(paras);\n        var last = list.last(paras);\n\n        var headList = isEscapseToBody ? dom.lastAncestor(head, dom.isList) :\n                                         head.parentNode;\n        var lastList = headList.childNodes.length > 1 ? dom.splitTree(headList, {\n          node: last.parentNode,\n          offset: dom.position(last) + 1\n        }, {\n          isSkipPaddingBlankHTML: true\n        }) : null;\n\n        var middleList = dom.splitTree(headList, {\n          node: head.parentNode,\n          offset: dom.position(head)\n        }, {\n          isSkipPaddingBlankHTML: true\n        });\n\n        paras = isEscapseToBody ? dom.listDescendant(middleList, dom.isLi) :\n                                  list.from(middleList.childNodes).filter(dom.isLi);\n\n        // LI to P\n        if (isEscapseToBody || !dom.isList(headList.parentNode)) {\n          paras = paras.map(function (para) {\n            return dom.replace(para, 'P');\n          });\n        }\n\n        $.each(list.from(paras).reverse(), function (idx, para) {\n          dom.insertAfter(para, headList);\n        });\n\n        // remove empty lists\n        var rootLists = list.compact([headList, middleList, lastList]);\n        $.each(rootLists, function (idx, rootList) {\n          var listNodes = [rootList].concat(dom.listDescendant(rootList, dom.isList));\n          $.each(listNodes.reverse(), function (idx, listNode) {\n            if (!dom.nodeLength(listNode)) {\n              dom.remove(listNode, true);\n            }\n          });\n        });\n\n        releasedParas = releasedParas.concat(paras);\n      });\n\n      return releasedParas;\n    };\n  };\n\n\n  /**\n   * @class editing.Typing\n   *\n   * Typing\n   *\n   */\n  var Typing = function () {\n\n    // a Bullet instance to toggle lists off\n    var bullet = new Bullet();\n\n    /**\n     * insert tab\n     *\n     * @param {jQuery} $editable\n     * @param {WrappedRange} rng\n     * @param {Number} tabsize\n     */\n    this.insertTab = function ($editable, rng, tabsize) {\n      var tab = dom.createText(new Array(tabsize + 1).join(dom.NBSP_CHAR));\n      rng = rng.deleteContents();\n      rng.insertNode(tab, true);\n\n      rng = range.create(tab, tabsize);\n      rng.select();\n    };\n\n    /**\n     * insert paragraph\n     */\n    this.insertParagraph = function () {\n      var rng = range.create();\n\n      // deleteContents on range.\n      rng = rng.deleteContents();\n\n      // Wrap range if it needs to be wrapped by paragraph\n      rng = rng.wrapBodyInlineWithPara();\n\n      // finding paragraph\n      var splitRoot = dom.ancestor(rng.sc, dom.isPara);\n\n      var nextPara;\n      // on paragraph: split paragraph\n      if (splitRoot) {\n        // if it is an empty line with li\n        if (dom.isEmpty(splitRoot) && dom.isLi(splitRoot)) {\n          // disable UL/OL and escape!\n          bullet.toggleList(splitRoot.parentNode.nodeName);\n          return;\n        // if new line has content (not a line break)\n        } else {\n          nextPara = dom.splitTree(splitRoot, rng.getStartPoint());\n\n          var emptyAnchors = dom.listDescendant(splitRoot, dom.isEmptyAnchor);\n          emptyAnchors = emptyAnchors.concat(dom.listDescendant(nextPara, dom.isEmptyAnchor));\n\n          $.each(emptyAnchors, function (idx, anchor) {\n            dom.remove(anchor);\n          });\n        }\n      // no paragraph: insert empty paragraph\n      } else {\n        var next = rng.sc.childNodes[rng.so];\n        nextPara = $(dom.emptyPara)[0];\n        if (next) {\n          rng.sc.insertBefore(nextPara, next);\n        } else {\n          rng.sc.appendChild(nextPara);\n        }\n      }\n\n      range.create(nextPara, 0).normalize().select();\n\n    };\n\n  };\n\n  /**\n   * @class editing.Table\n   *\n   * Table\n   *\n   */\n  var Table = function () {\n    /**\n     * handle tab key\n     *\n     * @param {WrappedRange} rng\n     * @param {Boolean} isShift\n     */\n    this.tab = function (rng, isShift) {\n      var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);\n      var table = dom.ancestor(cell, dom.isTable);\n      var cells = dom.listDescendant(table, dom.isCell);\n\n      var nextCell = list[isShift ? 'prev' : 'next'](cells, cell);\n      if (nextCell) {\n        range.create(nextCell, 0).select();\n      }\n    };\n\n    /**\n     * create empty table element\n     *\n     * @param {Number} rowCount\n     * @param {Number} colCount\n     * @return {Node}\n     */\n    this.createTable = function (colCount, rowCount) {\n      var tds = [], tdHTML;\n      for (var idxCol = 0; idxCol < colCount; idxCol++) {\n        tds.push('<td>' + dom.blank + '</td>');\n      }\n      tdHTML = tds.join('');\n\n      var trs = [], trHTML;\n      for (var idxRow = 0; idxRow < rowCount; idxRow++) {\n        trs.push('<tr>' + tdHTML + '</tr>');\n      }\n      trHTML = trs.join('');\n      return $('<table class=\"table table-bordered\">' + trHTML + '</table>')[0];\n    };\n  };\n\n\n  var KEY_BOGUS = 'bogus';\n\n  /**\n   * @class editing.Editor\n   *\n   * Editor\n   *\n   */\n  var Editor = function (handler) {\n\n    var self = this;\n    var style = new Style();\n    var table = new Table();\n    var typing = new Typing();\n    var bullet = new Bullet();\n\n    /**\n     * @method createRange\n     *\n     * create range\n     *\n     * @param {jQuery} $editable\n     * @return {WrappedRange}\n     */\n    this.createRange = function ($editable) {\n      this.focus($editable);\n      return range.create();\n    };\n\n    /**\n     * @method saveRange\n     *\n     * save current range\n     *\n     * @param {jQuery} $editable\n     * @param {Boolean} [thenCollapse=false]\n     */\n    this.saveRange = function ($editable, thenCollapse) {\n      this.focus($editable);\n      $editable.data('range', range.create());\n      if (thenCollapse) {\n        range.create().collapse().select();\n      }\n    };\n\n    /**\n     * @method saveRange\n     *\n     * save current node list to $editable.data('childNodes')\n     *\n     * @param {jQuery} $editable\n     */\n    this.saveNode = function ($editable) {\n      // copy child node reference\n      var copy = [];\n      for (var key  = 0, len = $editable[0].childNodes.length; key < len; key++) {\n        copy.push($editable[0].childNodes[key]);\n      }\n      $editable.data('childNodes', copy);\n    };\n\n    /**\n     * @method restoreRange\n     *\n     * restore lately range\n     *\n     * @param {jQuery} $editable\n     */\n    this.restoreRange = function ($editable) {\n      var rng = $editable.data('range');\n      if (rng) {\n        rng.select();\n        this.focus($editable);\n      }\n    };\n\n    /**\n     * @method restoreNode\n     *\n     * restore lately node list\n     *\n     * @param {jQuery} $editable\n     */\n    this.restoreNode = function ($editable) {\n      $editable.html('');\n      var child = $editable.data('childNodes');\n      for (var index = 0, len = child.length; index < len; index++) {\n        $editable[0].appendChild(child[index]);\n      }\n    };\n\n    /**\n     * @method currentStyle\n     *\n     * current style\n     *\n     * @param {Node} target\n     * @return {Object|Boolean} unfocus\n     */\n    this.currentStyle = function (target) {\n      var rng = range.create();\n      var styleInfo =  rng && rng.isOnEditable() ? style.current(rng.normalize()) : {};\n      if (dom.isImg(target)) {\n        styleInfo.image = target;\n      }\n      return styleInfo;\n    };\n\n    /**\n     * style from node\n     *\n     * @param {jQuery} $node\n     * @return {Object}\n     */\n    this.styleFromNode = function ($node) {\n      return style.fromNode($node);\n    };\n\n    var triggerOnBeforeChange = function ($editable) {\n      var $holder = dom.makeLayoutInfo($editable).holder();\n      handler.bindCustomEvent(\n        $holder, $editable.data('callbacks'), 'before.command'\n      )($editable.html(), $editable);\n    };\n\n    var triggerOnChange = function ($editable) {\n      var $holder = dom.makeLayoutInfo($editable).holder();\n      handler.bindCustomEvent(\n        $holder, $editable.data('callbacks'), 'change'\n      )($editable.html(), $editable);\n    };\n\n    /**\n     * @method undo\n     * undo\n     * @param {jQuery} $editable\n     */\n    this.undo = function ($editable) {\n      triggerOnBeforeChange($editable);\n      $editable.data('NoteHistory').undo();\n      triggerOnChange($editable);\n    };\n\n    /**\n     * @method redo\n     * redo\n     * @param {jQuery} $editable\n     */\n    this.redo = function ($editable) {\n      triggerOnBeforeChange($editable);\n      $editable.data('NoteHistory').redo();\n      triggerOnChange($editable);\n    };\n\n    /**\n     * @method beforeCommand\n     * before command\n     * @param {jQuery} $editable\n     */\n    var beforeCommand = this.beforeCommand = function ($editable) {\n      triggerOnBeforeChange($editable);\n      // keep focus on editable before command execution\n      self.focus($editable);\n    };\n\n    /**\n     * @method afterCommand\n     * after command\n     * @param {jQuery} $editable\n     * @param {Boolean} isPreventTrigger\n     */\n    var afterCommand = this.afterCommand = function ($editable, isPreventTrigger) {\n      $editable.data('NoteHistory').recordUndo();\n      if (!isPreventTrigger) {\n        triggerOnChange($editable);\n      }\n    };\n\n    /**\n     * @method bold\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method italic\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method underline\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method strikethrough\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method formatBlock\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method superscript\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method subscript\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method justifyLeft\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method justifyCenter\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method justifyRight\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method justifyFull\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method formatBlock\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method removeFormat\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method backColor\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method foreColor\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method insertHorizontalRule\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method fontName\n     *\n     * change font name\n     *\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /* jshint ignore:start */\n    // native commands(with execCommand), generate function for execCommand\n    var commands = ['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript',\n                    'justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull',\n                    'formatBlock', 'removeFormat',\n                    'backColor', 'foreColor', 'fontName'];\n\n    for (var idx = 0, len = commands.length; idx < len; idx ++) {\n      this[commands[idx]] = (function (sCmd) {\n        return function ($editable, value) {\n          beforeCommand($editable);\n\n          document.execCommand(sCmd, false, value);\n\n          afterCommand($editable, true);\n        };\n      })(commands[idx]);\n    }\n    /* jshint ignore:end */\n\n    /**\n     * @method tab\n     *\n     * handle tab key\n     *\n     * @param {jQuery} $editable\n     * @param {Object} options\n     */\n    this.tab = function ($editable, options) {\n      var rng = this.createRange($editable);\n      if (rng.isCollapsed() && rng.isOnCell()) {\n        table.tab(rng);\n      } else {\n        beforeCommand($editable);\n        typing.insertTab($editable, rng, options.tabsize);\n        afterCommand($editable);\n      }\n    };\n\n    /**\n     * @method untab\n     *\n     * handle shift+tab key\n     *\n     */\n    this.untab = function ($editable) {\n      var rng = this.createRange($editable);\n      if (rng.isCollapsed() && rng.isOnCell()) {\n        table.tab(rng, true);\n      }\n    };\n\n    /**\n     * @method insertParagraph\n     *\n     * insert paragraph\n     *\n     * @param {Node} $editable\n     */\n    this.insertParagraph = function ($editable) {\n      beforeCommand($editable);\n      typing.insertParagraph($editable);\n      afterCommand($editable);\n    };\n\n    /**\n     * @method insertOrderedList\n     *\n     * @param {jQuery} $editable\n     */\n    this.insertOrderedList = function ($editable) {\n      beforeCommand($editable);\n      bullet.insertOrderedList($editable);\n      afterCommand($editable);\n    };\n\n    /**\n     * @param {jQuery} $editable\n     */\n    this.insertUnorderedList = function ($editable) {\n      beforeCommand($editable);\n      bullet.insertUnorderedList($editable);\n      afterCommand($editable);\n    };\n\n    /**\n     * @param {jQuery} $editable\n     */\n    this.indent = function ($editable) {\n      beforeCommand($editable);\n      bullet.indent($editable);\n      afterCommand($editable);\n    };\n\n    /**\n     * @param {jQuery} $editable\n     */\n    this.outdent = function ($editable) {\n      beforeCommand($editable);\n      bullet.outdent($editable);\n      afterCommand($editable);\n    };\n\n    /**\n     * insert image\n     *\n     * @param {jQuery} $editable\n     * @param {String} sUrl\n     */\n    this.insertImage = function ($editable, sUrl, filename) {\n      async.createImage(sUrl, filename).then(function ($image) {\n        beforeCommand($editable);\n        $image.css({\n          display: '',\n          width: Math.min($editable.width(), $image.width())\n        });\n        range.create().insertNode($image[0]);\n        range.createFromNodeAfter($image[0]).select();\n        afterCommand($editable);\n      }).fail(function () {\n        var $holder = dom.makeLayoutInfo($editable).holder();\n        handler.bindCustomEvent(\n          $holder, $editable.data('callbacks'), 'image.upload.error'\n        )();\n      });\n    };\n\n    /**\n     * @method insertNode\n     * insert node\n     * @param {Node} $editable\n     * @param {Node} node\n     */\n    this.insertNode = function ($editable, node) {\n      beforeCommand($editable);\n      range.create().insertNode(node);\n      range.createFromNodeAfter(node).select();\n      afterCommand($editable);\n    };\n\n    /**\n     * insert text\n     * @param {Node} $editable\n     * @param {String} text\n     */\n    this.insertText = function ($editable, text) {\n      beforeCommand($editable);\n      var textNode = range.create().insertNode(dom.createText(text));\n      range.create(textNode, dom.nodeLength(textNode)).select();\n      afterCommand($editable);\n    };\n\n    /**\n     * paste HTML\n     * @param {Node} $editable\n     * @param {String} markup\n     */\n    this.pasteHTML = function ($editable, markup) {\n      beforeCommand($editable);\n      var contents = range.create().pasteHTML(markup);\n      range.createFromNodeAfter(list.last(contents)).select();\n      afterCommand($editable);\n    };\n\n    /**\n     * formatBlock\n     *\n     * @param {jQuery} $editable\n     * @param {String} tagName\n     */\n    this.formatBlock = function ($editable, tagName) {\n      beforeCommand($editable);\n      // [workaround] for MSIE, IE need `<`\n      tagName = agent.isMSIE ? '<' + tagName + '>' : tagName;\n      document.execCommand('FormatBlock', false, tagName);\n      afterCommand($editable);\n    };\n\n    this.formatPara = function ($editable) {\n      beforeCommand($editable);\n      this.formatBlock($editable, 'P');\n      afterCommand($editable);\n    };\n\n    /* jshint ignore:start */\n    for (var idx = 1; idx <= 6; idx ++) {\n      this['formatH' + idx] = function (idx) {\n        return function ($editable) {\n          this.formatBlock($editable, 'H' + idx);\n        };\n      }(idx);\n    };\n    /* jshint ignore:end */\n\n    /**\n     * fontSize\n     *\n     * @param {jQuery} $editable\n     * @param {String} value - px\n     */\n    this.fontSize = function ($editable, value) {\n      var rng = range.create();\n\n      if (rng.isCollapsed()) {\n        var spans = style.styleNodes(rng);\n        var firstSpan = list.head(spans);\n\n        $(spans).css({\n          'font-size': value + 'px'\n        });\n\n        // [workaround] added styled bogus span for style\n        //  - also bogus character needed for cursor position\n        if (firstSpan && !dom.nodeLength(firstSpan)) {\n          firstSpan.innerHTML = dom.ZERO_WIDTH_NBSP_CHAR;\n          range.createFromNodeAfter(firstSpan.firstChild).select();\n          $editable.data(KEY_BOGUS, firstSpan);\n        }\n      } else {\n        beforeCommand($editable);\n        $(style.styleNodes(rng)).css({\n          'font-size': value + 'px'\n        });\n        afterCommand($editable);\n      }\n    };\n\n    /**\n     * insert horizontal rule\n     * @param {jQuery} $editable\n     */\n    this.insertHorizontalRule = function ($editable) {\n      beforeCommand($editable);\n\n      var rng = range.create();\n      var hrNode = rng.insertNode($('<HR/>')[0]);\n      if (hrNode.nextSibling) {\n        range.create(hrNode.nextSibling, 0).normalize().select();\n      }\n\n      afterCommand($editable);\n    };\n\n    /**\n     * remove bogus node and character\n     */\n    this.removeBogus = function ($editable) {\n      var bogusNode = $editable.data(KEY_BOGUS);\n      if (!bogusNode) {\n        return;\n      }\n\n      var textNode = list.find(list.from(bogusNode.childNodes), dom.isText);\n\n      var bogusCharIdx = textNode.nodeValue.indexOf(dom.ZERO_WIDTH_NBSP_CHAR);\n      if (bogusCharIdx !== -1) {\n        textNode.deleteData(bogusCharIdx, 1);\n      }\n\n      if (dom.isEmpty(bogusNode)) {\n        dom.remove(bogusNode);\n      }\n\n      $editable.removeData(KEY_BOGUS);\n    };\n\n    /**\n     * lineHeight\n     * @param {jQuery} $editable\n     * @param {String} value\n     */\n    this.lineHeight = function ($editable, value) {\n      beforeCommand($editable);\n      style.stylePara(range.create(), {\n        lineHeight: value\n      });\n      afterCommand($editable);\n    };\n\n    /**\n     * unlink\n     *\n     * @type command\n     *\n     * @param {jQuery} $editable\n     */\n    this.unlink = function ($editable) {\n      var rng = this.createRange($editable);\n      if (rng.isOnAnchor()) {\n        var anchor = dom.ancestor(rng.sc, dom.isAnchor);\n        rng = range.createFromNode(anchor);\n        rng.select();\n\n        beforeCommand($editable);\n        document.execCommand('unlink');\n        afterCommand($editable);\n      }\n    };\n\n    /**\n     * create link (command)\n     *\n     * @param {jQuery} $editable\n     * @param {Object} linkInfo\n     * @param {Object} options\n     */\n    this.createLink = function ($editable, linkInfo, options) {\n      var linkUrl = linkInfo.url;\n      var linkText = linkInfo.text;\n      var isNewWindow = linkInfo.isNewWindow;\n      var rng = linkInfo.range || this.createRange($editable);\n      var isTextChanged = rng.toString() !== linkText;\n\n      options = options || dom.makeLayoutInfo($editable).editor().data('options');\n\n      beforeCommand($editable);\n\n      if (options.onCreateLink) {\n        linkUrl = options.onCreateLink(linkUrl);\n      }\n\n      var anchors = [];\n      if (isTextChanged) {\n        // Create a new link when text changed.\n        var anchor = rng.insertNode($('<A>' + linkText + '</A>')[0]);\n        anchors.push(anchor);\n      } else {\n        anchors = style.styleNodes(rng, {\n          nodeName: 'A',\n          expandClosestSibling: true,\n          onlyPartialContains: true\n        });\n      }\n\n      $.each(anchors, function (idx, anchor) {\n        $(anchor).attr('href', linkUrl);\n        if (isNewWindow) {\n          $(anchor).attr('target', '_blank');\n        } else {\n          $(anchor).removeAttr('target');\n        }\n      });\n\n      var startRange = range.createFromNodeBefore(list.head(anchors));\n      var startPoint = startRange.getStartPoint();\n      var endRange = range.createFromNodeAfter(list.last(anchors));\n      var endPoint = endRange.getEndPoint();\n\n      range.create(\n        startPoint.node,\n        startPoint.offset,\n        endPoint.node,\n        endPoint.offset\n      ).select();\n\n      afterCommand($editable);\n    };\n\n    /**\n     * returns link info\n     *\n     * @return {Object}\n     * @return {WrappedRange} return.range\n     * @return {String} return.text\n     * @return {Boolean} [return.isNewWindow=true]\n     * @return {String} [return.url=\"\"]\n     */\n    this.getLinkInfo = function ($editable) {\n      this.focus($editable);\n\n      var rng = range.create().expand(dom.isAnchor);\n\n      // Get the first anchor on range(for edit).\n      var $anchor = $(list.head(rng.nodes(dom.isAnchor)));\n\n      return {\n        range: rng,\n        text: rng.toString(),\n        isNewWindow: $anchor.length ? $anchor.attr('target') === '_blank' : false,\n        url: $anchor.length ? $anchor.attr('href') : ''\n      };\n    };\n\n    /**\n     * setting color\n     *\n     * @param {Node} $editable\n     * @param {Object} sObjColor  color code\n     * @param {String} sObjColor.foreColor foreground color\n     * @param {String} sObjColor.backColor background color\n     */\n    this.color = function ($editable, sObjColor) {\n      var oColor = JSON.parse(sObjColor);\n      var foreColor = oColor.foreColor, backColor = oColor.backColor;\n\n      beforeCommand($editable);\n\n      if (foreColor) { document.execCommand('foreColor', false, foreColor); }\n      if (backColor) { document.execCommand('backColor', false, backColor); }\n\n      afterCommand($editable);\n    };\n\n    /**\n     * insert Table\n     *\n     * @param {Node} $editable\n     * @param {String} sDim dimension of table (ex : \"5x5\")\n     */\n    this.insertTable = function ($editable, sDim) {\n      var dimension = sDim.split('x');\n      beforeCommand($editable);\n\n      var rng = range.create().deleteContents();\n      rng.insertNode(table.createTable(dimension[0], dimension[1]));\n      afterCommand($editable);\n    };\n\n    /**\n     * float me\n     *\n     * @param {jQuery} $editable\n     * @param {String} value\n     * @param {jQuery} $target\n     */\n    this.floatMe = function ($editable, value, $target) {\n      beforeCommand($editable);\n      // bootstrap\n      $target.removeClass('pull-left pull-right');\n      if (value && value !== 'none') {\n        $target.addClass('pull-' + value);\n      }\n\n      // fallback for non-bootstrap\n      $target.css('float', value);\n      afterCommand($editable);\n    };\n\n    /**\n     * change image shape\n     *\n     * @param {jQuery} $editable\n     * @param {String} value css class\n     * @param {Node} $target\n     */\n    this.imageShape = function ($editable, value, $target) {\n      beforeCommand($editable);\n\n      $target.removeClass('img-rounded img-circle img-thumbnail');\n\n      if (value) {\n        $target.addClass(value);\n      }\n\n      afterCommand($editable);\n    };\n\n    /**\n     * resize overlay element\n     * @param {jQuery} $editable\n     * @param {String} value\n     * @param {jQuery} $target - target element\n     */\n    this.resize = function ($editable, value, $target) {\n      beforeCommand($editable);\n\n      $target.css({\n        width: value * 100 + '%',\n        height: ''\n      });\n\n      afterCommand($editable);\n    };\n\n    /**\n     * @param {Position} pos\n     * @param {jQuery} $target - target element\n     * @param {Boolean} [bKeepRatio] - keep ratio\n     */\n    this.resizeTo = function (pos, $target, bKeepRatio) {\n      var imageSize;\n      if (bKeepRatio) {\n        var newRatio = pos.y / pos.x;\n        var ratio = $target.data('ratio');\n        imageSize = {\n          width: ratio > newRatio ? pos.x : pos.y / ratio,\n          height: ratio > newRatio ? pos.x * ratio : pos.y\n        };\n      } else {\n        imageSize = {\n          width: pos.x,\n          height: pos.y\n        };\n      }\n\n      $target.css(imageSize);\n    };\n\n    /**\n     * remove media object\n     *\n     * @param {jQuery} $editable\n     * @param {String} value - dummy argument (for keep interface)\n     * @param {jQuery} $target - target element\n     */\n    this.removeMedia = function ($editable, value, $target) {\n      beforeCommand($editable);\n      $target.detach();\n\n      handler.bindCustomEvent(\n        $(), $editable.data('callbacks'), 'media.delete'\n      )($target, $editable);\n\n      afterCommand($editable);\n    };\n\n    /**\n     * set focus\n     *\n     * @param $editable\n     */\n    this.focus = function ($editable) {\n      $editable.focus();\n\n      // [workaround] for firefox bug http://goo.gl/lVfAaI\n      if (agent.isFF && !range.create().isOnEditable()) {\n        range.createFromNode($editable[0])\n             .normalize()\n             .collapse()\n             .select();\n      }\n    };\n\n    /**\n     * returns whether contents is empty or not.\n     *\n     * @param {jQuery} $editable\n     * @return {Boolean}\n     */\n    this.isEmpty = function ($editable) {\n      return dom.isEmpty($editable[0]) || dom.emptyPara === $editable.html();\n    };\n  };\n\n  /**\n   * @class module.Button\n   *\n   * Button\n   */\n  var Button = function () {\n    /**\n     * update button status\n     *\n     * @param {jQuery} $container\n     * @param {Object} styleInfo\n     */\n    this.update = function ($container, styleInfo) {\n      /**\n       * handle dropdown's check mark (for fontname, fontsize, lineHeight).\n       * @param {jQuery} $btn\n       * @param {Number} value\n       */\n      var checkDropdownMenu = function ($btn, value) {\n        $btn.find('.dropdown-menu li a').each(function () {\n          // always compare string to avoid creating another func.\n          var isChecked = ($(this).data('value') + '') === (value + '');\n          this.className = isChecked ? 'checked' : '';\n        });\n      };\n\n      /**\n       * update button state(active or not).\n       *\n       * @private\n       * @param {String} selector\n       * @param {Function} pred\n       */\n      var btnState = function (selector, pred) {\n        var $btn = $container.find(selector);\n        $btn.toggleClass('active', pred());\n      };\n\n      if (styleInfo.image) {\n        var $img = $(styleInfo.image);\n\n        btnState('button[data-event=\"imageShape\"][data-value=\"img-rounded\"]', function () {\n          return $img.hasClass('img-rounded');\n        });\n        btnState('button[data-event=\"imageShape\"][data-value=\"img-circle\"]', function () {\n          return $img.hasClass('img-circle');\n        });\n        btnState('button[data-event=\"imageShape\"][data-value=\"img-thumbnail\"]', function () {\n          return $img.hasClass('img-thumbnail');\n        });\n        btnState('button[data-event=\"imageShape\"]:not([data-value])', function () {\n          return !$img.is('.img-rounded, .img-circle, .img-thumbnail');\n        });\n\n        var imgFloat = $img.css('float');\n        btnState('button[data-event=\"floatMe\"][data-value=\"left\"]', function () {\n          return imgFloat === 'left';\n        });\n        btnState('button[data-event=\"floatMe\"][data-value=\"right\"]', function () {\n          return imgFloat === 'right';\n        });\n        btnState('button[data-event=\"floatMe\"][data-value=\"none\"]', function () {\n          return imgFloat !== 'left' && imgFloat !== 'right';\n        });\n\n        var style = $img.attr('style');\n        btnState('button[data-event=\"resize\"][data-value=\"1\"]', function () {\n          return !!/(^|\\s)(max-)?width\\s*:\\s*100%/.test(style);\n        });\n        btnState('button[data-event=\"resize\"][data-value=\"0.5\"]', function () {\n          return !!/(^|\\s)(max-)?width\\s*:\\s*50%/.test(style);\n        });\n        btnState('button[data-event=\"resize\"][data-value=\"0.25\"]', function () {\n          return !!/(^|\\s)(max-)?width\\s*:\\s*25%/.test(style);\n        });\n        return;\n      }\n\n      // fontname\n      var $fontname = $container.find('.note-fontname');\n      if ($fontname.length) {\n        var selectedFont = styleInfo['font-family'];\n        if (!!selectedFont) {\n\n          var list = selectedFont.split(',');\n          for (var i = 0, len = list.length; i < len; i++) {\n            selectedFont = list[i].replace(/[\\'\\\"]/g, '').replace(/\\s+$/, '').replace(/^\\s+/, '');\n            if (agent.isFontInstalled(selectedFont)) {\n              break;\n            }\n          }\n          \n          $fontname.find('.note-current-fontname').text(selectedFont);\n          checkDropdownMenu($fontname, selectedFont);\n\n        }\n      }\n\n      // fontsize\n      var $fontsize = $container.find('.note-fontsize');\n      $fontsize.find('.note-current-fontsize').text(styleInfo['font-size']);\n      checkDropdownMenu($fontsize, parseFloat(styleInfo['font-size']));\n\n      // lineheight\n      var $lineHeight = $container.find('.note-height');\n      checkDropdownMenu($lineHeight, parseFloat(styleInfo['line-height']));\n\n      btnState('button[data-event=\"bold\"]', function () {\n        return styleInfo['font-bold'] === 'bold';\n      });\n      btnState('button[data-event=\"italic\"]', function () {\n        return styleInfo['font-italic'] === 'italic';\n      });\n      btnState('button[data-event=\"underline\"]', function () {\n        return styleInfo['font-underline'] === 'underline';\n      });\n      btnState('button[data-event=\"strikethrough\"]', function () {\n        return styleInfo['font-strikethrough'] === 'strikethrough';\n      });\n      btnState('button[data-event=\"superscript\"]', function () {\n        return styleInfo['font-superscript'] === 'superscript';\n      });\n      btnState('button[data-event=\"subscript\"]', function () {\n        return styleInfo['font-subscript'] === 'subscript';\n      });\n      btnState('button[data-event=\"justifyLeft\"]', function () {\n        return styleInfo['text-align'] === 'left' || styleInfo['text-align'] === 'start';\n      });\n      btnState('button[data-event=\"justifyCenter\"]', function () {\n        return styleInfo['text-align'] === 'center';\n      });\n      btnState('button[data-event=\"justifyRight\"]', function () {\n        return styleInfo['text-align'] === 'right';\n      });\n      btnState('button[data-event=\"justifyFull\"]', function () {\n        return styleInfo['text-align'] === 'justify';\n      });\n      btnState('button[data-event=\"insertUnorderedList\"]', function () {\n        return styleInfo['list-style'] === 'unordered';\n      });\n      btnState('button[data-event=\"insertOrderedList\"]', function () {\n        return styleInfo['list-style'] === 'ordered';\n      });\n    };\n\n    /**\n     * update recent color\n     *\n     * @param {Node} button\n     * @param {String} eventName\n     * @param {Mixed} value\n     */\n    this.updateRecentColor = function (button, eventName, value) {\n      var $color = $(button).closest('.note-color');\n      var $recentColor = $color.find('.note-recent-color');\n      var colorInfo = JSON.parse($recentColor.attr('data-value'));\n      colorInfo[eventName] = value;\n      $recentColor.attr('data-value', JSON.stringify(colorInfo));\n      var sKey = eventName === 'backColor' ? 'background-color' : 'color';\n      $recentColor.find('i').css(sKey, value);\n    };\n  };\n\n  /**\n   * @class module.Toolbar\n   *\n   * Toolbar\n   */\n  var Toolbar = function () {\n    var button = new Button();\n\n    this.update = function ($toolbar, styleInfo) {\n      button.update($toolbar, styleInfo);\n    };\n\n    /**\n     * @param {Node} button\n     * @param {String} eventName\n     * @param {String} value\n     */\n    this.updateRecentColor = function (buttonNode, eventName, value) {\n      button.updateRecentColor(buttonNode, eventName, value);\n    };\n\n    /**\n     * activate buttons exclude codeview\n     * @param {jQuery} $toolbar\n     */\n    this.activate = function ($toolbar) {\n      $toolbar.find('button')\n              .not('button[data-event=\"codeview\"]')\n              .removeClass('disabled');\n    };\n\n    /**\n     * deactivate buttons exclude codeview\n     * @param {jQuery} $toolbar\n     */\n    this.deactivate = function ($toolbar) {\n      $toolbar.find('button')\n              .not('button[data-event=\"codeview\"]')\n              .addClass('disabled');\n    };\n\n    /**\n     * @param {jQuery} $container\n     * @param {Boolean} [bFullscreen=false]\n     */\n    this.updateFullscreen = function ($container, bFullscreen) {\n      var $btn = $container.find('button[data-event=\"fullscreen\"]');\n      $btn.toggleClass('active', bFullscreen);\n    };\n\n    /**\n     * @param {jQuery} $container\n     * @param {Boolean} [isCodeview=false]\n     */\n    this.updateCodeview = function ($container, isCodeview) {\n      var $btn = $container.find('button[data-event=\"codeview\"]');\n      $btn.toggleClass('active', isCodeview);\n\n      if (isCodeview) {\n        this.deactivate($container);\n      } else {\n        this.activate($container);\n      }\n    };\n\n    /**\n     * get button in toolbar \n     *\n     * @param {jQuery} $editable\n     * @param {String} name\n     * @return {jQuery}\n     */\n    this.get = function ($editable, name) {\n      var $toolbar = dom.makeLayoutInfo($editable).toolbar();\n\n      return $toolbar.find('[data-name=' + name + ']');\n    };\n\n    /**\n     * set button state\n     * @param {jQuery} $editable\n     * @param {String} name\n     * @param {Boolean} [isActive=true]\n     */\n    this.setButtonState = function ($editable, name, isActive) {\n      isActive = (isActive === false) ? false : true;\n\n      var $button = this.get($editable, name);\n      $button.toggleClass('active', isActive);\n    };\n  };\n\n  var EDITABLE_PADDING = 24;\n\n  var Statusbar = function () {\n    var $document = $(document);\n\n    this.attach = function (layoutInfo, options) {\n      if (!options.disableResizeEditor) {\n        layoutInfo.statusbar().on('mousedown', hStatusbarMousedown);\n      }\n    };\n\n    /**\n     * `mousedown` event handler on statusbar\n     *\n     * @param {MouseEvent} event\n     */\n    var hStatusbarMousedown = function (event) {\n      event.preventDefault();\n      event.stopPropagation();\n\n      var $editable = dom.makeLayoutInfo(event.target).editable();\n      var editableTop = $editable.offset().top - $document.scrollTop();\n\n      var layoutInfo = dom.makeLayoutInfo(event.currentTarget || event.target);\n      var options = layoutInfo.editor().data('options');\n\n      $document.on('mousemove', function (event) {\n        var nHeight = event.clientY - (editableTop + EDITABLE_PADDING);\n\n        nHeight = (options.minHeight > 0) ? Math.max(nHeight, options.minHeight) : nHeight;\n        nHeight = (options.maxHeight > 0) ? Math.min(nHeight, options.maxHeight) : nHeight;\n\n        $editable.height(nHeight);\n      }).one('mouseup', function () {\n        $document.off('mousemove');\n      });\n    };\n  };\n\n  /**\n   * @class module.Popover\n   *\n   * Popover (http://getbootstrap.com/javascript/#popovers)\n   *\n   */\n  var Popover = function () {\n    var button = new Button();\n\n    /**\n     * returns position from placeholder\n     *\n     * @private\n     * @param {Node} placeholder\n     * @param {Object} options\n     * @param {Boolean} options.isAirMode\n     * @return {Position}\n     */\n    var posFromPlaceholder = function (placeholder, options) {\n      var isAirMode = options && options.isAirMode;\n      var isLeftTop = options && options.isLeftTop;\n\n      var $placeholder = $(placeholder);\n      var pos = isAirMode ? $placeholder.offset() : $placeholder.position();\n      var height = isLeftTop ? 0 : $placeholder.outerHeight(true); // include margin\n\n      // popover below placeholder.\n      return {\n        left: pos.left,\n        top: pos.top + height\n      };\n    };\n\n    /**\n     * show popover\n     *\n     * @private\n     * @param {jQuery} popover\n     * @param {Position} pos\n     */\n    var showPopover = function ($popover, pos) {\n      $popover.css({\n        display: 'block',\n        left: pos.left,\n        top: pos.top\n      });\n    };\n\n    var PX_POPOVER_ARROW_OFFSET_X = 20;\n\n    /**\n     * update current state\n     * @param {jQuery} $popover - popover container\n     * @param {Object} styleInfo - style object\n     * @param {Boolean} isAirMode\n     */\n    this.update = function ($popover, styleInfo, isAirMode) {\n      button.update($popover, styleInfo);\n\n      var $linkPopover = $popover.find('.note-link-popover');\n      if (styleInfo.anchor) {\n        var $anchor = $linkPopover.find('a');\n        var href = $(styleInfo.anchor).attr('href');\n        var target = $(styleInfo.anchor).attr('target');\n        $anchor.attr('href', href).html(href);\n        if (!target) {\n          $anchor.removeAttr('target');\n        } else {\n          $anchor.attr('target', '_blank');\n        }\n        showPopover($linkPopover, posFromPlaceholder(styleInfo.anchor, {\n          isAirMode: isAirMode\n        }));\n      } else {\n        $linkPopover.hide();\n      }\n\n      var $imagePopover = $popover.find('.note-image-popover');\n      if (styleInfo.image) {\n        showPopover($imagePopover, posFromPlaceholder(styleInfo.image, {\n          isAirMode: isAirMode,\n          isLeftTop: true\n        }));\n      } else {\n        $imagePopover.hide();\n      }\n\n      var $airPopover = $popover.find('.note-air-popover');\n      if (isAirMode && styleInfo.range && !styleInfo.range.isCollapsed()) {\n        var rect = list.last(styleInfo.range.getClientRects());\n        if (rect) {\n          var bnd = func.rect2bnd(rect);\n          showPopover($airPopover, {\n            left: Math.max(bnd.left + bnd.width / 2 - PX_POPOVER_ARROW_OFFSET_X, 0),\n            top: bnd.top + bnd.height\n          });\n        }\n      } else {\n        $airPopover.hide();\n      }\n    };\n\n    /**\n     * @param {Node} button\n     * @param {String} eventName\n     * @param {String} value\n     */\n    this.updateRecentColor = function (button, eventName, value) {\n      button.updateRecentColor(button, eventName, value);\n    };\n\n    /**\n     * hide all popovers\n     * @param {jQuery} $popover - popover container\n     */\n    this.hide = function ($popover) {\n      $popover.children().hide();\n    };\n  };\n\n  /**\n   * @class module.Handle\n   *\n   * Handle\n   */\n  var Handle = function (handler) {\n    var $document = $(document);\n\n    /**\n     * `mousedown` event handler on $handle\n     *  - controlSizing: resize image\n     *\n     * @param {MouseEvent} event\n     */\n    var hHandleMousedown = function (event) {\n      if (dom.isControlSizing(event.target)) {\n        event.preventDefault();\n        event.stopPropagation();\n\n        var layoutInfo = dom.makeLayoutInfo(event.target),\n            $handle = layoutInfo.handle(),\n            $popover = layoutInfo.popover(),\n            $editable = layoutInfo.editable(),\n            $editor = layoutInfo.editor();\n\n        var target = $handle.find('.note-control-selection').data('target'),\n            $target = $(target), posStart = $target.offset(),\n            scrollTop = $document.scrollTop();\n\n        var isAirMode = $editor.data('options').airMode;\n\n        $document.on('mousemove', function (event) {\n          handler.invoke('editor.resizeTo', {\n            x: event.clientX - posStart.left,\n            y: event.clientY - (posStart.top - scrollTop)\n          }, $target, !event.shiftKey);\n\n          handler.invoke('handle.update', $handle, {image: target}, isAirMode);\n          handler.invoke('popover.update', $popover, {image: target}, isAirMode);\n        }).one('mouseup', function () {\n          $document.off('mousemove');\n          handler.invoke('editor.afterCommand', $editable);\n        });\n\n        if (!$target.data('ratio')) { // original ratio.\n          $target.data('ratio', $target.height() / $target.width());\n        }\n      }\n    };\n\n    this.attach = function (layoutInfo) {\n      layoutInfo.handle().on('mousedown', hHandleMousedown);\n    };\n\n    /**\n     * update handle\n     * @param {jQuery} $handle\n     * @param {Object} styleInfo\n     * @param {Boolean} isAirMode\n     */\n    this.update = function ($handle, styleInfo, isAirMode) {\n      var $selection = $handle.find('.note-control-selection');\n      if (styleInfo.image) {\n        var $image = $(styleInfo.image);\n        var pos = isAirMode ? $image.offset() : $image.position();\n\n        // include margin\n        var imageSize = {\n          w: $image.outerWidth(true),\n          h: $image.outerHeight(true)\n        };\n\n        $selection.css({\n          display: 'block',\n          left: pos.left,\n          top: pos.top,\n          width: imageSize.w,\n          height: imageSize.h\n        }).data('target', styleInfo.image); // save current image element.\n        var sizingText = imageSize.w + 'x' + imageSize.h;\n        $selection.find('.note-control-selection-info').text(sizingText);\n      } else {\n        $selection.hide();\n      }\n    };\n\n    /**\n     * hide\n     *\n     * @param {jQuery} $handle\n     */\n    this.hide = function ($handle) {\n      $handle.children().hide();\n    };\n  };\n\n  var Fullscreen = function (handler) {\n    var $window = $(window);\n    var $scrollbar = $('html, body');\n\n    /**\n     * toggle fullscreen\n     *\n     * @param {Object} layoutInfo\n     */\n    this.toggle = function (layoutInfo) {\n\n      var $editor = layoutInfo.editor(),\n          $toolbar = layoutInfo.toolbar(),\n          $editable = layoutInfo.editable(),\n          $codable = layoutInfo.codable();\n\n      var resize = function (size) {\n        $editable.css('height', size.h);\n        $codable.css('height', size.h);\n        if ($codable.data('cmeditor')) {\n          $codable.data('cmeditor').setsize(null, size.h);\n        }\n      };\n\n      $editor.toggleClass('fullscreen');\n      var isFullscreen = $editor.hasClass('fullscreen');\n      if (isFullscreen) {\n        $editable.data('orgheight', $editable.css('height'));\n\n        $window.on('resize', function () {\n          resize({\n            h: $window.height() - $toolbar.outerHeight()\n          });\n        }).trigger('resize');\n\n        $scrollbar.css('overflow', 'hidden');\n      } else {\n        $window.off('resize');\n        resize({\n          h: $editable.data('orgheight')\n        });\n        $scrollbar.css('overflow', 'visible');\n      }\n\n      handler.invoke('toolbar.updateFullscreen', $toolbar, isFullscreen);\n    };\n  };\n\n\n  var CodeMirror;\n  if (agent.hasCodeMirror) {\n    if (agent.isSupportAmd) {\n      require(['CodeMirror'], function (cm) {\n        CodeMirror = cm;\n      });\n    } else {\n      CodeMirror = window.CodeMirror;\n    }\n  }\n\n  /**\n   * @class Codeview\n   */\n  var Codeview = function (handler) {\n\n    this.sync = function (layoutInfo) {\n      var isCodeview = handler.invoke('codeview.isActivated', layoutInfo);\n      if (isCodeview && agent.hasCodeMirror) {\n        layoutInfo.codable().data('cmEditor').save();\n      }\n    };\n\n    /**\n     * @param {Object} layoutInfo\n     * @return {Boolean}\n     */\n    this.isActivated = function (layoutInfo) {\n      var $editor = layoutInfo.editor();\n      return $editor.hasClass('codeview');\n    };\n\n    /**\n     * toggle codeview\n     *\n     * @param {Object} layoutInfo\n     */\n    this.toggle = function (layoutInfo) {\n      if (this.isActivated(layoutInfo)) {\n        this.deactivate(layoutInfo);\n      } else {\n        this.activate(layoutInfo);\n      }\n    };\n\n    /**\n     * activate code view\n     *\n     * @param {Object} layoutInfo\n     */\n    this.activate = function (layoutInfo) {\n      var $editor = layoutInfo.editor(),\n          $toolbar = layoutInfo.toolbar(),\n          $editable = layoutInfo.editable(),\n          $codable = layoutInfo.codable(),\n          $popover = layoutInfo.popover(),\n          $handle = layoutInfo.handle();\n\n      var options = $editor.data('options');\n\n      $codable.val(dom.html($editable, options.prettifyHtml));\n      $codable.height($editable.height());\n\n      handler.invoke('toolbar.updateCodeview', $toolbar, true);\n      handler.invoke('popover.hide', $popover);\n      handler.invoke('handle.hide', $handle);\n\n      $editor.addClass('codeview');\n\n      $codable.focus();\n\n      // activate CodeMirror as codable\n      if (agent.hasCodeMirror) {\n        var cmEditor = CodeMirror.fromTextArea($codable[0], options.codemirror);\n\n        // CodeMirror TernServer\n        if (options.codemirror.tern) {\n          var server = new CodeMirror.TernServer(options.codemirror.tern);\n          cmEditor.ternServer = server;\n          cmEditor.on('cursorActivity', function (cm) {\n            server.updateArgHints(cm);\n          });\n        }\n\n        // CodeMirror hasn't Padding.\n        cmEditor.setSize(null, $editable.outerHeight());\n        $codable.data('cmEditor', cmEditor);\n      }\n    };\n\n    /**\n     * deactivate code view\n     *\n     * @param {Object} layoutInfo\n     */\n    this.deactivate = function (layoutInfo) {\n      var $holder = layoutInfo.holder(),\n          $editor = layoutInfo.editor(),\n          $toolbar = layoutInfo.toolbar(),\n          $editable = layoutInfo.editable(),\n          $codable = layoutInfo.codable();\n\n      var options = $editor.data('options');\n\n      // deactivate CodeMirror as codable\n      if (agent.hasCodeMirror) {\n        var cmEditor = $codable.data('cmEditor');\n        $codable.val(cmEditor.getValue());\n        cmEditor.toTextArea();\n      }\n\n      var value = dom.value($codable, options.prettifyHtml) || dom.emptyPara;\n      var isChange = $editable.html() !== value;\n\n      $editable.html(value);\n      $editable.height(options.height ? $codable.height() : 'auto');\n      $editor.removeClass('codeview');\n\n      if (isChange) {\n        handler.bindCustomEvent(\n          $holder, $editable.data('callbacks'), 'change'\n        )($editable.html(), $editable);\n      }\n\n      $editable.focus();\n\n      handler.invoke('toolbar.updateCodeview', $toolbar, false);\n    };\n  };\n\n  var DragAndDrop = function (handler) {\n    var $document = $(document);\n\n    /**\n     * attach Drag and Drop Events\n     *\n     * @param {Object} layoutInfo - layout Informations\n     * @param {Object} options\n     */\n    this.attach = function (layoutInfo, options) {\n      if (options.airMode || options.disableDragAndDrop) {\n        // prevent default drop event\n        $document.on('drop', function (e) {\n          e.preventDefault();\n        });\n      } else {\n        this.attachDragAndDropEvent(layoutInfo, options);\n      }\n    };\n\n    /**\n     * attach Drag and Drop Events\n     *\n     * @param {Object} layoutInfo - layout Informations\n     * @param {Object} options\n     */\n    this.attachDragAndDropEvent = function (layoutInfo, options) {\n      var collection = $(),\n          $editor = layoutInfo.editor(),\n          $dropzone = layoutInfo.dropzone(),\n          $dropzoneMessage = $dropzone.find('.note-dropzone-message');\n\n      // show dropzone on dragenter when dragging a object to document\n      // -but only if the editor is visible, i.e. has a positive width and height\n      $document.on('dragenter', function (e) {\n        var isCodeview = handler.invoke('codeview.isActivated', layoutInfo);\n        var hasEditorSize = $editor.width() > 0 && $editor.height() > 0;\n        if (!isCodeview && !collection.length && hasEditorSize) {\n          $editor.addClass('dragover');\n          $dropzone.width($editor.width());\n          $dropzone.height($editor.height());\n          $dropzoneMessage.text(options.langInfo.image.dragImageHere);\n        }\n        collection = collection.add(e.target);\n      }).on('dragleave', function (e) {\n        collection = collection.not(e.target);\n        if (!collection.length) {\n          $editor.removeClass('dragover');\n        }\n      }).on('drop', function () {\n        collection = $();\n        $editor.removeClass('dragover');\n      });\n\n      // change dropzone's message on hover.\n      $dropzone.on('dragenter', function () {\n        $dropzone.addClass('hover');\n        $dropzoneMessage.text(options.langInfo.image.dropImage);\n      }).on('dragleave', function () {\n        $dropzone.removeClass('hover');\n        $dropzoneMessage.text(options.langInfo.image.dragImageHere);\n      });\n\n      // attach dropImage\n      $dropzone.on('drop', function (event) {\n\n        var dataTransfer = event.originalEvent.dataTransfer;\n        var layoutInfo = dom.makeLayoutInfo(event.currentTarget || event.target);\n\n        if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {\n          event.preventDefault();\n          layoutInfo.editable().focus();\n          handler.insertImages(layoutInfo, dataTransfer.files);\n        } else {\n          var insertNodefunc = function () {\n            layoutInfo.holder().summernote('insertNode', this);\n          };\n\n          for (var i = 0, len = dataTransfer.types.length; i < len; i++) {\n            var type = dataTransfer.types[i];\n            var content = dataTransfer.getData(type);\n\n            if (type.toLowerCase().indexOf('text') > -1) {\n              layoutInfo.holder().summernote('pasteHTML', content);\n            } else {\n              $(content).each(insertNodefunc);\n            }\n          }\n        }\n      }).on('dragover', false); // prevent default dragover event\n    };\n  };\n\n  var Clipboard = function (handler) {\n    var $paste;\n\n    this.attach = function (layoutInfo) {\n      // [workaround] getting image from clipboard\n      //  - IE11 and Firefox: CTRL+v hook\n      //  - Webkit: event.clipboardData\n      if ((agent.isMSIE && agent.browserVersion > 10) || agent.isFF) {\n        $paste = $('<div />').attr('contenteditable', true).css({\n          position : 'absolute',\n          left : -100000,\n          opacity : 0\n        });\n\n        layoutInfo.editable().on('keydown', function (e) {\n          if (e.ctrlKey && e.keyCode === key.code.V) {\n            handler.invoke('saveRange', layoutInfo.editable());\n            $paste.focus();\n\n            setTimeout(function () {\n              pasteByHook(layoutInfo);\n            }, 0);\n          }\n        });\n\n        layoutInfo.editable().before($paste);\n      } else {\n        layoutInfo.editable().on('paste', pasteByEvent);\n      }\n    };\n\n    var pasteByHook = function (layoutInfo) {\n      var $editable = layoutInfo.editable();\n      var node = $paste[0].firstChild;\n\n      if (dom.isImg(node)) {\n        var dataURI = node.src;\n        var decodedData = atob(dataURI.split(',')[1]);\n        var array = new Uint8Array(decodedData.length);\n        for (var i = 0; i < decodedData.length; i++) {\n          array[i] = decodedData.charCodeAt(i);\n        }\n\n        var blob = new Blob([array], { type : 'image/png' });\n        blob.name = 'clipboard.png';\n\n        handler.invoke('restoreRange', $editable);\n        handler.invoke('focus', $editable);\n        handler.insertImages(layoutInfo, [blob]);\n      } else {\n        var pasteContent = $('<div />').html($paste.html()).html();\n        handler.invoke('restoreRange', $editable);\n        handler.invoke('focus', $editable);\n\n        if (pasteContent) {\n          handler.invoke('pasteHTML', $editable, pasteContent);\n        }\n      }\n\n      $paste.empty();\n    };\n\n    /**\n     * paste by clipboard event\n     *\n     * @param {Event} event\n     */\n    var pasteByEvent = function (event) {\n      var clipboardData = event.originalEvent.clipboardData;\n      var layoutInfo = dom.makeLayoutInfo(event.currentTarget || event.target);\n      var $editable = layoutInfo.editable();\n\n      if (clipboardData && clipboardData.items && clipboardData.items.length) {\n        var item = list.head(clipboardData.items);\n        if (item.kind === 'file' && item.type.indexOf('image/') !== -1) {\n          handler.insertImages(layoutInfo, [item.getAsFile()]);\n        }\n        handler.invoke('editor.afterCommand', $editable);\n      }\n    };\n  };\n\n  var LinkDialog = function (handler) {\n\n    /**\n     * toggle button status\n     *\n     * @private\n     * @param {jQuery} $btn\n     * @param {Boolean} isEnable\n     */\n    var toggleBtn = function ($btn, isEnable) {\n      $btn.toggleClass('disabled', !isEnable);\n      $btn.attr('disabled', !isEnable);\n    };\n\n    /**\n     * bind enter key\n     *\n     * @private\n     * @param {jQuery} $input\n     * @param {jQuery} $btn\n     */\n    var bindEnterKey = function ($input, $btn) {\n      $input.on('keypress', function (event) {\n        if (event.keyCode === key.code.ENTER) {\n          $btn.trigger('click');\n        }\n      });\n    };\n\n    /**\n     * Show link dialog and set event handlers on dialog controls.\n     *\n     * @param {jQuery} $editable\n     * @param {jQuery} $dialog\n     * @param {Object} linkInfo\n     * @return {Promise}\n     */\n    this.showLinkDialog = function ($editable, $dialog, linkInfo) {\n      return $.Deferred(function (deferred) {\n        var $linkDialog = $dialog.find('.note-link-dialog');\n\n        var $linkText = $linkDialog.find('.note-link-text'),\n        $linkUrl = $linkDialog.find('.note-link-url'),\n        $linkBtn = $linkDialog.find('.note-link-btn'),\n        $openInNewWindow = $linkDialog.find('input[type=checkbox]');\n\n        $linkDialog.one('shown.bs.modal', function () {\n          $linkText.val(linkInfo.text);\n\n          $linkText.on('input', function () {\n            toggleBtn($linkBtn, $linkText.val() && $linkUrl.val());\n            // if linktext was modified by keyup,\n            // stop cloning text from linkUrl\n            linkInfo.text = $linkText.val();\n          });\n\n          // if no url was given, copy text to url\n          if (!linkInfo.url) {\n            linkInfo.url = linkInfo.text || 'http://';\n            toggleBtn($linkBtn, linkInfo.text);\n          }\n\n          $linkUrl.on('input', function () {\n            toggleBtn($linkBtn, $linkText.val() && $linkUrl.val());\n            // display same link on `Text to display` input\n            // when create a new link\n            if (!linkInfo.text) {\n              $linkText.val($linkUrl.val());\n            }\n          }).val(linkInfo.url).trigger('focus').trigger('select');\n\n          bindEnterKey($linkUrl, $linkBtn);\n          bindEnterKey($linkText, $linkBtn);\n\n          $openInNewWindow.prop('checked', linkInfo.isNewWindow);\n\n          $linkBtn.one('click', function (event) {\n            event.preventDefault();\n\n            deferred.resolve({\n              range: linkInfo.range,\n              url: $linkUrl.val(),\n              text: $linkText.val(),\n              isNewWindow: $openInNewWindow.is(':checked')\n            });\n            $linkDialog.modal('hide');\n          });\n        }).one('hidden.bs.modal', function () {\n          // detach events\n          $linkText.off('input keypress');\n          $linkUrl.off('input keypress');\n          $linkBtn.off('click');\n\n          if (deferred.state() === 'pending') {\n            deferred.reject();\n          }\n        }).modal('show');\n      }).promise();\n    };\n\n    /**\n     * @param {Object} layoutInfo\n     */\n    this.show = function (layoutInfo) {\n      var $editor = layoutInfo.editor(),\n          $dialog = layoutInfo.dialog(),\n          $editable = layoutInfo.editable(),\n          $popover = layoutInfo.popover(),\n          linkInfo = handler.invoke('editor.getLinkInfo', $editable);\n\n      var options = $editor.data('options');\n\n      handler.invoke('editor.saveRange', $editable);\n      this.showLinkDialog($editable, $dialog, linkInfo).then(function (linkInfo) {\n        handler.invoke('editor.restoreRange', $editable);\n        handler.invoke('editor.createLink', $editable, linkInfo, options);\n        // hide popover after creating link\n        handler.invoke('popover.hide', $popover);\n      }).fail(function () {\n        handler.invoke('editor.restoreRange', $editable);\n      });\n    };\n  };\n\n  var ImageDialog = function (handler) {\n    /**\n     * toggle button status\n     *\n     * @private\n     * @param {jQuery} $btn\n     * @param {Boolean} isEnable\n     */\n    var toggleBtn = function ($btn, isEnable) {\n      $btn.toggleClass('disabled', !isEnable);\n      $btn.attr('disabled', !isEnable);\n    };\n\n    /**\n     * bind enter key\n     *\n     * @private\n     * @param {jQuery} $input\n     * @param {jQuery} $btn\n     */\n    var bindEnterKey = function ($input, $btn) {\n      $input.on('keypress', function (event) {\n        if (event.keyCode === key.code.ENTER) {\n          $btn.trigger('click');\n        }\n      });\n    };\n\n    this.show = function (layoutInfo) {\n      var $dialog = layoutInfo.dialog(),\n          $editable = layoutInfo.editable();\n\n      handler.invoke('editor.saveRange', $editable);\n      this.showImageDialog($editable, $dialog).then(function (data) {\n        handler.invoke('editor.restoreRange', $editable);\n\n        if (typeof data === 'string') {\n          // image url\n          handler.invoke('editor.insertImage', $editable, data);\n        } else {\n          // array of files\n          handler.insertImages(layoutInfo, data);\n        }\n      }).fail(function () {\n        handler.invoke('editor.restoreRange', $editable);\n      });\n    };\n\n    /**\n     * show image dialog\n     *\n     * @param {jQuery} $editable\n     * @param {jQuery} $dialog\n     * @return {Promise}\n     */\n    this.showImageDialog = function ($editable, $dialog) {\n      return $.Deferred(function (deferred) {\n        var $imageDialog = $dialog.find('.note-image-dialog');\n\n        var $imageInput = $dialog.find('.note-image-input'),\n            $imageUrl = $dialog.find('.note-image-url'),\n            $imageBtn = $dialog.find('.note-image-btn');\n\n        $imageDialog.one('shown.bs.modal', function () {\n          // Cloning imageInput to clear element.\n          $imageInput.replaceWith($imageInput.clone()\n            .on('change', function () {\n              deferred.resolve(this.files || this.value);\n              $imageDialog.modal('hide');\n            })\n            .val('')\n          );\n\n          $imageBtn.click(function (event) {\n            event.preventDefault();\n\n            deferred.resolve($imageUrl.val());\n            $imageDialog.modal('hide');\n          });\n\n          $imageUrl.on('keyup paste', function (event) {\n            var url;\n            \n            if (event.type === 'paste') {\n              url = event.originalEvent.clipboardData.getData('text');\n            } else {\n              url = $imageUrl.val();\n            }\n            \n            toggleBtn($imageBtn, url);\n          }).val('').trigger('focus');\n          bindEnterKey($imageUrl, $imageBtn);\n        }).one('hidden.bs.modal', function () {\n          $imageInput.off('change');\n          $imageUrl.off('keyup paste keypress');\n          $imageBtn.off('click');\n\n          if (deferred.state() === 'pending') {\n            deferred.reject();\n          }\n        }).modal('show');\n      });\n    };\n  };\n\n  var HelpDialog = function (handler) {\n    /**\n     * show help dialog\n     *\n     * @param {jQuery} $editable\n     * @param {jQuery} $dialog\n     * @return {Promise}\n     */\n    this.showHelpDialog = function ($editable, $dialog) {\n      return $.Deferred(function (deferred) {\n        var $helpDialog = $dialog.find('.note-help-dialog');\n\n        $helpDialog.one('hidden.bs.modal', function () {\n          deferred.resolve();\n        }).modal('show');\n      }).promise();\n    };\n\n    /**\n     * @param {Object} layoutInfo\n     */\n    this.show = function (layoutInfo) {\n      var $dialog = layoutInfo.dialog(),\n          $editable = layoutInfo.editable();\n\n      handler.invoke('editor.saveRange', $editable, true);\n      this.showHelpDialog($editable, $dialog).then(function () {\n        handler.invoke('editor.restoreRange', $editable);\n      });\n    };\n  };\n\n\n  /**\n   * @class EventHandler\n   *\n   * EventHandler\n   *  - TODO: new instance per a editor\n   */\n  var EventHandler = function () {\n    var self = this;\n\n    /**\n     * Modules\n     */\n    var modules = this.modules = {\n      editor: new Editor(this),\n      toolbar: new Toolbar(this),\n      statusbar: new Statusbar(this),\n      popover: new Popover(this),\n      handle: new Handle(this),\n      fullscreen: new Fullscreen(this),\n      codeview: new Codeview(this),\n      dragAndDrop: new DragAndDrop(this),\n      clipboard: new Clipboard(this),\n      linkDialog: new LinkDialog(this),\n      imageDialog: new ImageDialog(this),\n      helpDialog: new HelpDialog(this)\n    };\n\n    /**\n     * invoke module's method\n     *\n     * @param {String} moduleAndMethod - ex) 'editor.redo'\n     * @param {...*} arguments - arguments of method\n     * @return {*}\n     */\n    this.invoke = function () {\n      var moduleAndMethod = list.head(list.from(arguments));\n      var args = list.tail(list.from(arguments));\n\n      var splits = moduleAndMethod.split('.');\n      var hasSeparator = splits.length > 1;\n      var moduleName = hasSeparator && list.head(splits);\n      var methodName = hasSeparator ? list.last(splits) : list.head(splits);\n\n      var module = this.getModule(moduleName);\n      var method = module[methodName];\n\n      return method && method.apply(module, args);\n    };\n\n    /**\n     * returns module\n     *\n     * @param {String} moduleName - name of module\n     * @return {Module} - defaults is editor\n     */\n    this.getModule = function (moduleName) {\n      return this.modules[moduleName] || this.modules.editor;\n    };\n\n    /**\n     * @param {jQuery} $holder\n     * @param {Object} callbacks\n     * @param {String} eventNamespace\n     * @returns {Function}\n     */\n    var bindCustomEvent = this.bindCustomEvent = function ($holder, callbacks, eventNamespace) {\n      return function () {\n        var callback = callbacks[func.namespaceToCamel(eventNamespace, 'on')];\n        if (callback) {\n          callback.apply($holder[0], arguments);\n        }\n        return $holder.trigger('summernote.' + eventNamespace, arguments);\n      };\n    };\n\n    /**\n     * insert Images from file array.\n     *\n     * @private\n     * @param {Object} layoutInfo\n     * @param {File[]} files\n     */\n    this.insertImages = function (layoutInfo, files) {\n      var $editor = layoutInfo.editor(),\n          $editable = layoutInfo.editable(),\n          $holder = layoutInfo.holder();\n\n      var callbacks = $editable.data('callbacks');\n      var options = $editor.data('options');\n\n      // If onImageUpload options setted\n      if (callbacks.onImageUpload) {\n        bindCustomEvent($holder, callbacks, 'image.upload')(files);\n      // else insert Image as dataURL\n      } else {\n        $.each(files, function (idx, file) {\n          var filename = file.name;\n          if (options.maximumImageFileSize && options.maximumImageFileSize < file.size) {\n            bindCustomEvent($holder, callbacks, 'image.upload.error')(options.langInfo.image.maximumFileSizeError);\n          } else {\n            async.readFileAsDataURL(file).then(function (sDataURL) {\n              modules.editor.insertImage($editable, sDataURL, filename);\n            }).fail(function () {\n              bindCustomEvent($holder, callbacks, 'image.upload.error')(options.langInfo.image.maximumFileSizeError);\n            });\n          }\n        });\n      }\n    };\n\n    var commands = {\n      /**\n       * @param {Object} layoutInfo\n       */\n      showLinkDialog: function (layoutInfo) {\n        modules.linkDialog.show(layoutInfo);\n      },\n\n      /**\n       * @param {Object} layoutInfo\n       */\n      showImageDialog: function (layoutInfo) {\n        modules.imageDialog.show(layoutInfo);\n      },\n\n      /**\n       * @param {Object} layoutInfo\n       */\n      showHelpDialog: function (layoutInfo) {\n        modules.helpDialog.show(layoutInfo);\n      },\n\n      /**\n       * @param {Object} layoutInfo\n       */\n      fullscreen: function (layoutInfo) {\n        modules.fullscreen.toggle(layoutInfo);\n      },\n\n      /**\n       * @param {Object} layoutInfo\n       */\n      codeview: function (layoutInfo) {\n        modules.codeview.toggle(layoutInfo);\n      }\n    };\n\n    var hMousedown = function (event) {\n      //preventDefault Selection for FF, IE8+\n      if (dom.isImg(event.target)) {\n        event.preventDefault();\n      }\n    };\n\n    var hKeyupAndMouseup = function (event) {\n      var layoutInfo = dom.makeLayoutInfo(event.currentTarget || event.target);\n      modules.editor.removeBogus(layoutInfo.editable());\n      hToolbarAndPopoverUpdate(event);\n    };\n\n    /**\n     * update sytle info\n     * @param {Object} styleInfo\n     * @param {Object} layoutInfo\n     */\n    this.updateStyleInfo = function (styleInfo, layoutInfo) {\n      if (!styleInfo) {\n        return;\n      }\n      var isAirMode = layoutInfo.editor().data('options').airMode;\n      if (!isAirMode) {\n        modules.toolbar.update(layoutInfo.toolbar(), styleInfo);\n      }\n\n      modules.popover.update(layoutInfo.popover(), styleInfo, isAirMode);\n      modules.handle.update(layoutInfo.handle(), styleInfo, isAirMode);\n    };\n\n    var hToolbarAndPopoverUpdate = function (event) {\n      var target = event.target;\n      // delay for range after mouseup\n      setTimeout(function () {\n        var layoutInfo = dom.makeLayoutInfo(target);\n        var styleInfo = modules.editor.currentStyle(target);\n        self.updateStyleInfo(styleInfo, layoutInfo);\n      }, 0);\n    };\n\n    var hScroll = function (event) {\n      var layoutInfo = dom.makeLayoutInfo(event.currentTarget || event.target);\n      //hide popover and handle when scrolled\n      modules.popover.hide(layoutInfo.popover());\n      modules.handle.hide(layoutInfo.handle());\n    };\n\n    var hToolbarAndPopoverMousedown = function (event) {\n      // prevent default event when insertTable (FF, Webkit)\n      var $btn = $(event.target).closest('[data-event]');\n      if ($btn.length) {\n        event.preventDefault();\n      }\n    };\n\n    var hToolbarAndPopoverClick = function (event) {\n      var $btn = $(event.target).closest('[data-event]');\n\n      if (!$btn.length) {\n        return;\n      }\n\n      var eventName = $btn.attr('data-event'),\n          value = $btn.attr('data-value'),\n          hide = $btn.attr('data-hide');\n\n      var layoutInfo = dom.makeLayoutInfo(event.target);\n\n      // before command: detect control selection element($target)\n      var $target;\n      if ($.inArray(eventName, ['resize', 'floatMe', 'removeMedia', 'imageShape']) !== -1) {\n        var $selection = layoutInfo.handle().find('.note-control-selection');\n        $target = $($selection.data('target'));\n      }\n\n      // If requested, hide the popover when the button is clicked.\n      // Useful for things like showHelpDialog.\n      if (hide) {\n        $btn.parents('.popover').hide();\n      }\n\n      if ($.isFunction($.summernote.pluginEvents[eventName])) {\n        $.summernote.pluginEvents[eventName](event, modules.editor, layoutInfo, value);\n      } else if (modules.editor[eventName]) { // on command\n        var $editable = layoutInfo.editable();\n        $editable.focus();\n        modules.editor[eventName]($editable, value, $target);\n        event.preventDefault();\n      } else if (commands[eventName]) {\n        commands[eventName].call(this, layoutInfo);\n        event.preventDefault();\n      }\n\n      // after command\n      if ($.inArray(eventName, ['backColor', 'foreColor']) !== -1) {\n        var options = layoutInfo.editor().data('options', options);\n        var module = options.airMode ? modules.popover : modules.toolbar;\n        module.updateRecentColor(list.head($btn), eventName, value);\n      }\n\n      hToolbarAndPopoverUpdate(event);\n    };\n\n    var PX_PER_EM = 18;\n    var hDimensionPickerMove = function (event, options) {\n      var $picker = $(event.target.parentNode); // target is mousecatcher\n      var $dimensionDisplay = $picker.next();\n      var $catcher = $picker.find('.note-dimension-picker-mousecatcher');\n      var $highlighted = $picker.find('.note-dimension-picker-highlighted');\n      var $unhighlighted = $picker.find('.note-dimension-picker-unhighlighted');\n\n      var posOffset;\n      // HTML5 with jQuery - e.offsetX is undefined in Firefox\n      if (event.offsetX === undefined) {\n        var posCatcher = $(event.target).offset();\n        posOffset = {\n          x: event.pageX - posCatcher.left,\n          y: event.pageY - posCatcher.top\n        };\n      } else {\n        posOffset = {\n          x: event.offsetX,\n          y: event.offsetY\n        };\n      }\n\n      var dim = {\n        c: Math.ceil(posOffset.x / PX_PER_EM) || 1,\n        r: Math.ceil(posOffset.y / PX_PER_EM) || 1\n      };\n\n      $highlighted.css({ width: dim.c + 'em', height: dim.r + 'em' });\n      $catcher.attr('data-value', dim.c + 'x' + dim.r);\n\n      if (3 < dim.c && dim.c < options.insertTableMaxSize.col) {\n        $unhighlighted.css({ width: dim.c + 1 + 'em'});\n      }\n\n      if (3 < dim.r && dim.r < options.insertTableMaxSize.row) {\n        $unhighlighted.css({ height: dim.r + 1 + 'em'});\n      }\n\n      $dimensionDisplay.html(dim.c + ' x ' + dim.r);\n    };\n    \n    /**\n     * bind KeyMap on keydown\n     *\n     * @param {Object} layoutInfo\n     * @param {Object} keyMap\n     */\n    this.bindKeyMap = function (layoutInfo, keyMap) {\n      var $editor = layoutInfo.editor();\n      var $editable = layoutInfo.editable();\n\n      $editable.on('keydown', function (event) {\n        var keys = [];\n\n        // modifier\n        if (event.metaKey) { keys.push('CMD'); }\n        if (event.ctrlKey && !event.altKey) { keys.push('CTRL'); }\n        if (event.shiftKey) { keys.push('SHIFT'); }\n\n        // keycode\n        var keyName = key.nameFromCode[event.keyCode];\n        if (keyName) {\n          keys.push(keyName);\n        }\n\n        var pluginEvent;\n        var keyString = keys.join('+');\n        var eventName = keyMap[keyString];\n        if (eventName) {\n          // FIXME Summernote doesn't support event pipeline yet.\n          //  - Plugin -> Base Code\n          pluginEvent = $.summernote.pluginEvents[keyString];\n          if ($.isFunction(pluginEvent)) {\n            if (pluginEvent(event, modules.editor, layoutInfo)) {\n              return false;\n            }\n          }\n\n          pluginEvent = $.summernote.pluginEvents[eventName];\n\n          if ($.isFunction(pluginEvent)) {\n            pluginEvent(event, modules.editor, layoutInfo);\n          } else if (modules.editor[eventName]) {\n            modules.editor[eventName]($editable, $editor.data('options'));\n            event.preventDefault();\n          } else if (commands[eventName]) {\n            commands[eventName].call(this, layoutInfo);\n            event.preventDefault();\n          }\n        } else if (key.isEdit(event.keyCode)) {\n          modules.editor.afterCommand($editable);\n        }\n      });\n    };\n\n    /**\n     * attach eventhandler\n     *\n     * @param {Object} layoutInfo - layout Informations\n     * @param {Object} options - user options include custom event handlers\n     */\n    this.attach = function (layoutInfo, options) {\n      // handlers for editable\n      if (options.shortcuts) {\n        this.bindKeyMap(layoutInfo, options.keyMap[agent.isMac ? 'mac' : 'pc']);\n      }\n      layoutInfo.editable().on('mousedown', hMousedown);\n      layoutInfo.editable().on('keyup mouseup', hKeyupAndMouseup);\n      layoutInfo.editable().on('scroll', hScroll);\n\n      // handler for clipboard\n      modules.clipboard.attach(layoutInfo, options);\n\n      // handler for handle and popover\n      modules.handle.attach(layoutInfo, options);\n      layoutInfo.popover().on('click', hToolbarAndPopoverClick);\n      layoutInfo.popover().on('mousedown', hToolbarAndPopoverMousedown);\n\n      // handler for drag and drop\n      modules.dragAndDrop.attach(layoutInfo, options);\n\n      // handlers for frame mode (toolbar, statusbar)\n      if (!options.airMode) {\n        // handler for toolbar\n        layoutInfo.toolbar().on('click', hToolbarAndPopoverClick);\n        layoutInfo.toolbar().on('mousedown', hToolbarAndPopoverMousedown);\n\n        // handler for statusbar\n        modules.statusbar.attach(layoutInfo, options);\n      }\n\n      // handler for table dimension\n      var $catcherContainer = options.airMode ? layoutInfo.popover() :\n                                                layoutInfo.toolbar();\n      var $catcher = $catcherContainer.find('.note-dimension-picker-mousecatcher');\n      $catcher.css({\n        width: options.insertTableMaxSize.col + 'em',\n        height: options.insertTableMaxSize.row + 'em'\n      }).on('mousemove', function (event) {\n        hDimensionPickerMove(event, options);\n      });\n\n      // save options on editor\n      layoutInfo.editor().data('options', options);\n\n      // ret styleWithCSS for backColor / foreColor clearing with 'inherit'.\n      if (!agent.isMSIE) {\n        // [workaround] for Firefox\n        //  - protect FF Error: NS_ERROR_FAILURE: Failure\n        setTimeout(function () {\n          document.execCommand('styleWithCSS', 0, options.styleWithSpan);\n        }, 0);\n      }\n\n      // History\n      var history = new History(layoutInfo.editable());\n      layoutInfo.editable().data('NoteHistory', history);\n\n      // All editor status will be saved on editable with jquery's data\n      // for support multiple editor with singleton object.\n      layoutInfo.editable().data('callbacks', {\n        onInit: options.onInit,\n        onFocus: options.onFocus,\n        onBlur: options.onBlur,\n        onKeydown: options.onKeydown,\n        onKeyup: options.onKeyup,\n        onMousedown: options.onMousedown,\n        onEnter: options.onEnter,\n        onPaste: options.onPaste,\n        onBeforeCommand: options.onBeforeCommand,\n        onChange: options.onChange,\n        onImageUpload: options.onImageUpload,\n        onImageUploadError: options.onImageUploadError,\n        onMediaDelete: options.onMediaDelete,\n        onToolbarClick: options.onToolbarClick\n      });\n\n      var styleInfo = modules.editor.styleFromNode(layoutInfo.editable());\n      this.updateStyleInfo(styleInfo, layoutInfo);\n    };\n\n    /**\n     * attach jquery custom event\n     *\n     * @param {Object} layoutInfo - layout Informations\n     */\n    this.attachCustomEvent = function (layoutInfo, options) {\n      var $holder = layoutInfo.holder();\n      var $editable = layoutInfo.editable();\n      var callbacks = $editable.data('callbacks');\n\n      $editable.focus(bindCustomEvent($holder, callbacks, 'focus'));\n      $editable.blur(bindCustomEvent($holder, callbacks, 'blur'));\n\n      $editable.keydown(function (event) {\n        if (event.keyCode === key.code.ENTER) {\n          bindCustomEvent($holder, callbacks, 'enter').call(this, event);\n        }\n        bindCustomEvent($holder, callbacks, 'keydown').call(this, event);\n      });\n      $editable.keyup(bindCustomEvent($holder, callbacks, 'keyup'));\n\n      $editable.on('mousedown', bindCustomEvent($holder, callbacks, 'mousedown'));\n      $editable.on('mouseup', bindCustomEvent($holder, callbacks, 'mouseup'));\n      $editable.on('scroll', bindCustomEvent($holder, callbacks, 'scroll'));\n\n      $editable.on('paste', bindCustomEvent($holder, callbacks, 'paste'));\n      \n      // [workaround] IE doesn't have input events for contentEditable\n      //  - see: https://goo.gl/4bfIvA\n      var changeEventName = agent.isMSIE ? 'DOMCharacterDataModified DOMSubtreeModified DOMNodeInserted' : 'input';\n      $editable.on(changeEventName, function () {\n        bindCustomEvent($holder, callbacks, 'change')($editable.html(), $editable);\n      });\n\n      if (!options.airMode) {\n        layoutInfo.toolbar().click(bindCustomEvent($holder, callbacks, 'toolbar.click'));\n        layoutInfo.popover().click(bindCustomEvent($holder, callbacks, 'popover.click'));\n      }\n\n      // Textarea: auto filling the code before form submit.\n      if (dom.isTextarea(list.head($holder))) {\n        $holder.closest('form').submit(function (e) {\n          layoutInfo.holder().val(layoutInfo.holder().code());\n          bindCustomEvent($holder, callbacks, 'submit').call(this, e, $holder.code());\n        });\n      }\n\n      // textarea auto sync\n      if (dom.isTextarea(list.head($holder)) && options.textareaAutoSync) {\n        $holder.on('summernote.change', function () {\n          layoutInfo.holder().val(layoutInfo.holder().code());\n        });\n      }\n\n      // fire init event\n      bindCustomEvent($holder, callbacks, 'init')(layoutInfo);\n\n      // fire plugin init event\n      for (var i = 0, len = $.summernote.plugins.length; i < len; i++) {\n        if ($.isFunction($.summernote.plugins[i].init)) {\n          $.summernote.plugins[i].init(layoutInfo);\n        }\n      }\n    };\n      \n    this.detach = function (layoutInfo, options) {\n      layoutInfo.holder().off();\n      layoutInfo.editable().off();\n\n      layoutInfo.popover().off();\n      layoutInfo.handle().off();\n      layoutInfo.dialog().off();\n\n      if (!options.airMode) {\n        layoutInfo.dropzone().off();\n        layoutInfo.toolbar().off();\n        layoutInfo.statusbar().off();\n      }\n    };\n  };\n\n  /**\n   * @class Renderer\n   *\n   * renderer\n   *\n   * rendering toolbar and editable\n   */\n  var Renderer = function () {\n\n    /**\n     * bootstrap button template\n     * @private\n     * @param {String} label button name\n     * @param {Object} [options] button options\n     * @param {String} [options.event] data-event\n     * @param {String} [options.className] button's class name\n     * @param {String} [options.value] data-value\n     * @param {String} [options.title] button's title for popup\n     * @param {String} [options.dropdown] dropdown html\n     * @param {String} [options.hide] data-hide\n     */\n    var tplButton = function (label, options) {\n      var event = options.event;\n      var value = options.value;\n      var title = options.title;\n      var className = options.className;\n      var dropdown = options.dropdown;\n      var hide = options.hide;\n\n      return (dropdown ? '<div class=\"btn-group' +\n               (className ? ' ' + className : '') + '\">' : '') +\n               '<button type=\"button\"' +\n                 ' class=\"btn btn-default btn-sm' +\n                   ((!dropdown && className) ? ' ' + className : '') +\n                   (dropdown ? ' dropdown-toggle' : '') +\n                 '\"' +\n                 (dropdown ? ' data-toggle=\"dropdown\"' : '') +\n                 (title ? ' title=\"' + title + '\"' : '') +\n                 (event ? ' data-event=\"' + event + '\"' : '') +\n                 (value ? ' data-value=\\'' + value + '\\'' : '') +\n                 (hide ? ' data-hide=\\'' + hide + '\\'' : '') +\n                 ' tabindex=\"-1\">' +\n                 label +\n                 (dropdown ? ' <span class=\"caret\"></span>' : '') +\n               '</button>' +\n               (dropdown || '') +\n             (dropdown ? '</div>' : '');\n    };\n\n    /**\n     * bootstrap icon button template\n     * @private\n     * @param {String} iconClassName\n     * @param {Object} [options]\n     * @param {String} [options.event]\n     * @param {String} [options.value]\n     * @param {String} [options.title]\n     * @param {String} [options.dropdown]\n     */\n    var tplIconButton = function (iconClassName, options) {\n      var label = '<i class=\"' + iconClassName + '\"></i>';\n      return tplButton(label, options);\n    };\n\n    /**\n     * bootstrap popover template\n     * @private\n     * @param {String} className\n     * @param {String} content\n     */\n    var tplPopover = function (className, content) {\n      var $popover = $('<div class=\"' + className + ' popover bottom in\" style=\"display: none;\">' +\n               '<div class=\"arrow\"></div>' +\n               '<div class=\"popover-content\">' +\n               '</div>' +\n             '</div>');\n\n      $popover.find('.popover-content').append(content);\n      return $popover;\n    };\n\n    /**\n     * bootstrap dialog template\n     *\n     * @param {String} className\n     * @param {String} [title='']\n     * @param {String} body\n     * @param {String} [footer='']\n     */\n    var tplDialog = function (className, title, body, footer) {\n      return '<div class=\"' + className + ' modal\" aria-hidden=\"false\">' +\n               '<div class=\"modal-dialog\">' +\n                 '<div class=\"modal-content\">' +\n                   (title ?\n                   '<div class=\"modal-header\">' +\n                     '<button type=\"button\" class=\"close\" aria-hidden=\"true\" tabindex=\"-1\">&times;</button>' +\n                     '<h4 class=\"modal-title\">' + title + '</h4>' +\n                   '</div>' : ''\n                   ) +\n                   '<div class=\"modal-body\">' + body + '</div>' +\n                   (footer ?\n                   '<div class=\"modal-footer\">' + footer + '</div>' : ''\n                   ) +\n                 '</div>' +\n               '</div>' +\n             '</div>';\n    };\n\n    /**\n     * bootstrap dropdown template\n     *\n     * @param {String|String[]} contents\n     * @param {String} [className='']\n     * @param {String} [nodeName='']\n     */\n    var tplDropdown = function (contents, className, nodeName) {\n      var classes = 'dropdown-menu' + (className ? ' ' + className : '');\n      nodeName = nodeName || 'ul';\n      if (contents instanceof Array) {\n        contents = contents.join('');\n      }\n\n      return '<' + nodeName + ' class=\"' + classes + '\">' + contents + '</' + nodeName + '>';\n    };\n\n    var tplButtonInfo = {\n      picture: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.image.image, {\n          event: 'showImageDialog',\n          title: lang.image.image,\n          hide: true\n        });\n      },\n      link: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.link.link, {\n          event: 'showLinkDialog',\n          title: lang.link.link,\n          hide: true\n        });\n      },\n      table: function (lang, options) {\n        var dropdown = [\n          '<div class=\"note-dimension-picker\">',\n          '<div class=\"note-dimension-picker-mousecatcher\" data-event=\"insertTable\" data-value=\"1x1\"></div>',\n          '<div class=\"note-dimension-picker-highlighted\"></div>',\n          '<div class=\"note-dimension-picker-unhighlighted\"></div>',\n          '</div>',\n          '<div class=\"note-dimension-display\"> 1 x 1 </div>'\n        ];\n\n        return tplIconButton(options.iconPrefix + options.icons.table.table, {\n          title: lang.table.table,\n          dropdown: tplDropdown(dropdown, 'note-table')\n        });\n      },\n      style: function (lang, options) {\n        var items = options.styleTags.reduce(function (memo, v) {\n          var label = lang.style[v === 'p' ? 'normal' : v];\n          return memo + '<li><a data-event=\"formatBlock\" href=\"#\" data-value=\"' + v + '\">' +\n                   (\n                     (v === 'p' || v === 'pre') ? label :\n                     '<' + v + '>' + label + '</' + v + '>'\n                   ) +\n                 '</a></li>';\n        }, '');\n\n        return tplIconButton(options.iconPrefix + options.icons.style.style, {\n          title: lang.style.style,\n          dropdown: tplDropdown(items)\n        });\n      },\n      fontname: function (lang, options) {\n        var realFontList = [];\n        var items = options.fontNames.reduce(function (memo, v) {\n          if (!agent.isFontInstalled(v) && !list.contains(options.fontNamesIgnoreCheck, v)) {\n            return memo;\n          }\n          realFontList.push(v);\n          return memo + '<li><a data-event=\"fontName\" href=\"#\" data-value=\"' + v + '\" style=\"font-family:\\'' + v + '\\'\">' +\n                          '<i class=\"' + options.iconPrefix + options.icons.misc.check + '\"></i> ' + v +\n                        '</a></li>';\n        }, '');\n\n        var hasDefaultFont = agent.isFontInstalled(options.defaultFontName);\n        var defaultFontName = (hasDefaultFont) ? options.defaultFontName : realFontList[0];\n\n        var label = '<span class=\"note-current-fontname\">' +\n                        defaultFontName +\n                     '</span>';\n        return tplButton(label, {\n          title: lang.font.name,\n          className: 'note-fontname',\n          dropdown: tplDropdown(items, 'note-check')\n        });\n      },\n      fontsize: function (lang, options) {\n        var items = options.fontSizes.reduce(function (memo, v) {\n          return memo + '<li><a data-event=\"fontSize\" href=\"#\" data-value=\"' + v + '\">' +\n                          '<i class=\"' + options.iconPrefix + options.icons.misc.check + '\"></i> ' + v +\n                        '</a></li>';\n        }, '');\n\n        var label = '<span class=\"note-current-fontsize\">11</span>';\n        return tplButton(label, {\n          title: lang.font.size,\n          className: 'note-fontsize',\n          dropdown: tplDropdown(items, 'note-check')\n        });\n      },\n      color: function (lang, options) {\n        var colorButtonLabel = '<i class=\"' +\n                                  options.iconPrefix + options.icons.color.recent +\n                                '\" style=\"color:black;background-color:yellow;\"></i>';\n\n        var colorButton = tplButton(colorButtonLabel, {\n          className: 'note-recent-color',\n          title: lang.color.recent,\n          event: 'color',\n          value: '{\"backColor\":\"yellow\"}'\n        });\n\n        var items = [\n          '<li><div class=\"btn-group\">',\n          '<div class=\"note-palette-title\">' + lang.color.background + '</div>',\n          '<div class=\"note-color-reset\" data-event=\"backColor\"',\n          ' data-value=\"inherit\" title=\"' + lang.color.transparent + '\">' + lang.color.setTransparent + '</div>',\n          '<div class=\"note-color-palette\" data-target-event=\"backColor\"></div>',\n          '</div><div class=\"btn-group\">',\n          '<div class=\"note-palette-title\">' + lang.color.foreground + '</div>',\n          '<div class=\"note-color-reset\" data-event=\"foreColor\" data-value=\"inherit\" title=\"' + lang.color.reset + '\">',\n          lang.color.resetToDefault,\n          '</div>',\n          '<div class=\"note-color-palette\" data-target-event=\"foreColor\"></div>',\n          '</div></li>'\n        ];\n\n        var moreButton = tplButton('', {\n          title: lang.color.more,\n          dropdown: tplDropdown(items)\n        });\n\n        return colorButton + moreButton;\n      },\n      bold: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.bold, {\n          event: 'bold',\n          title: lang.font.bold\n        });\n      },\n      italic: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.italic, {\n          event: 'italic',\n          title: lang.font.italic\n        });\n      },\n      underline: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.underline, {\n          event: 'underline',\n          title: lang.font.underline\n        });\n      },\n      strikethrough: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.strikethrough, {\n          event: 'strikethrough',\n          title: lang.font.strikethrough\n        });\n      },\n      superscript: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.superscript, {\n          event: 'superscript',\n          title: lang.font.superscript\n        });\n      },\n      subscript: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.subscript, {\n          event: 'subscript',\n          title: lang.font.subscript\n        });\n      },\n      clear: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.clear, {\n          event: 'removeFormat',\n          title: lang.font.clear\n        });\n      },\n      ul: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.lists.unordered, {\n          event: 'insertUnorderedList',\n          title: lang.lists.unordered\n        });\n      },\n      ol: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.lists.ordered, {\n          event: 'insertOrderedList',\n          title: lang.lists.ordered\n        });\n      },\n      paragraph: function (lang, options) {\n        var leftButton = tplIconButton(options.iconPrefix + options.icons.paragraph.left, {\n          title: lang.paragraph.left,\n          event: 'justifyLeft'\n        });\n        var centerButton = tplIconButton(options.iconPrefix + options.icons.paragraph.center, {\n          title: lang.paragraph.center,\n          event: 'justifyCenter'\n        });\n        var rightButton = tplIconButton(options.iconPrefix + options.icons.paragraph.right, {\n          title: lang.paragraph.right,\n          event: 'justifyRight'\n        });\n        var justifyButton = tplIconButton(options.iconPrefix + options.icons.paragraph.justify, {\n          title: lang.paragraph.justify,\n          event: 'justifyFull'\n        });\n\n        var outdentButton = tplIconButton(options.iconPrefix + options.icons.paragraph.outdent, {\n          title: lang.paragraph.outdent,\n          event: 'outdent'\n        });\n        var indentButton = tplIconButton(options.iconPrefix + options.icons.paragraph.indent, {\n          title: lang.paragraph.indent,\n          event: 'indent'\n        });\n\n        var dropdown = [\n          '<div class=\"note-align btn-group\">',\n          leftButton + centerButton + rightButton + justifyButton,\n          '</div><div class=\"note-list btn-group\">',\n          indentButton + outdentButton,\n          '</div>'\n        ];\n\n        return tplIconButton(options.iconPrefix + options.icons.paragraph.paragraph, {\n          title: lang.paragraph.paragraph,\n          dropdown: tplDropdown(dropdown, '', 'div')\n        });\n      },\n      height: function (lang, options) {\n        var items = options.lineHeights.reduce(function (memo, v) {\n          return memo + '<li><a data-event=\"lineHeight\" href=\"#\" data-value=\"' + parseFloat(v) + '\">' +\n                          '<i class=\"' + options.iconPrefix + options.icons.misc.check + '\"></i> ' + v +\n                        '</a></li>';\n        }, '');\n\n        return tplIconButton(options.iconPrefix + options.icons.font.height, {\n          title: lang.font.height,\n          dropdown: tplDropdown(items, 'note-check')\n        });\n\n      },\n      help: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.options.help, {\n          event: 'showHelpDialog',\n          title: lang.options.help,\n          hide: true\n        });\n      },\n      fullscreen: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.options.fullscreen, {\n          event: 'fullscreen',\n          title: lang.options.fullscreen\n        });\n      },\n      codeview: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.options.codeview, {\n          event: 'codeview',\n          title: lang.options.codeview\n        });\n      },\n      undo: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.history.undo, {\n          event: 'undo',\n          title: lang.history.undo\n        });\n      },\n      redo: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.history.redo, {\n          event: 'redo',\n          title: lang.history.redo\n        });\n      },\n      hr: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.hr.insert, {\n          event: 'insertHorizontalRule',\n          title: lang.hr.insert\n        });\n      }\n    };\n\n    var tplPopovers = function (lang, options) {\n      var tplLinkPopover = function () {\n        var linkButton = tplIconButton(options.iconPrefix + options.icons.link.edit, {\n          title: lang.link.edit,\n          event: 'showLinkDialog',\n          hide: true\n        });\n        var unlinkButton = tplIconButton(options.iconPrefix + options.icons.link.unlink, {\n          title: lang.link.unlink,\n          event: 'unlink'\n        });\n        var content = '<a href=\"http://www.google.com\" target=\"_blank\">www.google.com</a>&nbsp;&nbsp;' +\n                      '<div class=\"note-insert btn-group\">' +\n                        linkButton + unlinkButton +\n                      '</div>';\n        return tplPopover('note-link-popover', content);\n      };\n\n      var tplImagePopover = function () {\n        var fullButton = tplButton('<span class=\"note-fontsize-10\">100%</span>', {\n          title: lang.image.resizeFull,\n          event: 'resize',\n          value: '1'\n        });\n        var halfButton = tplButton('<span class=\"note-fontsize-10\">50%</span>', {\n          title: lang.image.resizeHalf,\n          event: 'resize',\n          value: '0.5'\n        });\n        var quarterButton = tplButton('<span class=\"note-fontsize-10\">25%</span>', {\n          title: lang.image.resizeQuarter,\n          event: 'resize',\n          value: '0.25'\n        });\n\n        var leftButton = tplIconButton(options.iconPrefix + options.icons.image.floatLeft, {\n          title: lang.image.floatLeft,\n          event: 'floatMe',\n          value: 'left'\n        });\n        var rightButton = tplIconButton(options.iconPrefix + options.icons.image.floatRight, {\n          title: lang.image.floatRight,\n          event: 'floatMe',\n          value: 'right'\n        });\n        var justifyButton = tplIconButton(options.iconPrefix + options.icons.image.floatNone, {\n          title: lang.image.floatNone,\n          event: 'floatMe',\n          value: 'none'\n        });\n\n        var roundedButton = tplIconButton(options.iconPrefix + options.icons.image.shapeRounded, {\n          title: lang.image.shapeRounded,\n          event: 'imageShape',\n          value: 'img-rounded'\n        });\n        var circleButton = tplIconButton(options.iconPrefix + options.icons.image.shapeCircle, {\n          title: lang.image.shapeCircle,\n          event: 'imageShape',\n          value: 'img-circle'\n        });\n        var thumbnailButton = tplIconButton(options.iconPrefix + options.icons.image.shapeThumbnail, {\n          title: lang.image.shapeThumbnail,\n          event: 'imageShape',\n          value: 'img-thumbnail'\n        });\n        var noneButton = tplIconButton(options.iconPrefix + options.icons.image.shapeNone, {\n          title: lang.image.shapeNone,\n          event: 'imageShape',\n          value: ''\n        });\n\n        var removeButton = tplIconButton(options.iconPrefix + options.icons.image.remove, {\n          title: lang.image.remove,\n          event: 'removeMedia',\n          value: 'none'\n        });\n\n        var content = (options.disableResizeImage ? '' : '<div class=\"btn-group\">' + fullButton + halfButton + quarterButton + '</div>') +\n                      '<div class=\"btn-group\">' + leftButton + rightButton + justifyButton + '</div><br>' +\n                      '<div class=\"btn-group\">' + roundedButton + circleButton + thumbnailButton + noneButton + '</div>' +\n                      '<div class=\"btn-group\">' + removeButton + '</div>';\n        return tplPopover('note-image-popover', content);\n      };\n\n      var tplAirPopover = function () {\n        var $content = $('<div />');\n        for (var idx = 0, len = options.airPopover.length; idx < len; idx ++) {\n          var group = options.airPopover[idx];\n\n          var $group = $('<div class=\"note-' + group[0] + ' btn-group\">');\n          for (var i = 0, lenGroup = group[1].length; i < lenGroup; i++) {\n            var $button = $(tplButtonInfo[group[1][i]](lang, options));\n\n            $button.attr('data-name', group[1][i]);\n\n            $group.append($button);\n          }\n          $content.append($group);\n        }\n\n        return tplPopover('note-air-popover', $content.children());\n      };\n\n      var $notePopover = $('<div class=\"note-popover\" />');\n\n      $notePopover.append(tplLinkPopover());\n      $notePopover.append(tplImagePopover());\n\n      if (options.airMode) {\n        $notePopover.append(tplAirPopover());\n      }\n\n      return $notePopover;\n    };\n\n    var tplHandles = function (options) {\n      return '<div class=\"note-handle\">' +\n               '<div class=\"note-control-selection\">' +\n                 '<div class=\"note-control-selection-bg\"></div>' +\n                 '<div class=\"note-control-holder note-control-nw\"></div>' +\n                 '<div class=\"note-control-holder note-control-ne\"></div>' +\n                 '<div class=\"note-control-holder note-control-sw\"></div>' +\n                 '<div class=\"' +\n                 (options.disableResizeImage ? 'note-control-holder' : 'note-control-sizing') +\n                 ' note-control-se\"></div>' +\n                 (options.disableResizeImage ? '' : '<div class=\"note-control-selection-info\"></div>') +\n               '</div>' +\n             '</div>';\n    };\n\n    /**\n     * shortcut table template\n     * @param {String} title\n     * @param {String} body\n     */\n    var tplShortcut = function (title, keys) {\n      var keyClass = 'note-shortcut-col col-xs-6 note-shortcut-';\n      var body = [];\n\n      for (var i in keys) {\n        if (keys.hasOwnProperty(i)) {\n          body.push(\n            '<div class=\"' + keyClass + 'key\">' + keys[i].kbd + '</div>' +\n            '<div class=\"' + keyClass + 'name\">' + keys[i].text + '</div>'\n            );\n        }\n      }\n\n      return '<div class=\"note-shortcut-row row\"><div class=\"' + keyClass + 'title col-xs-offset-6\">' + title + '</div></div>' +\n             '<div class=\"note-shortcut-row row\">' + body.join('</div><div class=\"note-shortcut-row row\">') + '</div>';\n    };\n\n    var tplShortcutText = function (lang) {\n      var keys = [\n        { kbd: '⌘ + B', text: lang.font.bold },\n        { kbd: '⌘ + I', text: lang.font.italic },\n        { kbd: '⌘ + U', text: lang.font.underline },\n        { kbd: '⌘ + \\\\', text: lang.font.clear }\n      ];\n\n      return tplShortcut(lang.shortcut.textFormatting, keys);\n    };\n\n    var tplShortcutAction = function (lang) {\n      var keys = [\n        { kbd: '⌘ + Z', text: lang.history.undo },\n        { kbd: '⌘ + ⇧ + Z', text: lang.history.redo },\n        { kbd: '⌘ + ]', text: lang.paragraph.indent },\n        { kbd: '⌘ + [', text: lang.paragraph.outdent },\n        { kbd: '⌘ + ENTER', text: lang.hr.insert }\n      ];\n\n      return tplShortcut(lang.shortcut.action, keys);\n    };\n\n    var tplShortcutPara = function (lang) {\n      var keys = [\n        { kbd: '⌘ + ⇧ + L', text: lang.paragraph.left },\n        { kbd: '⌘ + ⇧ + E', text: lang.paragraph.center },\n        { kbd: '⌘ + ⇧ + R', text: lang.paragraph.right },\n        { kbd: '⌘ + ⇧ + J', text: lang.paragraph.justify },\n        { kbd: '⌘ + ⇧ + NUM7', text: lang.lists.ordered },\n        { kbd: '⌘ + ⇧ + NUM8', text: lang.lists.unordered }\n      ];\n\n      return tplShortcut(lang.shortcut.paragraphFormatting, keys);\n    };\n\n    var tplShortcutStyle = function (lang) {\n      var keys = [\n        { kbd: '⌘ + NUM0', text: lang.style.normal },\n        { kbd: '⌘ + NUM1', text: lang.style.h1 },\n        { kbd: '⌘ + NUM2', text: lang.style.h2 },\n        { kbd: '⌘ + NUM3', text: lang.style.h3 },\n        { kbd: '⌘ + NUM4', text: lang.style.h4 },\n        { kbd: '⌘ + NUM5', text: lang.style.h5 },\n        { kbd: '⌘ + NUM6', text: lang.style.h6 }\n      ];\n\n      return tplShortcut(lang.shortcut.documentStyle, keys);\n    };\n\n    var tplExtraShortcuts = function (lang, options) {\n      var extraKeys = options.extraKeys;\n      var keys = [];\n\n      for (var key in extraKeys) {\n        if (extraKeys.hasOwnProperty(key)) {\n          keys.push({ kbd: key, text: extraKeys[key] });\n        }\n      }\n\n      return tplShortcut(lang.shortcut.extraKeys, keys);\n    };\n\n    var tplShortcutTable = function (lang, options) {\n      var colClass = 'class=\"note-shortcut note-shortcut-col col-sm-6 col-xs-12\"';\n      var template = [\n        '<div ' + colClass + '>' + tplShortcutAction(lang, options) + '</div>' +\n        '<div ' + colClass + '>' + tplShortcutText(lang, options) + '</div>',\n        '<div ' + colClass + '>' + tplShortcutStyle(lang, options) + '</div>' +\n        '<div ' + colClass + '>' + tplShortcutPara(lang, options) + '</div>'\n      ];\n\n      if (options.extraKeys) {\n        template.push('<div ' + colClass + '>' + tplExtraShortcuts(lang, options) + '</div>');\n      }\n\n      return '<div class=\"note-shortcut-row row\">' +\n               template.join('</div><div class=\"note-shortcut-row row\">') +\n             '</div>';\n    };\n\n    var replaceMacKeys = function (sHtml) {\n      return sHtml.replace(/⌘/g, 'Ctrl').replace(/⇧/g, 'Shift');\n    };\n\n    var tplDialogInfo = {\n      image: function (lang, options) {\n        var imageLimitation = '';\n        if (options.maximumImageFileSize) {\n          var unit = Math.floor(Math.log(options.maximumImageFileSize) / Math.log(1024));\n          var readableSize = (options.maximumImageFileSize / Math.pow(1024, unit)).toFixed(2) * 1 +\n                             ' ' + ' KMGTP'[unit] + 'B';\n          imageLimitation = '<small>' + lang.image.maximumFileSize + ' : ' + readableSize + '</small>';\n        }\n\n        var body = '<div class=\"form-group row note-group-select-from-files\">' +\n                     '<label>' + lang.image.selectFromFiles + '</label>' +\n                     '<input class=\"note-image-input form-control\" type=\"file\" name=\"files\" accept=\"image/*\" multiple=\"multiple\" />' +\n                     imageLimitation +\n                   '</div>' +\n                   '<div class=\"form-group row\">' +\n                     '<label>' + lang.image.url + '</label>' +\n                     '<input class=\"note-image-url form-control col-md-12\" type=\"text\" />' +\n                   '</div>';\n        var footer = '<button href=\"#\" class=\"btn btn-primary note-image-btn disabled\" disabled>' + lang.image.insert + '</button>';\n        return tplDialog('note-image-dialog', lang.image.insert, body, footer);\n      },\n\n      link: function (lang, options) {\n        var body = '<div class=\"form-group row\">' +\n                     '<label>' + lang.link.textToDisplay + '</label>' +\n                     '<input class=\"note-link-text form-control col-md-12\" type=\"text\" />' +\n                   '</div>' +\n                   '<div class=\"form-group row\">' +\n                     '<label>' + lang.link.url + '</label>' +\n                     '<input class=\"note-link-url form-control col-md-12\" type=\"text\" value=\"http://\" />' +\n                   '</div>' +\n                   (!options.disableLinkTarget ?\n                     '<div class=\"checkbox\">' +\n                       '<label>' + '<input type=\"checkbox\" checked> ' +\n                         lang.link.openInNewWindow +\n                       '</label>' +\n                     '</div>' : ''\n                   );\n        var footer = '<button href=\"#\" class=\"btn btn-primary note-link-btn disabled\" disabled>' + lang.link.insert + '</button>';\n        return tplDialog('note-link-dialog', lang.link.insert, body, footer);\n      },\n\n      help: function (lang, options) {\n        var body = '<a class=\"modal-close pull-right\" aria-hidden=\"true\" tabindex=\"-1\">' + lang.shortcut.close + '</a>' +\n                   '<div class=\"title\">' + lang.shortcut.shortcuts + '</div>' +\n                   (agent.isMac ? tplShortcutTable(lang, options) : replaceMacKeys(tplShortcutTable(lang, options))) +\n                   '<p class=\"text-center\">' +\n                     '<a href=\"//summernote.org/\" target=\"_blank\">Summernote 0.6.16</a> · ' +\n                     '<a href=\"//github.com/summernote/summernote\" target=\"_blank\">Project</a> · ' +\n                     '<a href=\"//github.com/summernote/summernote/issues\" target=\"_blank\">Issues</a>' +\n                   '</p>';\n        return tplDialog('note-help-dialog', '', body, '');\n      }\n    };\n\n    var tplDialogs = function (lang, options) {\n      var dialogs = '';\n\n      $.each(tplDialogInfo, function (idx, tplDialog) {\n        dialogs += tplDialog(lang, options);\n      });\n\n      return '<div class=\"note-dialog\">' + dialogs + '</div>';\n    };\n\n    var tplStatusbar = function () {\n      return '<div class=\"note-resizebar\">' +\n               '<div class=\"note-icon-bar\"></div>' +\n               '<div class=\"note-icon-bar\"></div>' +\n               '<div class=\"note-icon-bar\"></div>' +\n             '</div>';\n    };\n\n    var representShortcut = function (str) {\n      if (agent.isMac) {\n        str = str.replace('CMD', '⌘').replace('SHIFT', '⇧');\n      }\n\n      return str.replace('BACKSLASH', '\\\\')\n                .replace('SLASH', '/')\n                .replace('LEFTBRACKET', '[')\n                .replace('RIGHTBRACKET', ']');\n    };\n\n    /**\n     * createTooltip\n     *\n     * @param {jQuery} $container\n     * @param {Object} keyMap\n     * @param {String} [sPlacement]\n     */\n    var createTooltip = function ($container, keyMap, sPlacement) {\n      var invertedKeyMap = func.invertObject(keyMap);\n      var $buttons = $container.find('button');\n\n      $buttons.each(function (i, elBtn) {\n        var $btn = $(elBtn);\n        var sShortcut = invertedKeyMap[$btn.data('event')];\n        if (sShortcut) {\n          $btn.attr('title', function (i, v) {\n            return v + ' (' + representShortcut(sShortcut) + ')';\n          });\n        }\n      // bootstrap tooltip on btn-group bug\n      // https://github.com/twbs/bootstrap/issues/5687\n      }).tooltip({\n        container: 'body',\n        trigger: 'hover',\n        placement: sPlacement || 'top'\n      }).on('click', function () {\n        $(this).tooltip('hide');\n      });\n    };\n\n    // createPalette\n    var createPalette = function ($container, options) {\n      var colorInfo = options.colors;\n      $container.find('.note-color-palette').each(function () {\n        var $palette = $(this), eventName = $palette.attr('data-target-event');\n        var paletteContents = [];\n        for (var row = 0, lenRow = colorInfo.length; row < lenRow; row++) {\n          var colors = colorInfo[row];\n          var buttons = [];\n          for (var col = 0, lenCol = colors.length; col < lenCol; col++) {\n            var color = colors[col];\n            buttons.push(['<button type=\"button\" class=\"note-color-btn\" style=\"background-color:', color,\n                           ';\" data-event=\"', eventName,\n                           '\" data-value=\"', color,\n                           '\" title=\"', color,\n                           '\" data-toggle=\"button\" tabindex=\"-1\"></button>'].join(''));\n          }\n          paletteContents.push('<div class=\"note-color-row\">' + buttons.join('') + '</div>');\n        }\n        $palette.html(paletteContents.join(''));\n      });\n    };\n\n    /**\n     * create summernote layout (air mode)\n     *\n     * @param {jQuery} $holder\n     * @param {Object} options\n     */\n    this.createLayoutByAirMode = function ($holder, options) {\n      var langInfo = options.langInfo;\n      var keyMap = options.keyMap[agent.isMac ? 'mac' : 'pc'];\n      var id = func.uniqueId();\n\n      $holder.addClass('note-air-editor note-editable panel-body');\n      $holder.attr({\n        'id': 'note-editor-' + id,\n        'contentEditable': true\n      });\n\n      var body = document.body;\n\n      // create Popover\n      var $popover = $(tplPopovers(langInfo, options));\n      $popover.addClass('note-air-layout');\n      $popover.attr('id', 'note-popover-' + id);\n      $popover.appendTo(body);\n      createTooltip($popover, keyMap);\n      createPalette($popover, options);\n\n      // create Handle\n      var $handle = $(tplHandles(options));\n      $handle.addClass('note-air-layout');\n      $handle.attr('id', 'note-handle-' + id);\n      $handle.appendTo(body);\n\n      // create Dialog\n      var $dialog = $(tplDialogs(langInfo, options));\n      $dialog.addClass('note-air-layout');\n      $dialog.attr('id', 'note-dialog-' + id);\n      $dialog.find('button.close, a.modal-close').click(function () {\n        $(this).closest('.modal').modal('hide');\n      });\n      $dialog.appendTo(body);\n    };\n\n    /**\n     * create summernote layout (normal mode)\n     *\n     * @param {jQuery} $holder\n     * @param {Object} options\n     */\n    this.createLayoutByFrame = function ($holder, options) {\n      var langInfo = options.langInfo;\n\n      //01. create Editor\n      var $editor = $('<div class=\"note-editor panel panel-default\" />');\n      if (options.width) {\n        $editor.width(options.width);\n      }\n\n      //02. statusbar (resizebar)\n      if (options.height > 0) {\n        $('<div class=\"note-statusbar\">' + (options.disableResizeEditor ? '' : tplStatusbar()) + '</div>').prependTo($editor);\n      }\n\n      //03 editing area\n      var $editingArea = $('<div class=\"note-editing-area\" />');\n      //03. create editable\n      var isContentEditable = !$holder.is(':disabled');\n      var $editable = $('<div class=\"note-editable panel-body\" contentEditable=\"' + isContentEditable + '\"></div>').prependTo($editingArea);\n      \n      if (options.height) {\n        $editable.height(options.height);\n      }\n      if (options.direction) {\n        $editable.attr('dir', options.direction);\n      }\n      var placeholder = $holder.attr('placeholder') || options.placeholder;\n      if (placeholder) {\n        $editable.attr('data-placeholder', placeholder);\n      }\n\n      $editable.html(dom.html($holder) || dom.emptyPara);\n\n      //031. create codable\n      $('<textarea class=\"note-codable\"></textarea>').prependTo($editingArea);\n\n      //04. create Popover\n      var $popover = $(tplPopovers(langInfo, options)).prependTo($editingArea);\n      createPalette($popover, options);\n      createTooltip($popover, keyMap);\n\n      //05. handle(control selection, ...)\n      $(tplHandles(options)).prependTo($editingArea);\n\n      $editingArea.prependTo($editor);\n\n      //06. create Toolbar\n      var $toolbar = $('<div class=\"note-toolbar panel-heading\" />');\n      for (var idx = 0, len = options.toolbar.length; idx < len; idx ++) {\n        var groupName = options.toolbar[idx][0];\n        var groupButtons = options.toolbar[idx][1];\n\n        var $group = $('<div class=\"note-' + groupName + ' btn-group\" />');\n        for (var i = 0, btnLength = groupButtons.length; i < btnLength; i++) {\n          var buttonInfo = tplButtonInfo[groupButtons[i]];\n          // continue creating toolbar even if a button doesn't exist\n          if (!$.isFunction(buttonInfo)) { continue; }\n\n          var $button = $(buttonInfo(langInfo, options));\n          $button.attr('data-name', groupButtons[i]);  // set button's alias, becuase to get button element from $toolbar\n          $group.append($button);\n        }\n        $toolbar.append($group);\n      }\n\n      var keyMap = options.keyMap[agent.isMac ? 'mac' : 'pc'];\n      createPalette($toolbar, options);\n      createTooltip($toolbar, keyMap, 'bottom');\n      $toolbar.prependTo($editor);\n\n      //07. create Dropzone\n      $('<div class=\"note-dropzone\"><div class=\"note-dropzone-message\"></div></div>').prependTo($editor);\n\n      //08. create Dialog\n      var $dialogContainer = options.dialogsInBody ? $(document.body) : $editor;\n      var $dialog = $(tplDialogs(langInfo, options)).prependTo($dialogContainer);\n      $dialog.find('button.close, a.modal-close').click(function () {\n        $(this).closest('.modal').modal('hide');\n      });\n\n      //09. Editor/Holder switch\n      $editor.insertAfter($holder);\n      $holder.hide();\n    };\n\n    this.hasNoteEditor = function ($holder) {\n      return this.noteEditorFromHolder($holder).length > 0;\n    };\n\n    this.noteEditorFromHolder = function ($holder) {\n      if ($holder.hasClass('note-air-editor')) {\n        return $holder;\n      } else if ($holder.next().hasClass('note-editor')) {\n        return $holder.next();\n      } else {\n        return $();\n      }\n    };\n\n    /**\n     * create summernote layout\n     *\n     * @param {jQuery} $holder\n     * @param {Object} options\n     */\n    this.createLayout = function ($holder, options) {\n      if (options.airMode) {\n        this.createLayoutByAirMode($holder, options);\n      } else {\n        this.createLayoutByFrame($holder, options);\n      }\n    };\n\n    /**\n     * returns layoutInfo from holder\n     *\n     * @param {jQuery} $holder - placeholder\n     * @return {Object}\n     */\n    this.layoutInfoFromHolder = function ($holder) {\n      var $editor = this.noteEditorFromHolder($holder);\n      if (!$editor.length) {\n        return;\n      }\n\n      // connect $holder to $editor\n      $editor.data('holder', $holder);\n\n      return dom.buildLayoutInfo($editor);\n    };\n\n    /**\n     * removeLayout\n     *\n     * @param {jQuery} $holder - placeholder\n     * @param {Object} layoutInfo\n     * @param {Object} options\n     *\n     */\n    this.removeLayout = function ($holder, layoutInfo, options) {\n      if (options.airMode) {\n        $holder.removeClass('note-air-editor note-editable')\n               .removeAttr('id contentEditable');\n\n        layoutInfo.popover().remove();\n        layoutInfo.handle().remove();\n        layoutInfo.dialog().remove();\n      } else {\n        $holder.html(layoutInfo.editable().html());\n\n        if (options.dialogsInBody) {\n          layoutInfo.dialog().remove();\n        }\n        layoutInfo.editor().remove();\n        $holder.show();\n      }\n    };\n\n    /**\n     *\n     * @return {Object}\n     * @return {function(label, options=):string} return.button {@link #tplButton function to make text button}\n     * @return {function(iconClass, options=):string} return.iconButton {@link #tplIconButton function to make icon button}\n     * @return {function(className, title=, body=, footer=):string} return.dialog {@link #tplDialog function to make dialog}\n     */\n    this.getTemplate = function () {\n      return {\n        button: tplButton,\n        iconButton: tplIconButton,\n        dialog: tplDialog\n      };\n    };\n\n    /**\n     * add button information\n     *\n     * @param {String} name button name\n     * @param {Function} buttonInfo function to make button, reference to {@link #tplButton},{@link #tplIconButton}\n     */\n    this.addButtonInfo = function (name, buttonInfo) {\n      tplButtonInfo[name] = buttonInfo;\n    };\n\n    /**\n     *\n     * @param {String} name\n     * @param {Function} dialogInfo function to make dialog, reference to {@link #tplDialog}\n     */\n    this.addDialogInfo = function (name, dialogInfo) {\n      tplDialogInfo[name] = dialogInfo;\n    };\n  };\n\n\n  // jQuery namespace for summernote\n  /**\n   * @class $.summernote \n   * \n   * summernote attribute  \n   * \n   * @mixin defaults\n   * @singleton  \n   * \n   */\n  $.summernote = $.summernote || {};\n\n  // extends default settings\n  //  - $.summernote.version\n  //  - $.summernote.options\n  //  - $.summernote.lang\n  $.extend($.summernote, defaults);\n\n  var renderer = new Renderer();\n  var eventHandler = new EventHandler();\n\n  $.extend($.summernote, {\n    /** @property {Renderer} */\n    renderer: renderer,\n    /** @property {EventHandler} */\n    eventHandler: eventHandler,\n    /** \n     * @property {Object} core \n     * @property {core.agent} core.agent \n     * @property {core.dom} core.dom\n     * @property {core.range} core.range \n     */\n    core: {\n      agent: agent,\n      list : list,\n      dom: dom,\n      range: range\n    },\n    /** \n     * @property {Object} \n     * pluginEvents event list for plugins\n     * event has name and callback function.\n     * \n     * ``` \n     * $.summernote.addPlugin({\n     *     events : {\n     *          'hello' : function(layoutInfo, value, $target) {\n     *              console.log('event name is hello, value is ' + value );\n     *          }\n     *     }     \n     * })\n     * ```\n     * \n     * * event name is data-event property.\n     * * layoutInfo is a summernote layout information.\n     * * value is data-value property.\n     */\n    pluginEvents: {},\n\n    plugins : []\n  });\n\n  /**\n   * @method addPlugin\n   *\n   * add Plugin in Summernote \n   * \n   * Summernote can make a own plugin.\n   *\n   * ### Define plugin\n   * ```\n   * // get template function  \n   * var tmpl = $.summernote.renderer.getTemplate();\n   * \n   * // add a button   \n   * $.summernote.addPlugin({\n   *     buttons : {\n   *        // \"hello\"  is button's namespace.      \n   *        \"hello\" : function(lang, options) {\n   *            // make icon button by template function          \n   *            return tmpl.iconButton(options.iconPrefix + 'header', {\n   *                // callback function name when button clicked \n   *                event : 'hello',\n   *                // set data-value property                 \n   *                value : 'hello',                \n   *                hide : true\n   *            });           \n   *        }\n   *     \n   *     }, \n   *     \n   *     events : {\n   *        \"hello\" : function(layoutInfo, value) {\n   *            // here is event code \n   *        }\n   *     }     \n   * });\n   * ``` \n   * ### Use a plugin in toolbar\n   * \n   * ``` \n   *    $(\"#editor\").summernote({\n   *    ...\n   *    toolbar : [\n   *        // display hello plugin in toolbar     \n   *        ['group', [ 'hello' ]]\n   *    ]\n   *    ...    \n   *    });\n   * ```\n   *  \n   *  \n   * @param {Object} plugin\n   * @param {Object} [plugin.buttons] define plugin button. for detail, see to Renderer.addButtonInfo\n   * @param {Object} [plugin.dialogs] define plugin dialog. for detail, see to Renderer.addDialogInfo\n   * @param {Object} [plugin.events] add event in $.summernote.pluginEvents \n   * @param {Object} [plugin.langs] update $.summernote.lang\n   * @param {Object} [plugin.options] update $.summernote.options\n   */\n  $.summernote.addPlugin = function (plugin) {\n\n    // save plugin list\n    $.summernote.plugins.push(plugin);\n\n    if (plugin.buttons) {\n      $.each(plugin.buttons, function (name, button) {\n        renderer.addButtonInfo(name, button);\n      });\n    }\n\n    if (plugin.dialogs) {\n      $.each(plugin.dialogs, function (name, dialog) {\n        renderer.addDialogInfo(name, dialog);\n      });\n    }\n\n    if (plugin.events) {\n      $.each(plugin.events, function (name, event) {\n        $.summernote.pluginEvents[name] = event;\n      });\n    }\n\n    if (plugin.langs) {\n      $.each(plugin.langs, function (locale, lang) {\n        if ($.summernote.lang[locale]) {\n          $.extend($.summernote.lang[locale], lang);\n        }\n      });\n    }\n\n    if (plugin.options) {\n      $.extend($.summernote.options, plugin.options);\n    }\n  };\n\n  /*\n   * extend $.fn\n   */\n  $.fn.extend({\n    /**\n     * @method\n     * Initialize summernote\n     *  - create editor layout and attach Mouse and keyboard events.\n     * \n     * ```\n     * $(\"#summernote\").summernote( { options ..} );\n     * ```\n     *   \n     * @member $.fn\n     * @param {Object|String} options reference to $.summernote.options\n     * @return {this}\n     */\n    summernote: function () {\n      // check first argument's type\n      //  - {String}: External API call {{module}}.{{method}}\n      //  - {Object}: init options\n      var type = $.type(list.head(arguments));\n      var isExternalAPICalled = type === 'string';\n      var hasInitOptions = type === 'object';\n\n      // extend default options with custom user options\n      var options = hasInitOptions ? list.head(arguments) : {};\n\n      options = $.extend({}, $.summernote.options, options);\n      options.icons = $.extend({}, $.summernote.options.icons, options.icons);\n\n      // Include langInfo in options for later use, e.g. for image drag-n-drop\n      // Setup language info with en-US as default\n      options.langInfo = $.extend(true, {}, $.summernote.lang['en-US'], $.summernote.lang[options.lang]);\n\n      // override plugin options\n      if (!isExternalAPICalled && hasInitOptions) {\n        for (var i = 0, len = $.summernote.plugins.length; i < len; i++) {\n          var plugin = $.summernote.plugins[i];\n\n          if (options.plugin[plugin.name]) {\n            $.summernote.plugins[i] = $.extend(true, plugin, options.plugin[plugin.name]);\n          }\n        }\n      }\n\n      this.each(function (idx, holder) {\n        var $holder = $(holder);\n\n        // if layout isn't created yet, createLayout and attach events\n        if (!renderer.hasNoteEditor($holder)) {\n          renderer.createLayout($holder, options);\n\n          var layoutInfo = renderer.layoutInfoFromHolder($holder);\n          $holder.data('layoutInfo', layoutInfo);\n\n          eventHandler.attach(layoutInfo, options);\n          eventHandler.attachCustomEvent(layoutInfo, options);\n        }\n      });\n\n      var $first = this.first();\n      if ($first.length) {\n        var layoutInfo = renderer.layoutInfoFromHolder($first);\n\n        // external API\n        if (isExternalAPICalled) {\n          var moduleAndMethod = list.head(list.from(arguments));\n          var args = list.tail(list.from(arguments));\n\n          // TODO now external API only works for editor\n          var params = [moduleAndMethod, layoutInfo.editable()].concat(args);\n          return eventHandler.invoke.apply(eventHandler, params);\n        } else if (options.focus) {\n          // focus on first editable element for initialize editor\n          layoutInfo.editable().focus();\n        }\n      }\n\n      return this;\n    },\n\n    /**\n     * @method \n     * \n     * get the HTML contents of note or set the HTML contents of note.\n     *\n     * * get contents \n     * ```\n     * var content = $(\"#summernote\").code();\n     * ```\n     * * set contents \n     *\n     * ```\n     * $(\"#summernote\").code(html);\n     * ```\n     *\n     * @member $.fn \n     * @param {String} [html] - HTML contents(optional, set)\n     * @return {this|String} - context(set) or HTML contents of note(get).\n     */\n    code: function (html) {\n      // get the HTML contents of note\n      if (html === undefined) {\n        var $holder = this.first();\n        if (!$holder.length) {\n          return;\n        }\n\n        var layoutInfo = renderer.layoutInfoFromHolder($holder);\n        var $editable = layoutInfo && layoutInfo.editable();\n\n        if ($editable && $editable.length) {\n          var isCodeview = eventHandler.invoke('codeview.isActivated', layoutInfo);\n          eventHandler.invoke('codeview.sync', layoutInfo);\n          return isCodeview ? layoutInfo.codable().val() :\n                              layoutInfo.editable().html();\n        }\n        return dom.value($holder);\n      }\n\n      // set the HTML contents of note\n      this.each(function (i, holder) {\n        var layoutInfo = renderer.layoutInfoFromHolder($(holder));\n        var $editable = layoutInfo && layoutInfo.editable();\n        if ($editable) {\n          $editable.html(html);\n        }\n      });\n\n      return this;\n    },\n\n    /**\n     * @method\n     * \n     * destroy Editor Layout and detach Key and Mouse Event\n     *\n     * @member $.fn\n     * @return {this}\n     */\n    destroy: function () {\n      this.each(function (idx, holder) {\n        var $holder = $(holder);\n\n        if (!renderer.hasNoteEditor($holder)) {\n          return;\n        }\n\n        var info = renderer.layoutInfoFromHolder($holder);\n        var options = info.editor().data('options');\n\n        eventHandler.detach(info, options);\n        renderer.removeLayout($holder, info, options);\n      });\n\n      return this;\n    }\n  });\n}));\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-ar-AR.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'ar-AR': {\n      font: {\n        bold: 'عريض',\n        italic: 'مائل',\n        underline: 'تحته خط',\n        clear: 'مسح التنسيق',\n        height: 'إرتفاع السطر',\n        name: 'الخط',\n        strikethrough: 'فى وسطه خط',\n        size: 'الحجم'\n      },\n      image: {\n        image: 'صورة',\n        insert: 'إضافة صورة',\n        resizeFull: 'الحجم بالكامل',\n        resizeHalf: 'تصغير للنصف',\n        resizeQuarter: 'تصغير للربع',\n        floatLeft: 'تطيير لليسار',\n        floatRight: 'تطيير لليمين',\n        floatNone: 'ثابته',\n        dragImageHere: 'إدرج الصورة هنا',\n        selectFromFiles: 'حدد ملف',\n        url: 'رابط الصورة',\n        remove: 'حذف الصورة'\n      },\n      link: {\n        link: 'رابط رابط',\n        insert: 'إدراج',\n        unlink: 'حذف الرابط',\n        edit: 'تعديل',\n        textToDisplay: 'النص',\n        url: 'مسار الرابط',\n        openInNewWindow: 'فتح في نافذة جديدة'\n      },\n      table: {\n        table: 'جدول'\n      },\n      hr: {\n        insert: 'إدراج خط أفقي'\n      },\n      style: {\n        style: 'تنسيق',\n        normal: 'عادي',\n        blockquote: 'إقتباس',\n        pre: 'شفيرة',\n        h1: 'عنوان رئيسي 1',\n        h2: 'عنوان رئيسي 2',\n        h3: 'عنوان رئيسي 3',\n        h4: 'عنوان رئيسي 4',\n        h5: 'عنوان رئيسي 5',\n        h6: 'عنوان رئيسي 6'\n      },\n      lists: {\n        unordered: 'قائمة مُنقطة',\n        ordered: 'قائمة مُرقمة'\n      },\n      options: {\n        help: 'مساعدة',\n        fullscreen: 'حجم الشاشة بالكامل',\n        codeview: 'شفيرة المصدر'\n      },\n      paragraph: {\n        paragraph: 'فقرة',\n        outdent: 'محاذاة للخارج',\n        indent: 'محاذاة للداخل',\n        left: 'محاذاة لليسار',\n        center: 'توسيط',\n        right: 'محاذاة لليمين',\n        justify: 'ملئ السطر'\n      },\n      color: {\n        recent: 'تم إستخدامه',\n        more: 'المزيد',\n        background: 'لون الخلفية',\n        foreground: 'لون النص',\n        transparent: 'شفاف',\n        setTransparent: 'بدون خلفية',\n        reset: 'إعادة الضبط',\n        resetToDefault: 'إعادة الضبط'\n      },\n      shortcut: {\n        shortcuts: 'إختصارات',\n        close: 'غلق',\n        textFormatting: 'تنسيق النص',\n        action: 'Action',\n        paragraphFormatting: 'تنسيق الفقرة',\n        documentStyle: 'تنسيق المستند'\n      },\n      history: {\n        undo: 'تراجع',\n        redo: 'إعادة'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-bg-BG.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'bg-BG': {\n      font: {\n        bold: 'Удебелен',\n        italic: 'Наклонен',\n        underline: 'Подчертан',\n        clear: 'Изчисти стиловете',\n        height: 'Височина',\n        name: 'Шрифт',\n        strikethrough: 'Задраскано',\n        subscript: 'Долен индекс',\n        superscript: 'Горен индекс',\n        size: 'Размер на шрифта'\n      },\n      image: {\n        image: 'Изображение',\n        insert: 'Постави картинка',\n        resizeFull: 'Цял размер',\n        resizeHalf: 'Размер на 50%',\n        resizeQuarter: 'Размер на 25%',\n        floatLeft: 'Подравни в ляво',\n        floatRight: 'Подравни в дясно',\n        floatNone: 'Без подравняване',\n        dragImageHere: 'Пуснете изображението тук',\n        selectFromFiles: 'Изберете файл',\n        url: 'URL адрес на изображение',\n        remove: 'Премахни изображение'\n      },\n      link: {\n        link: 'Връзка',\n        insert: 'Добави връзка',\n        unlink: 'Премахни връзка',\n        edit: 'Промени',\n        textToDisplay: 'Текст за показване',\n        url: 'URL адрес',\n        openInNewWindow: 'Отвори в нов прозорец'\n      },\n      table: {\n        table: 'Таблица'\n      },\n      hr: {\n        insert: 'Добави хоризонтална линия'\n      },\n      style: {\n        style: 'Стил',\n        normal: 'Нормален',\n        blockquote: 'Цитат',\n        pre: 'Код',\n        h1: 'Заглавие 1',\n        h2: 'Заглавие 2',\n        h3: 'Заглавие 3',\n        h4: 'Заглавие 4',\n        h5: 'Заглавие 5',\n        h6: 'Заглавие 6'\n      },\n      lists: {\n        unordered: 'Символен списък',\n        ordered: 'Цифров списък'\n      },\n      options: {\n        help: 'Помощ',\n        fullscreen: 'На цял екран',\n        codeview: 'Преглед на код'\n      },\n      paragraph: {\n        paragraph: 'Параграф',\n        outdent: 'Намаляване на отстъпа',\n        indent: 'Абзац',\n        left: 'Подравняване в ляво',\n        center: 'Център',\n        right: 'Подравняване в дясно',\n        justify: 'Разтягане по ширина'\n      },\n      color: {\n        recent: 'Последния избран цвят',\n        more: 'Още цветове',\n        background: 'Цвят на фона',\n        foreground: 'Цвят на шрифта',\n        transparent: 'Прозрачен',\n        setTransparent: 'Направете прозрачен',\n        reset: 'Възстанови',\n        resetToDefault: 'Възстанови оригиналните'\n      },\n      shortcut: {\n        shortcuts: 'Клавишни комбинации',\n        close: 'Затвори',\n        textFormatting: 'Форматиране на текста',\n        action: 'Действие',\n        paragraphFormatting: 'Форматиране на параграф',\n        documentStyle: 'Стил на документа'\n      },\n      history: {\n        undo: 'Назад',\n        redo: 'Напред'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-ca-ES.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'ca-ES': {\n      font: {\n        bold: 'Negreta',\n        italic: 'Cursiva',\n        underline: 'Subratllat',\n        clear: 'Treure estil de lletra',\n        height: 'Alçada de línia',\n        strikethrough: 'Ratllat',\n        size: 'Mida de lletra'\n      },\n      image: {\n        image: 'Imatge',\n        insert: 'Inserir imatge',\n        resizeFull: 'Redimensionar a mida completa',\n        resizeHalf: 'Redimensionar a la meitat',\n        resizeQuarter: 'Redimensionar a un quart',\n        floatLeft: 'Surar a l%27esquerra',\n        floatRight: 'Surar a la dreta',\n        floatNone: 'No surar',\n        dragImageHere: 'Arrossegueu una imatge aquí',\n        selectFromFiles: 'Seleccioneu des dels arxius',\n        url: 'URL de la imatge'\n      },\n      link: {\n        link: 'Enllaç',\n        insert: 'Inserir enllaç',\n        unlink: 'Treure enllaç',\n        edit: 'Editar',\n        textToDisplay: 'Text per mostrar',\n        url: 'Cap a quina URL porta l\\'enllaç?',\n        openInNewWindow: 'Obrir en una finestra nova'\n      },\n      table: {\n        table: 'Taula'\n      },\n      hr: {\n        insert: 'Inserir línia horitzontal'\n      },\n      style: {\n        style: 'Estil',\n        normal: 'Normal',\n        blockquote: 'Cita',\n        pre: 'Codi',\n        h1: 'Títol 1',\n        h2: 'Títol 2',\n        h3: 'Títol 3',\n        h4: 'Títol 4',\n        h5: 'Títol 5',\n        h6: 'Títol 6'\n      },\n      lists: {\n        unordered: 'Llista desendreçada',\n        ordered: 'Llista endreçada'\n      },\n      options: {\n        help: 'Ajut',\n        fullscreen: 'Pantalla sencera',\n        codeview: 'Veure codi font'\n      },\n      paragraph: {\n        paragraph: 'Paràgraf',\n        outdent: 'Menys tabulació',\n        indent: 'Més tabulació',\n        left: 'Alinear a l\\'esquerra',\n        center: 'Alinear al mig',\n        right: 'Alinear a la dreta',\n        justify: 'Justificar'\n      },\n      color: {\n        recent: 'Últim color',\n        more: 'Més colors',\n        background: 'Color de fons',\n        foreground: 'Color de lletra',\n        transparent: 'Transparent',\n        setTransparent: 'Establir transparent',\n        reset: 'Restablir',\n        resetToDefault: 'Restablir per defecte'\n      },\n      shortcut: {\n        shortcuts: 'Dreceres de teclat',\n        close: 'Tancar',\n        textFormatting: 'Format de text',\n        action: 'Acció',\n        paragraphFormatting: 'Format de paràgraf',\n        documentStyle: 'Estil del document'\n      },\n      history: {\n        undo: 'Desfer',\n        redo: 'Refer'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-cs-CZ.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'cs-CZ': {\n      font: {\n        bold: 'Tučné',\n        italic: 'Kurzíva',\n        underline: 'Podtržené',\n        clear: 'Odstranit styl písma',\n        height: 'Výška řádku',\n        strikethrough: 'Přeškrtnuté',\n        size: 'Velikost písma'\n      },\n      image: {\n        image: 'Obrázek',\n        insert: 'Vložit obrázek',\n        resizeFull: 'Původní velikost',\n        resizeHalf: 'Poloviční velikost',\n        resizeQuarter: 'Čtvrteční velikost',\n        floatLeft: 'Umístit doleva',\n        floatRight: 'Umístit doprava',\n        floatNone: 'Neobtékat textem',\n        dragImageHere: 'Přetáhnout sem obrázek',\n        selectFromFiles: 'Vybrat soubor',\n        url: 'URL obrázku'\n      },\n      link: {\n        link: 'Odkaz',\n        insert: 'Vytvořit odkaz',\n        unlink: 'Zrušit odkaz',\n        edit: 'Upravit',\n        textToDisplay: 'Zobrazovaný text',\n        url: 'Na jaké URL má tento odkaz vést?',\n        openInNewWindow: 'Otevřít v novém okně'\n      },\n      table: {\n        table: 'Tabulka'\n      },\n      hr: {\n        insert: 'Vložit vodorovnou čáru'\n      },\n      style: {\n        style: 'Styl',\n        normal: 'Normální',\n        blockquote: 'Citace',\n        pre: 'Kód',\n        h1: 'Nadpis 1',\n        h2: 'Nadpis 2',\n        h3: 'Nadpis 3',\n        h4: 'Nadpis 4',\n        h5: 'Nadpis 5',\n        h6: 'Nadpis 6'\n      },\n      lists: {\n        unordered: 'Odrážkový seznam',\n        ordered: 'Číselný seznam'\n      },\n      options: {\n        help: 'Nápověda',\n        fullscreen: 'Celá obrazovka',\n        codeview: 'HTML kód'\n      },\n      paragraph: {\n        paragraph: 'Odstavec',\n        outdent: 'Zvětšit odsazení',\n        indent: 'Zmenšit odsazení',\n        left: 'Zarovnat doleva',\n        center: 'Zarovnat na střed',\n        right: 'Zarovnat doprava',\n        justify: 'Zarovnat oboustranně'\n      },\n      color: {\n        recent: 'Aktuální barva',\n        more: 'Další barvy',\n        background: 'Barva pozadí',\n        foreground: 'Barva písma',\n        transparent: 'Průhlednost',\n        setTransparent: 'Nastavit průhlednost',\n        reset: 'Obnovit',\n        resetToDefault: 'Obnovit výchozí'\n      },\n      shortcut: {\n        shortcuts: 'Klávesové zkratky',\n        close: 'Zavřít',\n        textFormatting: 'Formátování textu',\n        action: 'Akce',\n        paragraphFormatting: 'Formátování odstavce',\n        documentStyle: 'Styl dokumentu'\n      },\n      history: {\n        undo: 'Krok vzad',\n        redo: 'Krok vpřed'\n      }\n\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-da-DK.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'da-DK': {\n      font: {\n        bold: 'Fed',\n        italic: 'Kursiv',\n        underline: 'Understreget',\n        clear: 'Fjern formatering',\n        height: 'Højde',\n        name: 'Skrifttype',\n        strikethrough: 'Gennemstreget',\n        subscript: 'Sænket skrift',\n        superscript: 'Hævet skrift',\n        size: 'Skriftstørrelse'\n      },\n      image: {\n        image: 'Billede',\n        insert: 'Indsæt billede',\n        resizeFull: 'Original størrelse',\n        resizeHalf: 'Halv størrelse',\n        resizeQuarter: 'Kvart størrelse',\n        floatLeft: 'Venstrestillet',\n        floatRight: 'Højrestillet',\n        floatNone: 'Fjern formatering',\n        shapeRounded: 'Form: Runde kanter',\n        shapeCircle: 'Form: Cirkel',\n        shapeThumbnail: 'Form: Miniature',\n        shapeNone: 'Form: Ingen',\n        dragImageHere: 'Træk billede hertil',\n        dropImage: 'Slip billede',\n        selectFromFiles: 'Vælg billed-fil',\n        maximumFileSize: 'Maks fil størrelse',\n        maximumFileSizeError: 'Filen er større end maks tilladte fil størrelse!',\n        url: 'Billede URL',\n        remove: 'Fjern billede'\n      },\n      link: {\n        link: 'Link',\n        insert: 'Indsæt link',\n        unlink: 'Fjern link',\n        edit: 'Rediger',\n        textToDisplay: 'Visningstekst',\n        url: 'Hvor skal linket pege hen?',\n        openInNewWindow: 'Åbn i nyt vindue'\n      },\n      table: {\n        table: 'Tabel'\n      },\n      hr: {\n        insert: 'Indsæt horisontal linje'\n      },\n      style: {\n        style: 'Stil',\n        normal: 'Normal',\n        blockquote: 'Citat',\n        pre: 'Kode',\n        h1: 'Overskrift 1',\n        h2: 'Overskrift 2',\n        h3: 'Overskrift 3',\n        h4: 'Overskrift 4',\n        h5: 'Overskrift 5',\n        h6: 'Overskrift 6'\n      },\n      lists: {\n        unordered: 'Punktopstillet liste',\n        ordered: 'Nummereret liste'\n      },\n      options: {\n        help: 'Hjælp',\n        fullscreen: 'Fuld skærm',\n        codeview: 'HTML-Visning'\n      },\n      paragraph: {\n        paragraph: 'Afsnit',\n        outdent: 'Formindsk indryk',\n        indent: 'Forøg indryk',\n        left: 'Venstrestillet',\n        center: 'Centreret',\n        right: 'Højrestillet',\n        justify: 'Blokjuster'\n      },\n      color: {\n        recent: 'Nyligt valgt farve',\n        more: 'Flere farver',\n        background: 'Baggrund',\n        foreground: 'Forgrund',\n        transparent: 'Transparent',\n        setTransparent: 'Sæt transparent',\n        reset: 'Nulstil',\n        resetToDefault: 'Gendan standardindstillinger'\n      },\n      shortcut: {\n        shortcuts: 'Genveje',\n        close: 'Luk',\n        textFormatting: 'Tekstformatering',\n        action: 'Handling',\n        paragraphFormatting: 'Afsnitsformatering',\n        documentStyle: 'Dokumentstil'\n      },\n      history: {\n        undo: 'Fortryd',\n        redo: 'Annuller fortryd'\n      }\n\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-de-DE.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'de-DE': {\n      font: {\n        bold: 'Fett',\n        italic: 'Kursiv',\n        underline: 'Unterstreichen',\n        clear: 'Zurücksetzen',\n        height: 'Zeilenhöhe',\n        strikethrough: 'Durchgestrichen',\n        size: 'Schriftgröße'\n      },\n      image: {\n        image: 'Grafik',\n        insert: 'Grafik einfügen',\n        resizeFull: 'Originalgröße',\n        resizeHalf: 'Größe 1/2',\n        resizeQuarter: 'Größe 1/4',\n        floatLeft: 'Linksbündig',\n        floatRight: 'Rechtsbündig',\n        floatNone: 'Kein Textfluss',\n        shapeRounded: 'Rahmen: Abgerundet',\n        shapeCircle: 'Rahmen: Kreisförmig',\n        shapeThumbnail: 'Rahmen: Thumbnail',\n        shapeNone: 'Kein Rahmen',\n        dragImageHere: 'Ziehen Sie ein Bild mit der Maus hierher',\n        selectFromFiles: 'Wählen Sie eine Datei aus',\n        maximumFileSize: 'Maximale Dateigröße',\n        maximumFileSizeError: 'Maximale Dateigröße überschritten',\n        url: 'Grafik URL',\n        remove: 'Grafik entfernen'\n      },\n      link: {\n        link: 'Link',\n        insert: 'Link einfügen',\n        unlink: 'Link entfernen',\n        edit: 'Editieren',\n        textToDisplay: 'Anzeigetext',\n        url: 'Ziel des Links?',\n        openInNewWindow: 'In einem neuen Fenster öffnen'\n      },\n      table: {\n        table: 'Tabelle'\n      },\n      hr: {\n        insert: 'Eine horizontale Linie einfügen'\n      },\n      style: {\n        style: 'Stil',\n        normal: 'Normal',\n        blockquote: 'Zitat',\n        pre: 'Quellcode',\n        h1: 'Überschrift 1',\n        h2: 'Überschrift 2',\n        h3: 'Überschrift 3',\n        h4: 'Überschrift 4',\n        h5: 'Überschrift 5',\n        h6: 'Überschrift 6'\n      },\n      lists: {\n        unordered: 'Aufzählung',\n        ordered: 'Nummerierung'\n      },\n      options: {\n        help: 'Hilfe',\n        fullscreen: 'Vollbild',\n        codeview: 'HTML-Code anzeigen'\n      },\n      paragraph: {\n        paragraph: 'Absatz',\n        outdent: 'Einzug vergrößern',\n        indent: 'Einzug verkleinern',\n        left: 'Links ausrichten',\n        center: 'Zentriert ausrichten',\n        right: 'Rechts ausrichten',\n        justify: 'Blocksatz'\n      },\n      color: {\n        recent: 'Letzte Farbe',\n        more: 'Mehr Farben',\n        background: 'Hintergrundfarbe',\n        foreground: 'Schriftfarbe',\n        transparent: 'Transparenz',\n        setTransparent: 'Transparenz setzen',\n        reset: 'Zurücksetzen',\n        resetToDefault: 'Auf Standard zurücksetzen'\n      },\n      shortcut: {\n        shortcuts: 'Tastenkürzel',\n        close: 'Schließen',\n        textFormatting: 'Textformatierung',\n        action: 'Aktion',\n        paragraphFormatting: 'Absatzformatierung',\n        documentStyle: 'Dokumentenstil'\n      },\n      history: {\n        undo: 'Rückgängig',\n        redo: 'Wiederholen'\n      }\n\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-es-ES.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'es-ES': {\n      font: {\n        bold: 'Negrita',\n        italic: 'Cursiva',\n        underline: 'Subrayado',\n        clear: 'Quitar estilo de fuente',\n        height: 'Altura de línea',\n        name: 'Fuente',\n        strikethrough: 'Tachado',\n        superscript: 'Superíndice',\n        subscript: 'Subíndice',\n        size: 'Tamaño de la fuente'\n      },\n      image: {\n        image: 'Imagen',\n        insert: 'Insertar imagen',\n        resizeFull: 'Redimensionar a tamaño completo',\n        resizeHalf: 'Redimensionar a la mitad',\n        resizeQuarter: 'Redimensionar a un cuarto',\n        floatLeft: 'Flotar a la izquierda',\n        floatRight: 'Flotar a la derecha',\n        floatNone: 'No flotar',\n        dragImageHere: 'Arrastrar una imagen aquí',\n        selectFromFiles: 'Seleccionar desde los archivos',\n        url: 'URL de la imagen'\n      },\n      link: {\n        link: 'Link',\n        insert: 'Insertar link',\n        unlink: 'Quitar link',\n        edit: 'Editar',\n        textToDisplay: 'Texto para mostrar',\n        url: '¿Hacia que URL lleva el link?',\n        openInNewWindow: 'Abrir en una nueva ventana'\n      },\n      table: {\n        table: 'Tabla'\n      },\n      hr: {\n        insert: 'Insertar línea horizontal'\n      },\n      style: {\n        style: 'Estilo',\n        normal: 'Normal',\n        blockquote: 'Cita',\n        pre: 'Código',\n        h1: 'Título 1',\n        h2: 'Título 2',\n        h3: 'Título 3',\n        h4: 'Título 4',\n        h5: 'Título 5',\n        h6: 'Título 6'\n      },\n      lists: {\n        unordered: 'Lista desordenada',\n        ordered: 'Lista ordenada'\n      },\n      options: {\n        help: 'Ayuda',\n        fullscreen: 'Pantalla completa',\n        codeview: 'Ver código fuente'\n      },\n      paragraph: {\n        paragraph: 'Párrafo',\n        outdent: 'Menos tabulación',\n        indent: 'Más tabulación',\n        left: 'Alinear a la izquierda',\n        center: 'Alinear al centro',\n        right: 'Alinear a la derecha',\n        justify: 'Justificar'\n      },\n      color: {\n        recent: 'Último color',\n        more: 'Más colores',\n        background: 'Color de fondo',\n        foreground: 'Color de fuente',\n        transparent: 'Transparente',\n        setTransparent: 'Establecer transparente',\n        reset: 'Restaurar',\n        resetToDefault: 'Restaurar por defecto'\n      },\n      shortcut: {\n        shortcuts: 'Atajos de teclado',\n        close: 'Cerrar',\n        textFormatting: 'Formato de texto',\n        action: 'Acción',\n        paragraphFormatting: 'Formato de párrafo',\n        documentStyle: 'Estilo de documento'\n      },\n      history: {\n        undo: 'Deshacer',\n        redo: 'Rehacer'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-es-EU.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'es-EU': {\n      font: {\n        bold: 'Lodia',\n        italic: 'Etzana',\n        underline: 'Azpimarratua',\n        clear: 'Estiloa kendu',\n        height: 'Lerro altuera',\n        name: 'Tipografia',\n        strikethrough: 'Marratua',\n        size: 'Letren neurria'\n      },\n      image: {\n        image: 'Irudia',\n        insert: 'Irudi bat txertatu',\n        resizeFull: 'Jatorrizko neurrira aldatu',\n        resizeHalf: 'Neurria erdira aldatu',\n        resizeQuarter: 'Neurria laurdenera aldatu',\n        floatLeft: 'Ezkerrean kokatu',\n        floatRight: 'Eskuinean kokatu',\n        floatNone: 'Kokapenik ez ezarri',\n        dragImageHere: 'Irudi bat ezarri hemen',\n        selectFromFiles: 'Zure fitxategi bat aukeratu',\n        url: 'Irudiaren URL helbidea'\n      },\n      link: {\n        link: 'Esteka',\n        insert: 'Esteka bat txertatu',\n        unlink: 'Esteka ezabatu',\n        edit: 'Editatu',\n        textToDisplay: 'Estekaren testua',\n        url: 'Estekaren URL helbidea',\n        openInNewWindow: 'Leiho berri batean ireki'\n      },\n      table: {\n        table: 'Taula' //Tabla\n      },\n      hr: {\n        insert: 'Marra horizontala txertatu' //Insertar línea horizontal\n      },\n      style: {\n        style: 'Estiloa',\n        normal: 'Normal',\n        blockquote: 'Aipamena',\n        pre: 'Kodea',\n        h1: '1. izenburua',\n        h2: '2. izenburua',\n        h3: '3. izenburua',\n        h4: '4. izenburua',\n        h5: '5. izenburua',\n        h6: '6. izenburua'\n      },\n      lists: {\n        unordered: 'Ordenatu gabeko zerrenda',\n        ordered: 'Zerrenda ordenatua'\n      },\n      options: {\n        help: 'Laguntza',\n        fullscreen: 'Pantaila osoa',\n        codeview: 'Kodea ikusi'\n      },\n      paragraph: {\n        paragraph: 'Paragrafoa',\n        outdent: 'Koska txikiagoa',\n        indent: 'Koska handiagoa',\n        left: 'Ezkerrean kokatu',\n        center: 'Erdian kokatu',\n        right: 'Eskuinean kokatu',\n        justify: 'Justifikatu'\n      },\n      color: {\n        recent: 'Azken kolorea',\n        more: 'Kolore gehiago',\n        background: 'Atzeko planoa',\n        foreground: 'Aurreko planoa',\n        transparent: 'Gardena',\n        setTransparent: 'Gardendu',\n        reset: 'Lehengoratu',\n        resetToDefault: 'Berrezarri lehenetsia'\n      },\n      shortcut: {\n        shortcuts: 'Lasterbideak',\n        close: 'Itxi',\n        textFormatting: 'Testuaren formatua',\n        action: 'Ekintza',\n        paragraphFormatting: 'Paragrafoaren formatua',\n        documentStyle: 'Dokumentuaren estiloa'\n      },\n      history: {\n        undo: 'Desegin',\n        redo: 'Berregin'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-fa-IR.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'fa-IR': {\n      font: {\n        bold: 'درشت',\n        italic: 'خمیده',\n        underline: 'میان خط',\n        clear: 'پاک کردن فرمت فونت',\n        height: 'فاصله ی خطی',\n        name: 'اسم فونت',\n        strikethrough: 'Strike',\n        size: 'اندازه ی فونت'\n      },\n      image: {\n        image: 'تصویر',\n        insert: 'وارد کردن تصویر',\n        resizeFull: 'تغییر به اندازه ی کامل',\n        resizeHalf: 'تغییر به اندازه نصف',\n        resizeQuarter: 'تغییر به اندازه یک چهارم',\n        floatLeft: 'چسباندن به چپ',\n        floatRight: 'چسباندن به راست',\n        floatNone: 'بدون چسبندگی',\n        dragImageHere: 'یک تصویر را اینجا بکشید',\n        selectFromFiles: 'فایل ها را انتخاب کنید',\n        url: 'آدرس تصویر',\n        remove: 'حذف تصویر'\n      },\n      link: {\n        link: 'لینک',\n        insert: 'اضافه کردن لینک',\n        unlink: 'حذف لینک',\n        edit: 'ویرایش',\n        textToDisplay: 'متن جهت نمایش',\n        url: 'این لینک به چه آدرسی باید برود ؟',\n        openInNewWindow: 'در یک پنجره ی جدید باز شود'\n      },\n      table: {\n        table: 'جدول'\n      },\n      hr: {\n        insert: 'افزودن خط افقی'\n      },\n      style: {\n        style: 'استیل',\n        normal: 'نرمال',\n        blockquote: 'نقل قول',\n        pre: 'کد',\n        h1: 'سرتیتر 1',\n        h2: 'سرتیتر 2',\n        h3: 'سرتیتر 3',\n        h4: 'سرتیتر 4',\n        h5: 'سرتیتر 5',\n        h6: 'سرتیتر 6'\n      },\n      lists: {\n        unordered: 'لیست غیر ترتیبی',\n        ordered: 'لیست ترتیبی'\n      },\n      options: {\n        help: 'راهنما',\n        fullscreen: 'نمایش تمام صفحه',\n        codeview: 'مشاهده ی کد'\n      },\n      paragraph: {\n        paragraph: 'پاراگراف',\n        outdent: 'کاهش تو رفتگی',\n        indent: 'افزایش تو رفتگی',\n        left: 'چپ چین',\n        center: 'میان چین',\n        right: 'راست چین',\n        justify: 'بلوک چین'\n      },\n      color: {\n        recent: 'رنگ اخیرا استفاده شده',\n        more: 'رنگ بیشتر',\n        background: 'رنگ پس زمینه',\n        foreground: 'رنگ متن',\n        transparent: 'بی رنگ',\n        setTransparent: 'تنظیم حالت بی رنگ',\n        reset: 'بازنشاندن',\n        resetToDefault: 'حالت پیش فرض'\n      },\n      shortcut: {\n        shortcuts: 'دکمه های میان بر',\n        close: 'بستن',\n        textFormatting: 'فرمت متن',\n        action: 'عملیات',\n        paragraphFormatting: 'فرمت پاراگراف',\n        documentStyle: 'استیل سند'\n      },\n      history: {\n        undo: 'واچیدن',\n        redo: 'بازچیدن'\n      }\n    }\n  });\n})(jQuery);\n\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-fi-FI.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'fi-FI': {\n      font: {\n        bold: 'Lihavoitu',\n        italic: 'Kursiivi',\n        underline: 'Alleviivaa',\n        clear: 'Tyhjennä muotoilu',\n        height: 'Riviväli',\n        name: 'Kirjasintyyppi',\n        strikethrough: 'Yliviivaus',\n        size: 'Kirjasinkoko'\n      },\n      image: {\n        image: 'Kuva',\n        insert: 'Lisää kuva',\n        resizeFull: 'Koko leveys',\n        resizeHalf: 'Puolikas leveys',\n        resizeQuarter: 'Neljäsosa leveys',\n        floatLeft: 'Sijoita vasemmalle',\n        floatRight: 'Sijoita oikealle',\n        floatNone: 'Ei sijoitusta',\n        dragImageHere: 'Vedä kuva tähän',\n        selectFromFiles: 'Valitse tiedostoista',\n        url: 'URL-osoitteen mukaan',\n        remove: 'Poista kuva'\n      },\n      link: {\n        link: 'Linkki',\n        insert: 'Lisää linkki',\n        unlink: 'Poista linkki',\n        edit: 'Muokkaa',\n        textToDisplay: 'Näytettävä teksti',\n        url: 'Linkin URL-osoite?',\n        openInNewWindow: 'Avaa uudessa ikkunassa'\n      },\n      table: {\n        table: 'Taulukko'\n      },\n      hr: {\n        insert: 'Lisää vaakaviiva'\n      },\n      style: {\n        style: 'Tyyli',\n        normal: 'Normaali',\n        blockquote: 'Lainaus',\n        pre: 'Koodi',\n        h1: 'Otsikko 1',\n        h2: 'Otsikko 2',\n        h3: 'Otsikko 3',\n        h4: 'Otsikko 4',\n        h5: 'Otsikko 5',\n        h6: 'Otsikko 6'\n      },\n      lists: {\n        unordered: 'Luettelomerkitty luettelo',\n        ordered: 'Numeroitu luettelo'\n      },\n      options: {\n        help: 'Ohje',\n        fullscreen: 'Koko näyttö',\n        codeview: 'HTML-näkymä'\n      },\n      paragraph: {\n        paragraph: 'Kappale',\n        outdent: 'Pienennä sisennystä',\n        indent: 'Suurenna sisennystä',\n        left: 'Tasaus vasemmalle',\n        center: 'Keskitä',\n        right: 'Tasaus oikealle',\n        justify: 'Tasaa'\n      },\n      color: {\n        recent: 'Viimeisin väri',\n        more: 'Lisää värejä',\n        background: 'Taustaväri',\n        foreground: 'Tekstin väri',\n        transparent: 'Läpinäkyvä',\n        setTransparent: 'Aseta läpinäkyväksi',\n        reset: 'Palauta',\n        resetToDefault: 'Palauta oletusarvoksi'\n      },\n      shortcut: {\n        shortcuts: 'Pikanäppäimet',\n        close: 'Sulje',\n        textFormatting: 'Tekstin muotoilu',\n        action: 'Toiminto',\n        paragraphFormatting: 'Kappaleen muotoilu',\n        documentStyle: 'Asiakirjan tyyli'\n      },\n      history: {\n        undo: 'Kumoa',\n        redo: 'Toista'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-fr-FR.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'fr-FR': {\n      font: {\n        bold: 'Gras',\n        italic: 'Italique',\n        underline: 'Souligné',\n        clear: 'Effacer la mise en forme',\n        height: 'Interligne',\n        name: 'Famille de police',\n        strikethrough: 'Barré',\n        superscript: 'Exposant',\n        subscript: 'Indice',\n        size: 'Taille de police'\n      },\n      image: {\n        image: 'Image',\n        insert: 'Insérer une image',\n        resizeFull: 'Taille originale',\n        resizeHalf: 'Redimensionner à 50 %',\n        resizeQuarter: 'Redimensionner à 25 %',\n        floatLeft: 'Aligné à gauche',\n        floatRight: 'Aligné à droite',\n        floatNone: 'Pas d\\'alignement',\n        shapeRounded: 'Forme: Rectangle arrondie',\n        shapeCircle: 'Forme: Cercle',\n        shapeThumbnail: 'Forme: Vignette',\n        shapeNone: 'Forme: Aucune',\n        dragImageHere: 'Faites glisser une image ou un texte dans ce cadre',\n        dropImage: 'Lachez l\\'image ou le texte',\n        selectFromFiles: 'Choisir un fichier',\n        maximumFileSize: 'Taille de fichier maximale',\n        maximumFileSizeError: 'Taille maximale du fichier dépassée',\n        url: 'URL de l\\'image',\n        remove: 'Supprimer l\\'image'\n      },\n      link: {\n        link: 'Lien',\n        insert: 'Insérer un lien',\n        unlink: 'Supprimer un lien',\n        edit: 'Modifier',\n        textToDisplay: 'Texte à afficher',\n        url: 'URL du lien',\n        openInNewWindow: 'Ouvrir dans une nouvelle fenêtre'\n      },\n      table: {\n        table: 'Tableau'\n      },\n      hr: {\n        insert: 'Insérer une ligne horizontale'\n      },\n      style: {\n        style: 'Style',\n        normal: 'Normal',\n        blockquote: 'Citation',\n        pre: 'Code source',\n        h1: 'Titre 1',\n        h2: 'Titre 2',\n        h3: 'Titre 3',\n        h4: 'Titre 4',\n        h5: 'Titre 5',\n        h6: 'Titre 6'\n      },\n      lists: {\n        unordered: 'Liste à puces',\n        ordered: 'Liste numérotée'\n      },\n      options: {\n        help: 'Aide',\n        fullscreen: 'Plein écran',\n        codeview: 'Afficher le code HTML'\n      },\n      paragraph: {\n        paragraph: 'Paragraphe',\n        outdent: 'Diminuer le retrait',\n        indent: 'Augmenter le retrait',\n        left: 'Aligner à gauche',\n        center: 'Centrer',\n        right: 'Aligner à droite',\n        justify: 'Justifier'\n      },\n      color: {\n        recent: 'Dernière couleur sélectionnée',\n        more: 'Plus de couleurs',\n        background: 'Couleur de fond',\n        foreground: 'Couleur de police',\n        transparent: 'Transparent',\n        setTransparent: 'Définir la transparence',\n        reset: 'Restaurer',\n        resetToDefault: 'Restaurer la couleur par défaut'\n      },\n      shortcut: {\n        shortcuts: 'Raccourcis',\n        close: 'Fermer',\n        textFormatting: 'Mise en forme du texte',\n        action: 'Action',\n        paragraphFormatting: 'Mise en forme des paragraphes',\n        documentStyle: 'Style du document',\n        extraKeys: 'Touches supplémentaires'\n      },\n      history: {\n        undo: 'Annuler la dernière action',\n        redo: 'Restaurer la dernière action annulée'\n      }\n\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-he-IL.js",
    "content": "﻿(function ($) {\n  $.extend($.summernote.lang, {\n    'he-IL': {\n      font: {\n        bold: 'מודגש',\n        italic: 'נטוי',\n        underline: 'קו תחתון',\n        clear: 'נקה עיצוב',\n        height: 'גובה',\n        name: 'גופן',\n        strikethrough: 'קו חוצה',\n        subscript: 'כתב תחתי',\n        superscript: 'כתב עילי',\n        size: 'גודל גופן'\n      },\n      image: {\n        image: 'תמונה',\n        insert: 'הוסף תמונה',\n        resizeFull: 'גודל מלא',\n        resizeHalf: 'להקטין לחצי',\n        resizeQuarter: 'להקטין לרבע',\n        floatLeft: 'יישור לשמאל',\n        floatRight: 'יישור לימין',\n        floatNone: 'ישר',\n        dragImageHere: 'גרור תמונה לכאן',\n        selectFromFiles: 'בחר מתוך קבצים',\n        url: 'נתיב לתמונה',\n        remove: 'הסר תמונה'\n      },\n      link: {\n        link: 'קישור',\n        insert: 'הוסף קישור',\n        unlink: 'הסר קישור',\n        edit: 'ערוך',\n        textToDisplay: 'טקסט להציג',\n        url: 'קישור',\n        openInNewWindow: 'פתח בחלון חדש'\n      },\n      table: {\n        table: 'טבלה'\n      },\n      hr: {\n        insert: 'הוסף קו'\n      },\n      style: {\n        style: 'עיצוב',\n        normal: 'טקסט רגיל',\n        blockquote: 'ציטוט',\n        pre: 'קוד',\n        h1: 'כותרת 1',\n        h2: 'כותרת 2',\n        h3: 'כותרת 3',\n        h4: 'כותרת 4',\n        h5: 'כותרת 5',\n        h6: 'כותרת 6'\n      },\n      lists: {\n        unordered: 'רשימת תבליטים',\n        ordered: 'רשימה ממוספרת'\n      },\n      options: {\n        help: 'עזרה',\n        fullscreen: 'מסך מלא',\n        codeview: 'תצוגת קוד'\n      },\n      paragraph: {\n        paragraph: 'פסקה',\n        outdent: 'הקטן כניסה',\n        indent: 'הגדל כניסה',\n        left: 'יישור לשמאל',\n        center: 'יישור למרכז',\n        right: 'יישור לימין',\n        justify: 'מיושר'\n      },\n      color: {\n        recent: 'צבע טקסט אחרון',\n        more: 'עוד צבעים',\n        background: 'צבע רקע',\n        foreground: 'צבע טקסט',\n        transparent: 'שקוף',\n        setTransparent: 'קבע כשקוף',\n        reset: 'איפוס',\n        resetToDefault: 'אפס לברירת מחדל'\n      },\n      shortcut: {\n        shortcuts: 'קיצורי מקלדת',\n        close: 'סגור',\n        textFormatting: 'עיצוב הטקסט',\n        action: 'פעולה',\n        paragraphFormatting: 'סגנונות פסקה',\n        documentStyle: 'עיצוב המסמך',\n        extraKeys: 'קיצורים נוספים'\n      },\n      history: {\n        undo: 'בטל פעולה',\n        redo: 'בצע שוב'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-hu-HU.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'hu-HU': {\n      font: {\n        bold: 'Félkövér',\n        italic: 'Dőlt',\n        underline: 'Aláhúzott',\n        clear: 'Formázás törlése',\n        height: 'Sorköz',\n        name: 'Betűtípus',\n        strikethrough: 'Áthúzott',\n        size: 'Betűméret'\n      },\n      image: {\n        image: 'Kép',\n        insert: 'Kép beszúrása',\n        resizeFull: 'Átméretezés teljes méretre',\n        resizeHalf: 'Átméretezés felére',\n        resizeQuarter: 'Átméretezés negyedére',\n        floatLeft: 'Igazítás balra',\n        floatRight: 'Igazítás jobbra',\n        floatNone: 'Igazítás törlése',\n        dragImageHere: 'Ide húzhatod a képet',\n        selectFromFiles: 'Fájlok kiválasztása',\n        url: 'Kép URL címe',\n        remove: 'Kép törlése'\n      },\n      link: {\n        link: 'Hivatkozás',\n        insert: 'Hivatkozás beszúrása',\n        unlink: 'Hivatkozás megszüntetése',\n        edit: 'Szerkesztés',\n        textToDisplay: 'Megjelenítendő szöveg',\n        url: 'Milyen URL címre hivatkozzon?',\n        openInNewWindow: 'Megnyitás új ablakban'\n      },\n      table: {\n        table: 'Táblázat'\n      },\n      hr: {\n        insert: 'Elválasztó vonal beszúrása'\n      },\n      style: {\n        style: 'Stílus',\n        normal: 'Normál',\n        blockquote: 'Idézet',\n        pre: 'Kód',\n        h1: 'Fejléc 1',\n        h2: 'Fejléc 2',\n        h3: 'Fejléc 3',\n        h4: 'Fejléc 4',\n        h5: 'Fejléc 5',\n        h6: 'Fejléc 6'\n      },\n      lists: {\n        unordered: 'Listajeles lista',\n        ordered: 'Számozott lista'\n      },\n      options: {\n        help: 'Súgó',\n        fullscreen: 'Teljes képernyő',\n        codeview: 'Kód nézet'\n      },\n      paragraph: {\n        paragraph: 'Bekezdés',\n        outdent: 'Behúzás csökkentése',\n        indent: 'Behúzás növelése',\n        left: 'Igazítás balra',\n        center: 'Igazítás középre',\n        right: 'Igazítás jobbra',\n        justify: 'Sorkizárt'\n      },\n      color: {\n        recent: 'Jelenlegi szín',\n        more: 'További színek',\n        background: 'Háttérszín',\n        foreground: 'Betűszín',\n        transparent: 'Átlátszó',\n        setTransparent: 'Átlászóság beállítása',\n        reset: 'Visszaállítás',\n        resetToDefault: 'Alaphelyzetbe állítás'\n      },\n      shortcut: {\n        shortcuts: 'Gyorsbillentyű',\n        close: 'Bezárás',\n        textFormatting: 'Szöveg formázása',\n        action: 'Művelet',\n        paragraphFormatting: 'Bekezdés formázása',\n        documentStyle: 'Dokumentumstílus'\n      },\n      history: {\n        undo: 'Visszavonás',\n        redo: 'Újra'\n      }\n\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-id-ID.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'id-ID': {\n      font: {\n        bold: 'Tebal',\n        italic: 'Miring',\n        underline: 'Garis bawah',\n        clear: 'Bersihkan gaya',\n        height: 'Jarak baris',\n        strikethrough: 'Coret',\n        size: 'Ukuran font'\n      },\n      image: {\n        image: 'Gambar',\n        insert: 'Sisipkan gambar',\n        resizeFull: 'Ukuran penuh',\n        resizeHalf: 'Ukuran 50%',\n        resizeQuarter: 'Ukuran 25%',\n        floatLeft: 'Rata kiri',\n        floatRight: 'Rata kanan',\n        floatNone: 'Tidak ada perataan',\n        dragImageHere: 'Tarik gambar pada area ini',\n        selectFromFiles: 'Pilih gambar dari berkas',\n        url: 'URL gambar',\n        remove: 'Hapus Gambar'\n      },\n      link: {\n        link: 'Tautan',\n        insert: 'Tambah tautan',\n        unlink: 'Hapus tautan',\n        edit: 'Edit',\n        textToDisplay: 'Tampilan teks',\n        url: 'Tautan tujuan',\n        openInNewWindow: 'Buka di jendela baru'\n      },\n      table: {\n        table: 'Tabel'\n      },\n      hr: {\n        insert: 'Masukkan garis horizontal'\n      },\n      style: {\n        style: 'Gaya',\n        normal: 'Normal',\n        blockquote: 'Kutipan',\n        pre: 'Kode',\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      lists: {\n        unordered: 'Pencacahan',\n        ordered: 'Penomoran'\n      },\n      options: {\n        help: 'Bantuan',\n        fullscreen: 'Layar penuh',\n        codeview: 'Kode HTML'\n      },\n      paragraph: {\n        paragraph: 'Paragraf',\n        outdent: 'Outdent',\n        indent: 'Indent',\n        left: 'Rata kiri',\n        center: 'Rata tengah',\n        right: 'Rata kanan',\n        justify: 'Rata kanan kiri'\n      },\n      color: {\n        recent: 'Warna sekarang',\n        more: 'Selengkapnya',\n        background: 'Warna latar',\n        foreground: 'Warna font',\n        transparent: 'Transparan',\n        setTransparent: 'Atur transparansi',\n        reset: 'Atur ulang',\n        resetToDefault: 'Kembalikan kesemula'\n      },\n      shortcut: {\n        shortcuts: 'Jalan pintas',\n        close: 'Keluar',\n        textFormatting: 'Format teks',\n        action: 'Aksi',\n        paragraphFormatting: 'Format paragraf',\n        documentStyle: 'Gaya dokumen'\n      },\n      history: {\n        undo: 'Kembali',\n        redo: 'Ulang'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-it-IT.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'it-IT': {\n      font: {\n        bold: 'Testo in grassetto',\n        italic: 'Testo in corsivo',\n        underline: 'Testo sottolineato',\n        clear: 'Elimina la formattazione del testo',\n        height: 'Altezza della linea di testo',\n        name: 'Famiglia Font',\n        strikethrough: 'Testo barrato',\n        size: 'Dimensione del carattere'\n      },\n      image: {\n        image: 'Immagine',\n        insert: 'Inserisci Immagine',\n        resizeFull: 'Dimensioni originali',\n        resizeHalf: 'Ridimensiona al 50%',\n        resizeQuarter: 'Ridimensiona al 25%',\n        floatLeft: 'Posiziona a sinistra',\n        floatRight: 'Posiziona a destra',\n        floatNone: 'Nessun posizionamento',\n        dragImageHere: 'Trascina qui un\\'immagine',\n        selectFromFiles: 'Scegli dai Documenti',\n        url: 'URL dell\\'immagine',\n        remove: 'Rimuovi immagine'\n      },\n      link: {\n        link: 'Collegamento',\n        insert: 'Inserisci Collegamento',\n        unlink: 'Elimina collegamento',\n        edit: 'Modifica collegamento',\n        textToDisplay: 'Testo del collegamento',\n        url: 'URL del collegamento',\n        openInNewWindow: 'Apri in una nuova finestra'\n      },\n      table: {\n        table: 'Tabella'\n      },\n      hr: {\n        insert: 'Inserisce una linea di separazione'\n      },\n      style: {\n        style: 'Stili',\n        normal: 'Normale',\n        blockquote: 'Citazione',\n        pre: 'Codice',\n        h1: 'Titolo 1',\n        h2: 'Titolo 2',\n        h3: 'Titolo 3',\n        h4: 'Titolo 4',\n        h5: 'Titolo 5',\n        h6: 'Titolo 6'\n      },\n      lists: {\n        unordered: 'Elenco non ordinato',\n        ordered: 'Elenco ordinato'\n      },\n      options: {\n        help: 'Aiuto',\n        fullscreen: 'Modalità a tutto schermo',\n        codeview: 'Visualizza codice'\n      },\n      paragraph: {\n        paragraph: 'Paragrafo',\n        outdent: 'Diminuisce il livello di rientro',\n        indent: 'Aumenta il livello di rientro',\n        left: 'Allinea a sinistra',\n        center: 'Centra',\n        right: 'Allinea a destra',\n        justify: 'Giustifica (allinea a destra e sinistra)'\n      },\n      color: {\n        recent: 'Ultimo colore utilizzato',\n        more: 'Altri colori',\n        background: 'Colore di sfondo',\n        foreground: 'Colore',\n        transparent: 'Trasparente',\n        setTransparent: 'Trasparente',\n        reset: 'Reimposta',\n        resetToDefault: 'Reimposta i colori'\n      },\n      shortcut: {\n        shortcuts: 'Scorciatoie da tastiera',\n        close: 'Chiudi',\n        textFormatting: 'Formattazione testo',\n        action: 'Azioni',\n        paragraphFormatting: 'Formattazione paragrafo',\n        documentStyle: 'Stili'\n      },\n      history: {\n        undo: 'Annulla',\n        redo: 'Ripristina'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-ja-JP.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'ja-JP': {\n      font: {\n        bold: '太字',\n        italic: '斜体',\n        underline: '下線',\n        clear: 'クリア',\n        height: '文字高',\n        name: 'フォント',\n        strikethrough: '取り消し線',\n        size: '大きさ'\n      },\n      image: {\n        image: '画像',\n        insert: '画像挿入',\n        resizeFull: '最大化',\n        resizeHalf: '1/2',\n        resizeQuarter: '1/4',\n        floatLeft: '左寄せ',\n        floatRight: '右寄せ',\n        floatNone: '寄せ解除',\n        dragImageHere: 'ここに画像をドラッグしてください',\n        selectFromFiles: '画像ファイルを選ぶ',\n        url: 'URLから画像を挿入する',\n        remove: '画像を削除する'\n      },\n      link: {\n        link: 'リンク',\n        insert: 'リンク挿入',\n        unlink: 'リンク解除',\n        edit: '編集',\n        textToDisplay: 'リンク文字列',\n        url: 'URLを入力してください',\n        openInNewWindow: '新しいウィンドウで開く'\n      },\n      table: {\n        table: 'テーブル'\n      },\n      hr: {\n        insert: '水平線の挿入'\n      },\n      style: {\n        style: 'スタイル',\n        normal: '標準',\n        blockquote: '引用',\n        pre: 'コード',\n        h1: '見出し1',\n        h2: '見出し2',\n        h3: '見出し3',\n        h4: '見出し4',\n        h5: '見出し5',\n        h6: '見出し6'\n      },\n      lists: {\n        unordered: '通常リスト',\n        ordered: '番号リスト'\n      },\n      options: {\n        help: 'ヘルプ',\n        fullscreen: 'フルスクリーン',\n        codeview: 'コード表示'\n      },\n      paragraph: {\n        paragraph: '文章',\n        outdent: '字上げ',\n        indent: '字下げ',\n        left: '左寄せ',\n        center: '中央寄せ',\n        right: '右寄せ',\n        justify: '均等割付'\n      },\n      color: {\n        recent: '現在の色',\n        more: 'もっと見る',\n        background: '背景色',\n        foreground: '文字色',\n        transparent: '透過率',\n        setTransparent: '透過率を設定',\n        reset: '標準',\n        resetToDefault: '標準に戻す'\n      },\n      shortcut: {\n        shortcuts: 'ショートカット',\n        close: '閉じる',\n        textFormatting: '文字フォーマット',\n        action: 'アクション',\n        paragraphFormatting: '文章フォーマット',\n        documentStyle: 'ドキュメント形式'\n      },\n      history: {\n        undo: '元に戻す',\n        redo: 'やり直す'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-ko-KR.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'ko-KR': {\n      font: {\n        bold: '굵게',\n        italic: '기울임꼴',\n        underline: '밑줄',\n        clear: '글자 효과 없애기',\n        height: '줄간격',\n        name: '글꼴',\n        superscript: '위 첨자',\n        subscript: '아래 첨자',\n        strikethrough: '취소선',\n        size: '글자 크기'\n      },\n      image: {\n        image: '사진',\n        insert: '사진 추가',\n        resizeFull: '원본 크기로 변경',\n        resizeHalf: '50% 크기로 변경',\n        resizeQuarter: '25% 크기로 변경',\n        floatLeft: '왼쪽 정렬',\n        floatRight: '오른쪽 정렬',\n        floatNone: '정렬하지 않음',\n        shapeRounded: '스타일: 둥근 모서리',\n        shapeCircle: '스타일: 원형',\n        shapeThumbnail: '스타일: 액자',\n        shapeNone: '스타일: 없음',\n        dragImageHere: '사진을 이곳으로 끌어오세요',\n        selectFromFiles: '파일 선택',\n        url: '사진 URL',\n        remove: '사진 삭제'\n      },\n      link: {\n        link: '링크',\n        insert: '링크 추가',\n        unlink: '링크 삭제',\n        edit: '수정',\n        textToDisplay: '링크에 표시할 내용',\n        url: '이동할 URL',\n        openInNewWindow: '새창으로 열기'\n      },\n      table: {\n        table: '테이블'\n      },\n      hr: {\n        insert: '구분선 추가'\n      },\n      style: {\n        style: '스타일',\n        normal: '본문',\n        blockquote: '인용구',\n        pre: '코드',\n        h1: '제목 1',\n        h2: '제목 2',\n        h3: '제목 3',\n        h4: '제목 4',\n        h5: '제목 5',\n        h6: '제목 6'\n      },\n      lists: {\n        unordered: '글머리 기호',\n        ordered: '번호 매기기'\n      },\n      options: {\n        help: '도움말',\n        fullscreen: '전체 화면',\n        codeview: '코드 보기'\n      },\n      paragraph: {\n        paragraph: '문단 정렬',\n        outdent: '내어쓰기',\n        indent: '들여쓰기',\n        left: '왼쪽 정렬',\n        center: '가운데 정렬',\n        right: '오른쪽 정렬',\n        justify: '양쪽 정렬'\n      },\n      color: {\n        recent: '마지막으로 사용한 색',\n        more: '다른 색 선택',\n        background: '배경색',\n        foreground: '글자색',\n        transparent: '투명',\n        setTransparent: '투명',\n        reset: '취소',\n        resetToDefault: '기본 값으로 변경'\n      },\n      shortcut: {\n        shortcuts: '키보드 단축키',\n        close: '닫기',\n        textFormatting: '글자 스타일 적용',\n        action: '기능',\n        paragraphFormatting: '문단 스타일 적용',\n        documentStyle: '문서 스타일 적용'\n      },\n      history: {\n        undo: '실행 취소',\n        redo: '다시 실행'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-lt-LT.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'lt-LT': {\n      font: {\n        bold: 'Paryškintas',\n        italic: 'Kursyvas',\n        underline: 'Pabrėžtas',\n        clear: 'Be formatavimo',\n        height: 'Eilutės aukštis',\n        name: 'Šrifto pavadinimas',\n        strikethrough: 'Perbrauktas',\n        superscript: 'Viršutinis',\n        subscript: 'Indeksas',\n        size: 'Šrifto dydis'\n      },\n      image: {\n        image: 'Paveikslėlis',\n        insert: 'Įterpti paveikslėlį',\n        resizeFull: 'Pilnas dydis',\n        resizeHalf: 'Sumažinti dydį 50%',\n        resizeQuarter: 'Sumažinti dydį 25%',\n        floatLeft: 'Kairinis lygiavimas',\n        floatRight: 'Dešininis lygiavimas',\n        floatNone: 'Jokio lygiavimo',\n        shapeRounded: 'Forma: apvalūs kraštai',\n        shapeCircle: 'Forma: apskritimas',\n        shapeThumbnail: 'Forma: miniatiūra',\n        shapeNone: 'Forma: jokia',\n        dragImageHere: 'Vilkite paveikslėlį čia',\n        selectFromFiles: 'Pasirinkite failą',\n        maximumFileSize: 'Maskimalus failo dydis',\n        maximumFileSizeError: 'Maskimalus failo dydis viršytas!',\n        url: 'Paveikslėlio URL adresas',\n        remove: 'Ištrinti paveikslėlį'\n      },\n      link: {\n        link: 'Nuoroda',\n        insert: 'Įterpti nuorodą',\n        unlink: 'Pašalinti nuorodą',\n        edit: 'Redaguoti',\n        textToDisplay: 'Rodomas tekstas',\n        url: 'Koks URL adresas yra susietas?',\n        openInNewWindow: 'Atidaryti naujame lange'\n      },\n      table: {\n        table: 'Lentelė'\n      },\n      hr: {\n        insert: 'Įterpti horizontalią liniją'\n      },\n      style: {\n        style: 'Stilius',\n        normal: 'Normalus',\n        blockquote: 'Citata',\n        pre: 'Kodas',\n        h1: 'Antraštė 1',\n        h2: 'Antraštė 2',\n        h3: 'Antraštė 3',\n        h4: 'Antraštė 4',\n        h5: 'Antraštė 5',\n        h6: 'Antraštė 6'\n      },\n      lists: {\n        unordered: 'Suženklintasis sąrašas',\n        ordered: 'Sunumeruotas sąrašas'\n      },\n      options: {\n        help: 'Pagalba',\n        fullscreen: 'Viso ekrano režimas',\n        codeview: 'HTML kodo peržiūra'\n      },\n      paragraph: {\n        paragraph: 'Pastraipa',\n        outdent: 'Sumažinti įtrauką',\n        indent: 'Padidinti įtrauką',\n        left: 'Kairinė lygiuotė',\n        center: 'Centrinė lygiuotė',\n        right: 'Dešininė lygiuotė',\n        justify: 'Abipusis išlyginimas'\n      },\n      color: {\n        recent: 'Paskutinė naudota spalva',\n        more: 'Daugiau spalvų',\n        background: 'Fono spalva',\n        foreground: 'Šrifto spalva',\n        transparent: 'Permatoma',\n        setTransparent: 'Nustatyti skaidrumo intensyvumą',\n        reset: 'Atkurti',\n        resetToDefault: 'Atstatyti numatytąją spalvą'\n      },\n      shortcut: {\n        shortcuts: 'Spartieji klavišai',\n        close: 'Uždaryti',\n        textFormatting: 'Teksto formatavimas',\n        action: 'Veiksmas',\n        paragraphFormatting: 'Pastraipos formatavimas',\n        documentStyle: 'Dokumento stilius',\n        extraKeys: 'Papildomi klavišų deriniai'\n      },\n      history: {\n        undo: 'Anuliuoti veiksmą',\n        redo: 'Perdaryti veiksmą'\n      }\n\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-nb-NO.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'nb-NO': {\n      font: {\n        bold: 'Fet',\n        italic: 'Kursiv',\n        underline: 'Understrek',\n        clear: 'Fjern formatering',\n        height: 'Linjehøyde',\n        name: 'Skrifttype',\n        strikethrough: 'Gjennomstrek',\n        size: 'Skriftstørrelse'\n      },\n      image: {\n        image: 'Bilde',\n        insert: 'Sett inn bilde',\n        resizeFull: 'Sett full størrelse',\n        resizeHalf: 'Sett halv størrelse',\n        resizeQuarter: 'Sett kvart størrelse',\n        floatLeft: 'Flyt til venstre',\n        floatRight: 'Flyt til høyre',\n        floatNone: 'Fjern flyt',\n        dragImageHere: 'Dra et bilde hit',\n        selectFromFiles: 'Velg fra filer',\n        url: 'Bilde-URL',\n        remove: 'Fjern bilde'\n      },\n      link: {\n        link: 'Lenke',\n        insert: 'Sett inn lenke',\n        unlink: 'Fjern lenke',\n        edit: 'Rediger',\n        textToDisplay: 'Visningstekst',\n        url: 'Til hvilken URL skal denne lenken peke?',\n        openInNewWindow: 'Åpne i nytt vindu'\n      },\n      table: {\n        table: 'Tabell'\n      },\n      hr: {\n        insert: 'Sett inn horisontal linje'\n      },\n      style: {\n        style: 'Stil',\n        normal: 'Normal',\n        blockquote: 'Sitat',\n        pre: 'Kode',\n        h1: 'Overskrift 1',\n        h2: 'Overskrift 2',\n        h3: 'Overskrift 3',\n        h4: 'Overskrift 4',\n        h5: 'Overskrift 5',\n        h6: 'Overskrift 6'\n      },\n      lists: {\n        unordered: 'Punktliste',\n        ordered: 'Nummerert liste'\n      },\n      options: {\n        help: 'Hjelp',\n        fullscreen: 'Fullskjerm',\n        codeview: 'HTML-visning'\n      },\n      paragraph: {\n        paragraph: 'Avsnitt',\n        outdent: 'Tilbakerykk',\n        indent: 'Innrykk',\n        left: 'Venstrejustert',\n        center: 'Midtstilt',\n        right: 'Høyrejustert',\n        justify: 'Blokkjustert'\n      },\n      color: {\n        recent: 'Nylig valgt farge',\n        more: 'Flere farger',\n        background: 'Bakgrunnsfarge',\n        foreground: 'Skriftfarge',\n        transparent: 'Gjennomsiktig',\n        setTransparent: 'Sett gjennomsiktig',\n        reset: 'Nullstill',\n        resetToDefault: 'Nullstill til standard'\n      },\n      shortcut: {\n        shortcuts: 'Hurtigtaster',\n        close: 'Lukk',\n        textFormatting: 'Tekstformatering',\n        action: 'Handling',\n        paragraphFormatting: 'Avsnittsformatering',\n        documentStyle: 'Dokumentstil'\n      },\n      history: {\n        undo: 'Angre',\n        redo: 'Gjør om'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-nl-NL.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'nl-NL': {\n      font: {\n        bold: 'Vet',\n        italic: 'Cursief',\n        underline: 'Onderstrepen',\n        clear: 'Stijl verwijderen',\n        height: 'Regelhoogte',\n        name: 'Lettertype',\n        strikethrough: 'Doorhalen',\n        size: 'Tekstgrootte'\n      },\n      image: {\n        image: 'Afbeelding',\n        insert: 'Afbeelding invoegen',\n        resizeFull: 'Volledige breedte',\n        resizeHalf: 'Halve breedte',\n        resizeQuarter: 'Kwart breedte',\n        floatLeft: 'Links uitlijnen',\n        floatRight: 'Rechts uitlijnen',\n        floatNone: 'Geen uitlijning',\n        dragImageHere: 'Sleep hier een afbeelding naar toe',\n        selectFromFiles: 'Selecteer een bestand',\n        url: 'URL van de afbeelding',\n        remove: 'Verwijder afbeelding'\n      },\n      link: {\n        link: 'Link',\n        insert: 'Link invoegen',\n        unlink: 'Link verwijderen',\n        edit: 'Wijzigen',\n        textToDisplay: 'Tekst van link',\n        url: 'Naar welke URL moet deze link verwijzen?',\n        openInNewWindow: 'Open in nieuw venster'\n      },\n      table: {\n        table: 'Tabel'\n      },\n      hr: {\n        insert: 'Horizontale lijn invoegen'\n      },\n      style: {\n        style: 'Stijl',\n        normal: 'Normaal',\n        blockquote: 'Quote',\n        pre: 'Code',\n        h1: 'Kop 1',\n        h2: 'Kop 2',\n        h3: 'Kop 3',\n        h4: 'Kop 4',\n        h5: 'Kop 5',\n        h6: 'Kop 6'\n      },\n      lists: {\n        unordered: 'Ongeordende lijst',\n        ordered: 'Geordende lijst'\n      },\n      options: {\n        help: 'Help',\n        fullscreen: 'Volledig scherm',\n        codeview: 'Bekijk Code'\n      },\n      paragraph: {\n        paragraph: 'Paragraaf',\n        outdent: 'Inspringen verkleinen',\n        indent: 'Inspringen vergroten',\n        left: 'Links uitlijnen',\n        center: 'Centreren',\n        right: 'Rechts uitlijnen',\n        justify: 'Uitvullen'\n      },\n      color: {\n        recent: 'Recente kleur',\n        more: 'Meer kleuren',\n        background: 'Achtergrond kleur',\n        foreground: 'Tekst kleur',\n        transparent: 'Transparant',\n        setTransparent: 'Transparant',\n        reset: 'Standaard',\n        resetToDefault: 'Standaard kleur'\n      },\n      shortcut: {\n        shortcuts: 'Toetsencombinaties',\n        close: 'sluiten',\n        textFormatting: 'Tekststijlen',\n        action: 'Acties',\n        paragraphFormatting: 'Paragraafstijlen',\n        documentStyle: 'Documentstijlen'\n      },\n      history: {\n        undo: 'Ongedaan maken',\n        redo: 'Opnieuw doorvoeren'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-pl-PL.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'pl-PL': {\n      font: {\n        bold: 'Pogrubienie',\n        italic: 'Pochylenie',\n        underline: 'Podkreślenie',\n        clear: 'Usuń formatowanie',\n        height: 'Interlinia',\n        name: 'Czcionka',\n        strikethrough: 'Przekreślenie',\n        size: 'Rozmiar'\n      },\n      image: {\n        image: 'Grafika',\n        insert: 'Wstaw grafikę',\n        resizeFull: 'Zmień rozmiar na 100%',\n        resizeHalf: 'Zmień rozmiar na 50%',\n        resizeQuarter: 'Zmień rozmiar na 25%',\n        floatLeft: 'Po lewej',\n        floatRight: 'Po prawej',\n        floatNone: 'Równo z tekstem',\n        shapeRounded: 'Kształt: zaokrąglone',\n        shapeCircle: 'Kształt: okrąg',\n        shapeThumbnail: 'Kształt: miniatura',\n        shapeNone: 'Kształt: brak',\n        dragImageHere: 'Przeciągnij grafikę lub tekst tutaj',\n        dropImage: 'Przeciągnij grafikę lub tekst',\n        selectFromFiles: 'Wybierz z dysku',\n        maximumFileSize: 'Limit wielkości pliku',\n        maximumFileSizeError: 'Przekroczono limit wielkości pliku.',\n        url: 'Adres URL grafiki',\n        remove: 'Usuń grafikę'\n      },\n      link: {\n        link: 'Odnośnik',\n        insert: 'Wstaw odnośnik',\n        unlink: 'Usuń odnośnik',\n        edit: 'Edytuj',\n        textToDisplay: 'Tekst do wyświetlenia',\n        url: 'Na jaki adres URL powinien przenosić ten odnośnik?',\n        openInNewWindow: 'Otwórz w nowym oknie'\n      },\n      table: {\n        table: 'Tabela'\n      },\n      hr: {\n        insert: 'Wstaw poziomą linię'\n      },\n      style: {\n        style: 'Style',\n        normal: 'Normalny',\n        blockquote: 'Cytat',\n        pre: 'Kod',\n        h1: 'Nagłówek 1',\n        h2: 'Nagłówek 2',\n        h3: 'Nagłówek 3',\n        h4: 'Nagłówek 4',\n        h5: 'Nagłówek 5',\n        h6: 'Nagłówek 6'\n      },\n      lists: {\n        unordered: 'Lista wypunktowana',\n        ordered: 'Lista numerowana'\n      },\n      options: {\n        help: 'Pomoc',\n        fullscreen: 'Pełny ekran',\n        codeview: 'Źródło'\n      },\n      paragraph: {\n        paragraph: 'Akapit',\n        outdent: 'Zmniejsz wcięcie',\n        indent: 'Zwiększ wcięcie',\n        left: 'Wyrównaj do lewej',\n        center: 'Wyrównaj do środka',\n        right: 'Wyrównaj do prawej',\n        justify: 'Wyrównaj do lewej i prawej'\n      },\n      color: {\n        recent: 'Ostani kolor',\n        more: 'Więcej kolorów',\n        background: 'Tło',\n        foreground: 'Czcionka',\n        transparent: 'Przeźroczysty',\n        setTransparent: 'Przeźroczyste',\n        reset: 'Reset',\n        resetToDefault: 'Domyślne'\n      },\n      shortcut: {\n        shortcuts: 'Skróty klawiaturowe',\n        close: 'Zamknij',\n        textFormatting: 'Formatowanie tekstu',\n        action: 'Akcja',\n        paragraphFormatting: 'Formatowanie akapitu',\n        documentStyle: 'Styl dokumentu',\n        extraKeys: 'Dodatkowe klawisze'\n      },\n      history: {\n        undo: 'Cofnij',\n        redo: 'Ponów'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-pt-BR.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'pt-BR': {\n      font: {\n        bold: 'Negrito',\n        italic: 'Itálico',\n        underline: 'Sublinhado',\n        clear: 'Remover estilo da fonte',\n        height: 'Altura da linha',\n        name: 'Fonte',\n        strikethrough: 'Riscado',\n        size: 'Tamanho da fonte'\n      },\n      image: {\n        image: 'Imagem',\n        insert: 'Inserir imagem',\n        resizeFull: 'Resize Full',\n        resizeHalf: 'Resize Half',\n        resizeQuarter: 'Resize Quarter',\n        floatLeft: 'Float Left',\n        floatRight: 'Float Right',\n        floatNone: 'Float None',\n        dragImageHere: 'Arraste uma imagem para cá',\n        selectFromFiles: 'Selecione a partir dos arquivos',\n        url: 'URL da image'\n      },\n      link: {\n        link: 'Link',\n        insert: 'Inserir link',\n        unlink: 'Remover link',\n        edit: 'Editar',\n        textToDisplay: 'Texto para exibir',\n        url: 'Para qual URL esse link leva?',\n        openInNewWindow: 'Abrir em uma nova janela'\n      },\n      table: {\n        table: 'Tabela'\n      },\n      hr: {\n        insert: 'Inserir linha horizontal'\n      },\n      style: {\n        style: 'Estilo',\n        normal: 'Normal',\n        blockquote: 'Citação',\n        pre: 'Código',\n        h1: 'Título 1',\n        h2: 'Título 2',\n        h3: 'Título 3',\n        h4: 'Título 4',\n        h5: 'Título 5',\n        h6: 'Título 6'\n      },\n      lists: {\n        unordered: 'Lista com marcadores',\n        ordered: 'Lista numerada'\n      },\n      options: {\n        help: 'Ajuda',\n        fullscreen: 'Tela cheia',\n        codeview: 'Ver código-fonte'\n      },\n      paragraph: {\n        paragraph: 'Parágrafo',\n        outdent: 'Menor tabulação',\n        indent: 'Maior tabulação',\n        left: 'Alinhar à esquerda',\n        center: 'Alinhar ao centro',\n        right: 'Alinha à direita',\n        justify: 'Justificado'\n      },\n      color: {\n        recent: 'Cor recente',\n        more: 'Mais cores',\n        background: 'Fundo',\n        foreground: 'Fonte',\n        transparent: 'Transparente',\n        setTransparent: 'Fundo transparente',\n        reset: 'Restaurar',\n        resetToDefault: 'Restaurar padrão'\n      },\n      shortcut: {\n        shortcuts: 'Atalhos do teclado',\n        close: 'Fechar',\n        textFormatting: 'Formatação de texto',\n        action: 'Ação',\n        paragraphFormatting: 'Formatação de parágrafo',\n        documentStyle: 'Estilo de documento'\n      },\n      history: {\n        undo: 'Desfazer',\n        redo: 'Refazer'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-pt-PT.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'pt-PT': {\n      font: {\n        bold: 'Negrito',\n        italic: 'Itálico',\n        underline: 'Sublinhado',\n        clear: 'Remover estilo da fonte',\n        height: 'Altura da linha',\n        name: 'Fonte',\n        strikethrough: 'Riscado',\n        size: 'Tamanho da fonte'\n      },\n      image: {\n        image: 'Imagem',\n        insert: 'Inserir imagem',\n        resizeFull: 'Redimensionar Completo',\n        resizeHalf: 'Redimensionar Metade',\n        resizeQuarter: 'Redimensionar Um Quarto',\n        floatLeft: 'Float Esquerda',\n        floatRight: 'Float Direita',\n        floatNone: 'Sem Float',\n        dragImageHere: 'Arraste uma imagem para aqui',\n        selectFromFiles: 'Selecione a partir dos arquivos',\n        url: 'Endereço da imagem'\n      },\n      link: {\n        link: 'Link',\n        insert: 'Inserir ligação',\n        unlink: 'Remover ligação',\n        edit: 'Editar',\n        textToDisplay: 'Texto para exibir',\n        url: 'Que endereço esta licação leva?',\n        openInNewWindow: 'Abrir numa nova janela'\n      },\n      table: {\n        table: 'Tabela'\n      },\n      hr: {\n        insert: 'Inserir linha horizontal'\n      },\n      style: {\n        style: 'Estilo',\n        normal: 'Normal',\n        blockquote: 'Citação',\n        pre: 'Código',\n        h1: 'Título 1',\n        h2: 'Título 2',\n        h3: 'Título 3',\n        h4: 'Título 4',\n        h5: 'Título 5',\n        h6: 'Título 6'\n      },\n      lists: {\n        unordered: 'Lista com marcadores',\n        ordered: 'Lista numerada'\n      },\n      options: {\n        help: 'Ajuda',\n        fullscreen: 'Janela Completa',\n        codeview: 'Ver código-fonte'\n      },\n      paragraph: {\n        paragraph: 'Parágrafo',\n        outdent: 'Menor tabulação',\n        indent: 'Maior tabulação',\n        left: 'Alinhar à esquerda',\n        center: 'Alinhar ao centro',\n        right: 'Alinha à direita',\n        justify: 'Justificado'\n      },\n      color: {\n        recent: 'Cor recente',\n        more: 'Mais cores',\n        background: 'Fundo',\n        foreground: 'Fonte',\n        transparent: 'Transparente',\n        setTransparent: 'Fundo transparente',\n        reset: 'Restaurar',\n        resetToDefault: 'Restaurar padrão'\n      },\n      shortcut: {\n        shortcuts: 'Atalhos do teclado',\n        close: 'Fechar',\n        textFormatting: 'Formatação de texto',\n        action: 'Ação',\n        paragraphFormatting: 'Formatação de parágrafo',\n        documentStyle: 'Estilo de documento'\n      },\n      history: {\n        undo: 'Desfazer',\n        redo: 'Refazer'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-ro-RO.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'ro-RO': {\n      font: {\n        bold: 'Îngroșat',\n        italic: 'Înclinat',\n        underline: 'Subliniat',\n        clear: 'Înlătură formatare font',\n        height: 'Înălțime rând',\n        strikethrough: 'Tăiat',\n        size: 'Dimensiune font'\n      },\n      image: {\n        image: 'Imagine',\n        insert: 'Inserează imagine',\n        resizeFull: 'Redimensionează complet',\n        resizeHalf: 'Redimensionează 1/2',\n        resizeQuarter: 'Redimensionează 1/4',\n        floatLeft: 'Aliniere la stânga',\n        floatRight: 'Aliniere la dreapta',\n        floatNone: 'Fară aliniere',\n        dragImageHere: 'Trage o imagine aici',\n        selectFromFiles: 'Alege din fişiere',\n        url: 'URL imagine'\n      },\n      link: {\n        link: 'Link',\n        insert: 'Inserează link',\n        unlink: 'Înlătură link',\n        edit: 'Editează',\n        textToDisplay: 'Text ce va fi afişat',\n        url: 'Deschidere în fereastra nouă?'\n      },\n      table: {\n        table: 'Tabel'\n      },\n      hr: {\n        insert: 'Inserează o linie orizontală'\n      },\n      style: {\n        style: 'Stil',\n        normal: 'Normal',\n        blockquote: 'Citat',\n        pre: 'Preformatat',\n        h1: 'Titlu 1',\n        h2: 'Titlu 2',\n        h3: 'Titlu 3',\n        h4: 'Titlu 4',\n        h5: 'Titlu 5',\n        h6: 'Titlu 6'\n      },\n      lists: {\n        unordered: 'Listă neordonată',\n        ordered: 'Listă ordonată'\n      },\n      options: {\n        help: 'Ajutor',\n        fullscreen: 'Măreşte',\n        codeview: 'Sursă'\n      },\n      paragraph: {\n        paragraph: 'Paragraf',\n        outdent: 'Creşte identarea',\n        indent: 'Scade identarea',\n        left: 'Aliniere la stânga',\n        center: 'Aliniere centrală',\n        right: 'Aliniere la dreapta',\n        justify: 'Aliniere în bloc'\n      },\n      color: {\n        recent: 'Culoare recentă',\n        more: 'Mai multe  culori',\n        background: 'Culoarea fundalului',\n        foreground: 'Culoarea textului',\n        transparent: 'Transparent',\n        setTransparent: 'Setează transparent',\n        reset: 'Resetează',\n        resetToDefault: 'Revino la iniţial'\n      },\n      shortcut: {\n        shortcuts: 'Scurtături tastatură',\n        close: 'Închide',\n        textFormatting: 'Formatare text',\n        action: 'Acţiuni',\n        paragraphFormatting: 'Formatare paragraf',\n        documentStyle: 'Stil paragraf'\n      },\n      history: {\n        undo: 'Starea anterioară',\n        redo: 'Starea ulterioară'\n      }\n\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-ru-RU.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'ru-RU': {\n      font: {\n        bold: 'Полужирный',\n        italic: 'Курсив',\n        underline: 'Подчёркнутый',\n        clear: 'Убрать стили шрифта',\n        height: 'Высота линии',\n        name: 'Шрифт',\n        strikethrough: 'Зачёркнутый',\n        subscript: 'Нижний индекс',\n        superscript: 'Верхний индекс',\n        size: 'Размер шрифта'\n      },\n      image: {\n        image: 'Картинка',\n        insert: 'Вставить картинку',\n        resizeFull: 'Восстановить размер',\n        resizeHalf: 'Уменьшить до 50%',\n        resizeQuarter: 'Уменьшить до 25%',\n        floatLeft: 'Расположить слева',\n        floatRight: 'Расположить справа',\n        floatNone: 'Расположение по-умолчанию',\n        dragImageHere: 'Перетащите сюда картинку',\n        selectFromFiles: 'Выбрать из файлов',\n        url: 'URL картинки',\n        remove: 'Удалить картинку'\n      },\n      link: {\n        link: 'Ссылка',\n        insert: 'Вставить ссылку',\n        unlink: 'Убрать ссылку',\n        edit: 'Редактировать',\n        textToDisplay: 'Отображаемый текст',\n        url: 'URL для перехода',\n        openInNewWindow: 'Открывать в новом окне'\n      },\n      table: {\n        table: 'Таблица'\n      },\n      hr: {\n        insert: 'Вставить горизонтальную линию'\n      },\n      style: {\n        style: 'Стиль',\n        normal: 'Нормальный',\n        blockquote: 'Цитата',\n        pre: 'Код',\n        h1: 'Заголовок 1',\n        h2: 'Заголовок 2',\n        h3: 'Заголовок 3',\n        h4: 'Заголовок 4',\n        h5: 'Заголовок 5',\n        h6: 'Заголовок 6'\n      },\n      lists: {\n        unordered: 'Маркированный список',\n        ordered: 'Нумерованный список'\n      },\n      options: {\n        help: 'Помощь',\n        fullscreen: 'На весь экран',\n        codeview: 'Исходный код'\n      },\n      paragraph: {\n        paragraph: 'Параграф',\n        outdent: 'Уменьшить отступ',\n        indent: 'Увеличить отступ',\n        left: 'Выровнять по левому краю',\n        center: 'Выровнять по центру',\n        right: 'Выровнять по правому краю',\n        justify: 'Растянуть по ширине'\n      },\n      color: {\n        recent: 'Последний цвет',\n        more: 'Еще цвета',\n        background: 'Цвет фона',\n        foreground: 'Цвет шрифта',\n        transparent: 'Прозрачный',\n        setTransparent: 'Сделать прозрачным',\n        reset: 'Сброс',\n        resetToDefault: 'Восстановить умолчания'\n      },\n      shortcut: {\n        shortcuts: 'Сочетания клавиш',\n        close: 'Закрыть',\n        textFormatting: 'Форматирование текста',\n        action: 'Действие',\n        paragraphFormatting: 'Форматирование параграфа',\n        documentStyle: 'Стиль документа',\n        extraKeys: 'Дополнительные комбинации'\n      },\n      history: {\n        undo: 'Отменить',\n        redo: 'Повтор'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-sk-SK.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'sk-SK': {\n      font: {\n        bold: 'Tučné',\n        italic: 'Kurzíva',\n        underline: 'Podtržené',\n        clear: 'Odstrániť štýl písma',\n        height: 'Výška riadku',\n        strikethrough: 'Preškrtnuté',\n        size: 'Veľkosť písma'\n      },\n      image: {\n        image: 'Obrázok',\n        insert: 'Vložiť obrázok',\n        resizeFull: 'Pôvodná veľkosť',\n        resizeHalf: 'Polovičná veľkosť',\n        resizeQuarter: 'Štvrtinová veľkosť',\n        floatLeft: 'Umiestniť doľava',\n        floatRight: 'Umiestniť doprava',\n        floatNone: 'Bez zarovnania',\n        dragImageHere: 'Pretiahnuť sem obrázok',\n        selectFromFiles: 'Vybrať súbor',\n        url: 'URL obrázku'\n      },\n      link: {\n        link: 'Odkaz',\n        insert: 'Vytvoriť odkaz',\n        unlink: 'Zrušiť odkaz',\n        edit: 'Upraviť',\n        textToDisplay: 'Zobrazovaný text',\n        url: 'Na akú URL adresu má tento odkaz viesť?',\n        openInNewWindow: 'Otvoriť v novom okne'\n      },\n      table: {\n        table: 'Tabuľka'\n      },\n      hr: {\n        insert: 'Vložit vodorovnú čiaru'\n      },\n      style: {\n        style: 'Štýl',\n        normal: 'Normálny',\n        blockquote: 'Citácia',\n        pre: 'Kód',\n        h1: 'Nadpis 1',\n        h2: 'Nadpis 2',\n        h3: 'Nadpis 3',\n        h4: 'Nadpis 4',\n        h5: 'Nadpis 5',\n        h6: 'Nadpis 6'\n      },\n      lists: {\n        unordered: 'Odrážkový zoznam',\n        ordered: 'Číselný zoznam'\n      },\n      options: {\n        help: 'Pomoc',\n        fullscreen: 'Celá obrazovka',\n        codeview: 'HTML kód'\n      },\n      paragraph: {\n        paragraph: 'Odstavec',\n        outdent: 'Zvečiť odsadenie',\n        indent: 'Zmenšiť odsadenie',\n        left: 'Zarovnať doľava',\n        center: 'Zarovnať na stred',\n        right: 'Zarovnať doprava',\n        justify: 'Zarovnať obojstranne'\n      },\n      color: {\n        recent: 'Aktuálna farba',\n        more: 'Dalšie farby',\n        background: 'Farba pozadia',\n        foreground: 'Farba písma',\n        transparent: 'Priehľednosť',\n        setTransparent: 'Nastaviť priehľadnosť',\n        reset: 'Obnoviť',\n        resetToDefault: 'Obnoviť prednastavené'\n      },\n      shortcut: {\n        shortcuts: 'Klávesové skratky',\n        close: 'Zavrieť',\n        textFormatting: 'Formátovanie textu',\n        action: 'Akcia',\n        paragraphFormatting: 'Formátovánie odstavca',\n        documentStyle: 'Štýl dokumentu'\n      },\n      history: {\n        undo: 'Krok vzad',\n        redo: 'Krok dopredu'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-sl-SI.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'sl-SI': {\n      font: {\n        bold: 'Krepko',\n        italic: 'Ležeče',\n        underline: 'Podčrtano',\n        clear: 'Počisti oblikovanje izbire',\n        height: 'Razmik med vrsticami',\n        name: 'Pisava',\n        strikethrough: 'Prečrtano',\n        subscript: 'Podpisano',\n        superscript: 'Nadpisano',\n        size: 'Velikost pisave'\n      },\n      image: {\n        image: 'Slika',\n        insert: 'Vstavi sliko',\n        resizeFull: 'Razširi na polno velikost',\n        resizeHalf: 'Razširi na polovico velikosti',\n        resizeQuarter: 'Razširi na četrtino velikosti',\n        floatLeft: 'Leva poravnava',\n        floatRight: 'Desna poravnava',\n        floatNone: 'Brez poravnave',\n        dragImageHere: 'Sem povlecite sliko',\n        selectFromFiles: 'Izberi sliko za nalaganje',\n        url: 'URL naslov slike',\n        remove: 'Odstrani sliko'\n      },\n      link: {\n        link: 'Povezava',\n        insert: 'Vstavi povezavo',\n        unlink: 'Odstrani povezavo',\n        edit: 'Uredi',\n        textToDisplay: 'Prikazano besedilo',\n        url: 'Povezava',\n        openInNewWindow: 'Odpri v novem oknu'\n      },\n      table: {\n        table: 'Tabela'\n      },\n      hr: {\n        insert: 'Vstavi horizontalno črto'\n      },\n      style: {\n        style: 'Slogi',\n        normal: 'Navadno besedilo',\n        blockquote: 'Citat',\n        pre: 'Koda',\n        h1: 'Naslov 1',\n        h2: 'Naslov 2',\n        h3: 'Naslov 3',\n        h4: 'Naslov 4',\n        h5: 'Naslov 5',\n        h6: 'Naslov 6'\n      },\n      lists: {\n        unordered: 'Označen seznam',\n        ordered: 'Oštevilčen seznam'\n      },\n      options: {\n        help: 'Pomoč',\n        fullscreen: 'Celozaslonski način',\n        codeview: 'Pregled HTML kode'\n      },\n      paragraph: {\n        paragraph: 'Slogi odstavka',\n        outdent: 'Zmanjšaj odmik',\n        indent: 'Povečaj odmik',\n        left: 'Leva poravnava',\n        center: 'Desna poravnava',\n        right: 'Sredinska poravnava',\n        justify: 'Obojestranska poravnava'\n      },\n      color: {\n        recent: 'Uporabi zadnjo barvo',\n        more: 'Več barv',\n        background: 'Barva ozadja',\n        foreground: 'Barva besedila',\n        transparent: 'Brez barve',\n        setTransparent: 'Brez barve',\n        reset: 'Ponastavi',\n        resetToDefault: 'Ponastavi na privzeto'\n      },\n      shortcut: {\n        shortcuts: 'Bljižnice',\n        close: 'Zapri',\n        textFormatting: 'Oblikovanje besedila',\n        action: 'Dejanja',\n        paragraphFormatting: 'Oblikovanje odstavka',\n        documentStyle: 'Oblikovanje naslova'\n      },\n      history: {\n        undo: 'Razveljavi',\n        redo: 'Uveljavi'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-sr-RS-Latin.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'sr-RS': {\n      font: {\n        bold: 'Podebljano',\n        italic: 'Kurziv',\n        underline: 'Podvučeno',\n        clear: 'Ukloni stilove fonta',\n        height: 'Visina linije',\n        strikethrough: 'Precrtano',\n        size: 'Veličina fonta'\n      },\n      image: {\n        image: 'Slika',\n        insert: 'Umetni sliku',\n        resizeFull: 'Puna veličina',\n        resizeHalf: 'Umanji na 50%',\n        resizeQuarter: 'Umanji na 25%',\n        floatLeft: 'Uz levu ivicu',\n        floatRight: 'Uz desnu ivicu',\n        floatNone: 'Bez ravnanja',\n        dragImageHere: 'Prevuci sliku ovde',\n        selectFromFiles: 'Izaberi iz datoteke',\n        url: 'Adresa slike',\n        remove: 'Ukloni sliku'\n      },\n      link: {\n        link: 'Veza',\n        insert: 'Umetni vezu',\n        unlink: 'Ukloni vezu',\n        edit: 'Uredi',\n        textToDisplay: 'Tekst za prikaz',\n        url: 'Internet adresa',\n        openInNewWindow: 'Otvori u novom prozoru'\n      },\n      table: {\n        table: 'Tabela'\n      },\n      hr: {\n        insert: 'Umetni horizontalnu liniju'\n      },\n      style: {\n        style: 'Stil',\n        normal: 'Normalni',\n        blockquote: 'Citat',\n        pre: 'Kod',\n        h1: 'Zaglavlje 1',\n        h2: 'Zaglavlje 2',\n        h3: 'Zaglavlje 3',\n        h4: 'Zaglavlje 4',\n        h5: 'Zaglavlje 5',\n        h6: 'Zaglavlje 6'\n      },\n      lists: {\n        unordered: 'Obična lista',\n        ordered: 'Numerisana lista'\n      },\n      options: {\n        help: 'Pomoć',\n        fullscreen: 'Preko celog ekrana',\n        codeview: 'Izvorni kod'\n      },\n      paragraph: {\n        paragraph: 'Paragraf',\n        outdent: 'Smanji uvlačenje',\n        indent: 'Povečaj uvlačenje',\n        left: 'Poravnaj u levo',\n        center: 'Centrirano',\n        right: 'Poravnaj u desno',\n        justify: 'Poravnaj obostrano'\n      },\n      color: {\n        recent: 'Poslednja boja',\n        more: 'Više boja',\n        background: 'Boja pozadine',\n        foreground: 'Boja teksta',\n        transparent: 'Providna',\n        setTransparent: 'Providna',\n        reset: 'Opoziv',\n        resetToDefault: 'Podrazumevana'\n      },\n      shortcut: {\n        shortcuts: 'Prečice sa tastature',\n        close: 'Zatvori',\n        textFormatting: 'Formatiranje teksta',\n        action: 'Akcija',\n        paragraphFormatting: 'Formatiranje paragrafa',\n        documentStyle: 'Stil dokumenta',\n        extraKeys: 'Dodatne kombinacije'\n      },\n      history: {\n        undo: 'Poništi',\n        redo: 'Ponovi'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-sr-RS.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'sr-RS': {\n      font: {\n        bold: 'Подебљано',\n        italic: 'Курзив',\n        underline: 'Подвучено',\n        clear: 'Уклони стилове фонта',\n        height: 'Висина линије',\n        strikethrough: 'Прецртано',\n        size: 'Величина фонта'\n      },\n      image: {\n        image: 'Слика',\n        insert: 'Уметни слику',\n        resizeFull: 'Пуна величина',\n        resizeHalf: 'Умањи на 50%',\n        resizeQuarter: 'Умањи на 25%',\n        floatLeft: 'Уз леву ивицу',\n        floatRight: 'Уз десну ивицу',\n        floatNone: 'Без равнања',\n        dragImageHere: 'Превуци слику овде',\n        selectFromFiles: 'Изабери из датотеке',\n        url: 'Адреса слике',\n        remove: 'Уклони слику'\n      },\n      link: {\n        link: 'Веза',\n        insert: 'Уметни везу',\n        unlink: 'Уклони везу',\n        edit: 'Уреди',\n        textToDisplay: 'Текст за приказ',\n        url: 'Интернет адреса',\n        openInNewWindow: 'Отвори у новом прозору'\n      },\n      table: {\n        table: 'Табела'\n      },\n      hr: {\n        insert: 'Уметни хоризонталну линију'\n      },\n      style: {\n        style: 'Стил',\n        normal: 'Нормални',\n        blockquote: 'Цитат',\n        pre: 'Код',\n        h1: 'Заглавље 1',\n        h2: 'Заглавље 2',\n        h3: 'Заглавље 3',\n        h4: 'Заглавље 4',\n        h5: 'Заглавље 5',\n        h6: 'Заглавље 6'\n      },\n      lists: {\n        unordered: 'Обична листа',\n        ordered: 'Нумерисана листа'\n      },\n      options: {\n        help: 'Помоћ',\n        fullscreen: 'Преко целог екрана',\n        codeview: 'Изворни код'\n      },\n      paragraph: {\n        paragraph: 'Параграф',\n        outdent: 'Смањи увлачење',\n        indent: 'Повечај увлачење',\n        left: 'Поравнај у лево',\n        center: 'Центрирано',\n        right: 'Поравнај у десно',\n        justify: 'Поравнај обострано'\n      },\n      color: {\n        recent: 'Последња боја',\n        more: 'Више боја',\n        background: 'Боја позадине',\n        foreground: 'Боја текста',\n        transparent: 'Провидна',\n        setTransparent: 'Провидна',\n        reset: 'Опозив',\n        resetToDefault: 'Подразумевана'\n      },\n      shortcut: {\n        shortcuts: 'Пречице са тастатуре',\n        close: 'Затвори',\n        textFormatting: 'Форматирање текста',\n        action: 'Акција',\n        paragraphFormatting: 'Форматирање параграфа',\n        documentStyle: 'Стил документа',\n        extraKeys: 'Додатне комбинације'\n      },\n      history: {\n        undo: 'Поништи',\n        redo: 'Понови'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-sv-SE.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'sv-SE': {\n      font: {\n        bold: 'Fet',\n        italic: 'Kursiv',\n        underline: 'Understruken',\n        clear: 'Radera formatering',\n        height: 'Radavstånd',\n        name: 'Teckensnitt',\n        strikethrough: 'Genomstruken',\n        size: 'Teckenstorlek'\n      },\n      image: {\n        image: 'Bild',\n        insert: 'Infoga bild',\n        resizeFull: 'Full storlek',\n        resizeHalf: 'Halv storlek',\n        resizeQuarter: 'En fjärdedel i storlek',\n        floatLeft: 'Vänsterjusterad',\n        floatRight: 'Högerjusterad',\n        floatNone: 'Ingen justering',\n        dragImageHere: 'Dra en bild hit',\n        selectFromFiles: 'Välj från filer',\n        url: 'Länk till bild',\n        remove: 'Ta bort bild'\n      },\n      link: {\n        link: 'Länk',\n        insert: 'Infoga länk',\n        unlink: 'Ta bort länk',\n        edit: 'Redigera',\n        textToDisplay: 'Visningstext',\n        url: 'Till vilken URL ska denna länk peka?',\n        openInNewWindow: 'Öppna i ett nytt fönster'\n      },\n      table: {\n        table: 'Tabell'\n      },\n      hr: {\n        insert: 'Infoga horisontell linje'\n      },\n      style: {\n        style: 'Stil',\n        normal: 'Normal',\n        blockquote: 'Citat',\n        pre: 'Kod',\n        h1: 'Rubrik 1',\n        h2: 'Rubrik 2',\n        h3: 'Rubrik 3',\n        h4: 'Rubrik 4',\n        h5: 'Rubrik 5',\n        h6: 'Rubrik 6'\n      },\n      lists: {\n        unordered: 'Punktlista',\n        ordered: 'Numrerad lista'\n      },\n      options: {\n        help: 'Hjälp',\n        fullscreen: 'Fullskärm',\n        codeview: 'HTML-visning'\n      },\n      paragraph: {\n        paragraph: 'Justera text',\n        outdent: 'Minska indrag',\n        indent: 'Öka indrag',\n        left: 'Vänsterjusterad',\n        center: 'Centrerad',\n        right: 'Högerjusterad',\n        justify: 'Justera text'\n      },\n      color: {\n        recent: 'Senast använda färg',\n        more: 'Fler färger',\n        background: 'Bakgrundsfärg',\n        foreground: 'Teckenfärg',\n        transparent: 'Genomskinlig',\n        setTransparent: 'Gör genomskinlig',\n        reset: 'Nollställ',\n        resetToDefault: 'Återställ till standard'\n      },\n      shortcut: {\n        shortcuts: 'Kortkommandon',\n        close: 'Stäng',\n        textFormatting: 'Textformatering',\n        action: 'Funktion',\n        paragraphFormatting: 'Avsnittsformatering',\n        documentStyle: 'Dokumentstil'\n      },\n      history: {\n        undo: 'Ångra',\n        redo: 'Gör om'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-th-TH.js",
    "content": "(function ($) {\n\t$.extend($.summernote.lang, {\n\t\t'th-TH': {\n\t\t\tfont: {\n\t\t\t\tbold: 'ตัวหนา',\n\t\t\t\titalic: 'ตัวเอียง',\n\t\t\t\tunderline: 'ขีดเส้นใต้',\n\t\t\t\tclear: 'ล้างรูปแบบตัวอักษร',\n\t\t\t\theight: 'ความสูงบรรทัด',\n\t\t\t\tname: 'แบบตัวอักษร',\n        strikethrough: 'ขีดฆ่า',\n        subscript: 'ตัวห้อย',\n        superscript: 'ตัวยก',\n        size: 'ขนาดตัวอักษร'\n\t\t\t},\n\t\t\timage: {\n\t\t\t\timage: 'รูปภาพ',\n\t\t\t\tinsert: 'แทรกรูปภาพ',\n\t\t\t\tresizeFull: 'ปรับขนาดเท่าจริง',\n\t\t\t\tresizeHalf: 'ปรับขนาดลง 50%',\n\t\t\t\tresizeQuarter: 'ปรับขนาดลง 25%',\n\t\t\t\tfloatLeft: 'ชิดซ้าย',\n\t\t\t\tfloatRight: 'ชิดขวา',\n\t\t\t\tfloatNone: 'ไม่จัดตำแหน่ง',\n\t\t\t\tdragImageHere: 'ลากรูปภาพที่ต้องการไว้ที่นี่',\n\t\t\t\tselectFromFiles: 'เลือกไฟล์รูปภาพ',\n\t\t\t\turl: 'ที่อยู่ URL ของรูปภาพ',\n\t\t\t\tremove: 'ลบรูปภาพ'\n\t\t\t},\n\t\t\tlink: {\n\t\t\t\tlink: 'ตัวเชื่อมโยง',\n\t\t\t\tinsert: 'แทรกตัวเชื่อมโยง',\n\t\t\t\tunlink: 'ยกเลิกตัวเชื่อมโยง',\n\t\t\t\tedit: 'แก้ไข',\n\t\t\t\ttextToDisplay: 'ข้อความที่ให้แสดง',\n\t\t\t\turl: 'ที่อยู่เว็บไซต์ที่ต้องการให้เชื่อมโยงไปถึง?',\n\t\t\t\topenInNewWindow: 'เปิดในหน้าต่างใหม่'\n\t\t\t},\n\t\t\ttable: {\n\t\t\t\ttable: 'ตาราง'\n\t\t\t},\n\t\t\thr: {\n\t\t\t\tinsert: 'แทรกเส้นคั่น'\n\t\t\t},\n\t\t\tstyle: {\n\t\t\t\tstyle: 'รูปแบบ',\n\t\t\t\tnormal: 'ปกติ',\n\t\t\t\tblockquote: 'ข้อความ',\n\t\t\t\tpre: 'โค้ด',\n\t\t\t\th1: 'หัวข้อ 1',\n\t\t\t\th2: 'หัวข้อ 2',\n\t\t\t\th3: 'หัวข้อ 3',\n\t\t\t\th4: 'หัวข้อ 4',\n\t\t\t\th5: 'หัวข้อ 5',\n\t\t\t\th6: 'หัวข้อ 6'\n\t\t\t},\n\t\t\tlists: {\n\t\t\t\tunordered: 'รายการแบบไม่มีลำดับ',\n\t\t\t\tordered: 'รายการแบบมีลำดับ'\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\thelp: 'ช่วยเหลือ',\n\t\t\t\tfullscreen: 'ขยายเต็มหน้าจอ',\n\t\t\t\tcodeview: 'ซอร์สโค้ด'\n\t\t\t},\n\t\t\tparagraph: {\n\t\t\t\tparagraph: 'ย่อหน้า',\n\t\t\t\toutdent: 'เยื้องซ้าย',\n\t\t\t\tindent: 'เยื้องขวา',\n\t\t\t\tleft: 'จัดหน้าชิดซ้าย',\n\t\t\t\tcenter: 'จัดหน้ากึ่งกลาง',\n\t\t\t\tright: 'จัดหน้าชิดขวา',\n\t\t\t\tjustify: 'จัดบรรทัดเสมอกัน'\n\t\t\t},\n\t\t\tcolor: {\n\t\t\t\trecent: 'สีที่ใช้ล่าสุด',\n\t\t\t\tmore: 'สีอื่นๆ',\n\t\t\t\tbackground: 'สีพื้นหลัง',\n\t\t\t\tforeground: 'สีพื้นหน้า',\n\t\t\t\ttransparent: 'โปร่งแสง',\n\t\t\t\tsetTransparent: 'ตั้งค่าความโปร่งแสง',\n\t\t\t\treset: 'คืนค่า',\n\t\t\t\tresetToDefault: 'คืนค่ามาตรฐาน'\n\t\t\t},\n\t\t\tshortcut: {\n\t\t\t\tshortcuts: 'แป้นลัด',\n\t\t\t\tclose: 'ปิด',\n\t\t\t\ttextFormatting: 'การจัดรูปแบบข้อความ',\n\t\t\t\taction: 'การกระทำ',\n\t\t\t\tparagraphFormatting: 'การจัดรูปแบบย่อหน้า',\n\t\t\t\tdocumentStyle: 'รูปแบบของเอกสาร'\n\t\t\t},\n\t\t\thistory: {\n\t\t\t\tundo: 'ยกเลิกการกระทำ',\n\t\t\t\tredo: 'ทำซ้ำการกระทำ'\n\t\t\t}\n\t\t}\n\t});\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-tr-TR.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'tr-TR': {\n      font: {\n        bold: 'Kalın',\n        italic: 'İtalik',\n        underline: 'Altı çizili',\n        clear: 'Temizle',\n        height: 'Satır yüksekliği',\n        name: 'Yazı Tipi',\n        strikethrough: 'Üstü çizili',\n        subscript: 'Alt Simge',\n        superscript: 'Üst Simge',\n        size: 'Yazı tipi boyutu'\n      },\n      image: {\n        image: 'Resim',\n        insert: 'Resim ekle',\n        resizeFull: 'Orjinal boyut',\n        resizeHalf: '1/2 boyut',\n        resizeQuarter: '1/4 boyut',\n        floatLeft: 'Sola hizala',\n        floatRight: 'Sağa hizala',\n        floatNone: 'Hizalamayı kaldır',\n        shapeRounded: 'Şekil: Yuvarlatılmış Köşe',\n        shapeCircle: 'Şekil: Daire',\n        shapeThumbnail: 'Şekil: K.Resim',\n        shapeNone: 'Şekil: Yok',\n        dragImageHere: 'Buraya sürükleyin',\n        selectFromFiles: 'Dosya seçin',\n        url: 'Resim bağlantısı',\n        remove: 'Resimi Kaldır'\n      },\n      link: {\n        link: 'Bağlantı',\n        insert: 'Bağlantı ekle',\n        unlink: 'Bağlantıyı kaldır',\n        edit: 'Bağlantıyı düzenle',\n        textToDisplay: 'Görüntülemek için',\n        url: 'Bağlantı adresi?',\n        openInNewWindow: 'Yeni pencerede aç'\n      },\n      table: {\n        table: 'Tablo'\n      },\n      hr: {\n        insert: 'Yatay çizgi ekle'\n      },\n      style: {\n        style: 'Biçim',\n        normal: 'Normal',\n        blockquote: 'Alıntı',\n        pre: 'Önbiçimli',\n        h1: 'Başlık 1',\n        h2: 'Başlık 2',\n        h3: 'Başlık 3',\n        h4: 'Başlık 4',\n        h5: 'Başlık 5',\n        h6: 'Başlık 6'\n      },\n      lists: {\n        unordered: 'Madde işaretli liste',\n        ordered: 'Numaralı liste'\n      },\n      options: {\n        help: 'Yardım',\n        fullscreen: 'Tam ekran',\n        codeview: 'HTML Kodu'\n      },\n      paragraph: {\n        paragraph: 'Paragraf',\n        outdent: 'Girintiyi artır',\n        indent: 'Girintiyi azalt',\n        left: 'Sola hizala',\n        center: 'Ortaya hizala',\n        right: 'Sağa hizala',\n        justify: 'Yasla'\n      },\n      color: {\n        recent: 'Son renk',\n        more: 'Daha fazla renk',\n        background: 'Arka plan rengi',\n        foreground: 'Yazı rengi',\n        transparent: 'Seffaflık',\n        setTransparent: 'Şeffaflığı ayarla',\n        reset: 'Sıfırla',\n        resetToDefault: 'Varsayılanlara sıfırla'\n      },\n      shortcut: {\n        shortcuts: 'Kısayollar',\n        close: 'Kapat',\n        textFormatting: 'Yazı biçimlendirme',\n        action: 'Eylem',\n        paragraphFormatting: 'Paragraf biçimlendirme',\n        documentStyle: 'Biçim'\n      },\n      history: {\n        undo: 'Geri al',\n        redo: 'Yeniden yap'\n      }\n\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-uk-UA.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'uk-UA': {\n      font: {\n        bold: 'Напівжирний',\n        italic: 'Курсив',\n        underline: 'Підкреслений',\n        clear: 'Прибрати стилі шрифту',\n        height: 'Висота лінії',\n        name: 'Шрифт',\n        strikethrough: 'Закреслений',\n        subscript: 'Нижній індекс',\n        superscript: 'Верхній індекс',\n        size: 'Розмір шрифту'\n      },\n      image: {\n        image: 'Картинка',\n        insert: 'Вставити картинку',\n        resizeFull: 'Відновити розмір',\n        resizeHalf: 'Зменшити до 50%',\n        resizeQuarter: 'Зменшити до 25%',\n        floatLeft: 'Розташувати ліворуч',\n        floatRight: 'Розташувати праворуч',\n        floatNone: 'Початкове розташування',\n        dragImageHere: 'Перетягніть сюди картинку',\n        selectFromFiles: 'Вибрати з файлів',\n        url: 'URL картинки',\n        remove: 'Видалити картинку'\n      },\n      link: {\n        link: 'Посилання',\n        insert: 'Вставити посилання',\n        unlink: 'Прибрати посилання',\n        edit: 'Редагувати',\n        textToDisplay: 'Текст, що відображається',\n        url: 'URL для переходу',\n        openInNewWindow: 'Відкривати у новому вікні'\n      },\n      table: {\n        table: 'Таблиця'\n      },\n      hr: {\n        insert: 'Вставити горизонтальну лінію'\n      },\n      style: {\n        style: 'Стиль',\n        normal: 'Нормальний',\n        blockquote: 'Цитата',\n        pre: 'Код',\n        h1: 'Заголовок 1',\n        h2: 'Заголовок 2',\n        h3: 'Заголовок 3',\n        h4: 'Заголовок 4',\n        h5: 'Заголовок 5',\n        h6: 'Заголовок 6'\n      },\n      lists: {\n        unordered: 'Маркований список',\n        ordered: 'Нумерований список'\n      },\n      options: {\n        help: 'Допомога',\n        fullscreen: 'На весь екран',\n        codeview: 'Початковий код'\n      },\n      paragraph: {\n        paragraph: 'Параграф',\n        outdent: 'Зменшити відступ',\n        indent: 'Збільшити відступ',\n        left: 'Вирівняти по лівому краю',\n        center: 'Вирівняти по центру',\n        right: 'Вирівняти по правому краю',\n        justify: 'Розтягнути по ширині'\n      },\n      color: {\n        recent: 'Останній колір',\n        more: 'Ще кольори',\n        background: 'Колір фону',\n        foreground: 'Колір шрифту',\n        transparent: 'Прозорий',\n        setTransparent: 'Зробити прозорим',\n        reset: 'Відновити',\n        resetToDefault: 'Відновити початкові'\n      },\n      shortcut: {\n        shortcuts: 'Комбінації клавіш',\n        close: 'Закрити',\n        textFormatting: 'Форматування тексту',\n        action: 'Дія',\n        paragraphFormatting: 'Форматування параграфу',\n        documentStyle: 'Стиль документу'\n      },\n      history: {\n        undo: 'Відмінити',\n        redo: 'Повторити'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-vi-VN.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'vi-VN': {\n      font: {\n        bold: 'In Đậm',\n        italic: 'In Nghiên',\n        underline: 'Gạch Dưới',\n        clear: 'Bỏ Định Dạng',\n        height: 'Khoảng Cách Hàng',\n        name: 'Phông Chữ',\n        strikethrough: 'Gạch Ngang',\n        size: 'Cỡ Chữ'\n      },\n      image: {\n        image: 'Hình Ảnh',\n        insert: 'Chèn',\n        resizeFull: '100%',\n        resizeHalf: '50%',\n        resizeQuarter: '25%',\n        floatLeft: 'Canh Trái',\n        floatRight: 'Canh Phải',\n        floatNone: 'Canh Đều',\n        dragImageHere: 'Thả Ảnh Ở Đây',\n        selectFromFiles: 'Chọn Từ Files',\n        url: 'URL',\n        remove: 'Ghỡ Bỏ'\n      },\n      link: {\n        link: 'Đường Dẫn',\n        insert: 'Chèn Đường Dẫn',\n        unlink: 'Ghỡ Đường Dẫn',\n        edit: 'Sửa',\n        textToDisplay: 'Text Hiển Thị',\n        url: 'URL',\n        openInNewWindow: 'Mở ở Cửa Sổ Mới'\n      },\n      table: {\n        table: 'Bảng'\n      },\n      hr: {\n        insert: 'Chèn Vào'\n      },\n      style: {\n        style: 'Kiểu Chữ',\n        normal: 'Chữ Thường',\n        blockquote: 'Đoạn Trích',\n        pre: 'Mã Code',\n        h1: 'H1',\n        h2: 'H2',\n        h3: 'H3',\n        h4: 'H4',\n        h5: 'H5',\n        h6: 'H6'\n      },\n      lists: {\n        unordered: 'Liệt Kê Danh Sách',\n        ordered: 'Liệt Kê Theo Số'\n      },\n      options: {\n        help: 'Trợ Giúp',\n        fullscreen: 'Đầy Màn Hình',\n        codeview: 'Xem Dạng Code'\n      },\n      paragraph: {\n        paragraph: 'Canh Lề',\n        outdent: 'Dịch Sang Trái',\n        indent: 'Dịch Sang Phải',\n        left: 'Canh Trái',\n        center: 'Canh Giữa',\n        right: 'Canh Phải',\n        justify: 'Canh Đều'\n      },\n      color: {\n        recent: 'Màu Chữ',\n        more: 'Mở Rộng',\n        background: 'Màu Nền',\n        foreground: 'Màu Chữ',\n        transparent: 'Trong Suốt',\n        setTransparent: 'Nền Trong Suốt',\n        reset: 'Thiệt Lập Lại',\n        resetToDefault: 'Trở Lại Ban Đầu'\n      },\n      shortcut: {\n        shortcuts: 'Phím Tắt',\n        close: 'Đóng',\n        textFormatting: 'Định Dạng Văn Bản',\n        action: 'Hành Động',\n        paragraphFormatting: 'Định Dạng',\n        documentStyle: 'Kiểu Văn Bản'\n      },\n      history: {\n        undo: 'Lùi Lại',\n        redo: 'Làm Lại'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-zh-CN.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'zh-CN': {\n      font: {\n        bold: '粗体',\n        italic: '斜体',\n        underline: '下划线',\n        clear: '清除格式',\n        height: '行高',\n        name: '字体',\n        strikethrough: '删除线',\n        subscript: '下标',\n        superscript: '上标',\n        size: '字号'\n      },\n      image: {\n        image: '图片',\n        insert: '插入图片',\n        resizeFull: '缩放至 100%',\n        resizeHalf: '缩放至 50%',\n        resizeQuarter: '缩放至 25%',\n        floatLeft: '靠左浮动',\n        floatRight: '靠右浮动',\n        floatNone: '取消浮动',\n        shapeRounded: '形状: 圆角',\n        shapeCircle: '形状: 圆',\n        shapeThumbnail: '形状: 缩略图',\n        shapeNone: '形状: 无',\n        dragImageHere: '将图片拖拽至此处',\n        selectFromFiles: '从本地上传',\n        maximumFileSize: '文件大小最大值',\n        maximumFileSizeError: '文件大小超出最大值。',\n        url: '图片地址',\n        remove: '移除图片'\n      },\n      link: {\n        link: '链接',\n        insert: '插入链接',\n        unlink: '去除链接',\n        edit: '编辑链接',\n        textToDisplay: '显示文本',\n        url: '链接地址',\n        openInNewWindow: '在新窗口打开'\n      },\n      table: {\n        table: '表格'\n      },\n      hr: {\n        insert: '水平线'\n      },\n      style: {\n        style: '样式',\n        normal: '普通',\n        blockquote: '引用',\n        pre: '代码',\n        h1: '标题 1',\n        h2: '标题 2',\n        h3: '标题 3',\n        h4: '标题 4',\n        h5: '标题 5',\n        h6: '标题 6'\n      },\n      lists: {\n        unordered: '无序列表',\n        ordered: '有序列表'\n      },\n      options: {\n        help: '帮助',\n        fullscreen: '全屏',\n        codeview: '源代码'\n      },\n      paragraph: {\n        paragraph: '段落',\n        outdent: '减少缩进',\n        indent: '增加缩进',\n        left: '左对齐',\n        center: '居中对齐',\n        right: '右对齐',\n        justify: '两端对齐'\n      },\n      color: {\n        recent: '最近使用',\n        more: '更多',\n        background: '背景',\n        foreground: '前景',\n        transparent: '透明',\n        setTransparent: '透明',\n        reset: '重置',\n        resetToDefault: '默认'\n      },\n      shortcut: {\n        shortcuts: '快捷键',\n        close: '关闭',\n        textFormatting: '文本格式',\n        action: '动作',\n        paragraphFormatting: '段落格式',\n        documentStyle: '文档样式',\n        extraKeys: '额外按键'\n      },\n      history: {\n        undo: '撤销',\n        redo: '重做'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/lang/summernote-zh-TW.js",
    "content": "(function ($) {\n  $.extend($.summernote.lang, {\n    'zh-TW': {\n      font: {\n        bold: '粗體',\n        italic: '斜體',\n        underline: '底線',\n        clear: '清除格式',\n        height: '行高',\n        name: '字體',\n        strikethrough: '刪除線',\n        subscript: '下標',\n        superscript: '上標',\n        size: '字號'\n      },\n      image: {\n        image: '圖片',\n        insert: '插入圖片',\n        resizeFull: '縮放至100%',\n        resizeHalf: '縮放至 50%',\n        resizeQuarter: '縮放至 25%',\n        floatLeft: '靠左浮動',\n        floatRight: '靠右浮動',\n        floatNone: '取消浮動',\n        shapeRounded: '形狀: 圓角',\n        shapeCircle: '形狀: 圓',\n        shapeThumbnail: '形狀: 縮略圖',\n        shapeNone: '形狀: 無',\n        dragImageHere: '將圖片拖曳至此處',\n        selectFromFiles: '從本機上傳',\n        maximumFileSize: '文件大小最大值',\n        maximumFileSizeError: '文件大小超出最大值。',\n        url: '圖片網址',\n        remove: '移除圖片'\n      },\n      link: {\n        link: '連結',\n        insert: '插入連結',\n        unlink: '取消連結',\n        edit: '編輯連結',\n        textToDisplay: '顯示文字',\n        url: '連結網址',\n        openInNewWindow: '在新視窗開啟'\n      },\n      table: {\n        table: '表格'\n      },\n      hr: {\n        insert: '水平線'\n      },\n      style: {\n        style: '樣式',\n        normal: '一般',\n        blockquote: '引用區塊',\n        pre: '程式碼區塊',\n        h1: '標題 1',\n        h2: '標題 2',\n        h3: '標題 3',\n        h4: '標題 4',\n        h5: '標題 5',\n        h6: '標題 6'\n      },\n      lists: {\n        unordered: '項目清單',\n        ordered: '編號清單'\n      },\n      options: {\n        help: '幫助',\n        fullscreen: '全螢幕',\n        codeview: '原始碼'\n      },\n      paragraph: {\n        paragraph: '段落',\n        outdent: '取消縮排',\n        indent: '增加縮排',\n        left: '靠右對齊',\n        center: '靠中對齊',\n        right: '靠右對齊',\n        justify: '左右對齊'\n      },\n      color: {\n        recent: '字型顏色',\n        more: '更多',\n        background: '背景',\n        foreground: '前景',\n        transparent: '透明',\n        setTransparent: '透明',\n        reset: '重設',\n        resetToDefault: '默認'\n      },\n      shortcut: {\n        shortcuts: '快捷鍵',\n        close: '關閉',\n        textFormatting: '文字格式',\n        action: '動作',\n        paragraphFormatting: '段落格式',\n        documentStyle: '文件格式',\n        extraKeys: '額外按鍵'\n      },\n      history: {\n        undo: '復原',\n        redo: '取消復原'\n      }\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "static/assets/plugins/summernote/meteor/README.md",
    "content": "Build + Meteor status: [![Build Status](https://travis-ci.org/MeteorPackaging/summernote.svg?branch=meteor-integration)](https://github.com/MeteorPackaging/summernote/tree/meteor-integration/meteor)\n\nPackaging [summernote](http://summernote.org/) for [Meteor.js](http://meteor.com).\n\n# Versions\n\n* [summernote:summernote](https://atmospherejs.com/summernote/summernote) - includes jQuery and Bootstrap as dependencies\n* [summernote:standalone](https://atmospherejs.com/summernote/standalone) - doesn't include any dependencies\n\n\n# Meteor\n\nIf you're new to Meteor, here's what the excitement is all about -\n[watch the first two minutes](https://www.youtube.com/watch?v=fsi0aJ9yr2o); you'll be hooked by 1:28.\nThat screencast is from 2012. In the meantime, Meteor has become a mature JavaScript-everywhere web\ndevelopment framework. Read more at [Why Meteor](http://www.meteorpedia.com/read/Why_Meteor).\n\n\n# Issues\n\nIf you encounter an issue while using this package, please CC @dandv when you file it in this repo.\n\n\n# DONE\n\n* Instantiation test\n\n\n# TODO\n\n* Make sure the library works with Meteor's reactivity - for example to auto-save to a collection\n  transparently after the text changes.\n* Tests ensuring correct event handling on template re-rendering\n"
  },
  {
    "path": "static/assets/plugins/summernote/meteor/package-standalone.js",
    "content": "// package metadata file for Meteor.js\n'use strict';\n\nvar packageName = 'summernote:standalone';  // http://atmospherejs.com/summernote:standalone\nvar where = 'client';  // where to install: 'client' or 'server'. For both, pass nothing.\n\nvar packageJson = JSON.parse(Npm.require(\"fs\").readFileSync('package.json'));\n\nPackage.describe({\n  name: packageName,\n  summary: 'summernote standalone (official): WYSIWYG editor with embedded images support, packaged without deps',\n  version: packageJson.version,\n  git: 'https://github.com/summernote/summernote.git'\n});\n\nPackage.onUse(function (api) {\n  api.versionsFrom(['METEOR@0.9.0', 'METEOR@1.0']);\n  // no exports - summernote adds itself to jQuery\n  api.addFiles([\n    'dist/summernote.js',\n    'dist/summernote.css'\n  ], where);\n});\n\nPackage.onTest(function (api) {\n  // load dependencies for test only, before loading the package\n  api.use(['twbs:bootstrap@3.3.1', 'fortawesome:fontawesome@4.2.0'], where);\n\n  // load our package\n  api.use(packageName, where);\n\n  // load the test runner\n  api.use('tinytest', where);\n\n  api.addFiles('meteor/test.js', where);\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/meteor/package.js",
    "content": "// package metadata file for Meteor.js\n'use strict';\n\nvar packageName = 'summernote:summernote';  // http://atmospherejs.com/summernote:summernote\nvar where = 'client';  // where to install: 'client' or 'server'. For both, pass nothing.\n\nvar packageJson = JSON.parse(Npm.require(\"fs\").readFileSync('package.json'));\n\nPackage.describe({\n  name: packageName,\n  summary: 'summernote (official): jQuery+Bootstrap+FontAwesome WYSIWYG editor with embedded images support',\n  version: packageJson.version,\n  git: 'https://github.com/summernote/summernote.git'\n});\n\nPackage.onUse(function (api) {\n  api.versionsFrom(['METEOR@0.9.0', 'METEOR@1.0']);\n  api.use([\n    'jquery',\n    'twbs:bootstrap@3.3.1',\n    'fortawesome:fontawesome@4.2.0'\n  ], where);\n  // no exports - summernote adds itself to jQuery\n  api.addFiles([\n    'dist/summernote.js',\n    'dist/summernote.css'\n  ], where);\n});\n\nPackage.onTest(function (api) {\n  api.use(packageName, where);\n  api.use('tinytest', where);\n\n  api.addFiles('meteor/test.js', where);\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/meteor/publish.sh",
    "content": "#!/bin/bash\n# Publish package to Meteor's repository, Atmospherejs.com\n\n# Make sure Meteor is installed, per https://www.meteor.com/install.\n# The curl'ed script is totally safe; takes 2 minutes to read its source and check.\ntype meteor >/dev/null 2>&1 || { curl https://install.meteor.com/ | sh; }\n\n# sanity check: make sure we're in the root directory of the checkout\ncd \"$( dirname \"$0\" )/..\"\n\nALL_EXIT_CODE=0\n\n# test any package*.js packages we may have, e.g. package.js, package-compat.js\nfor PACKAGE_FILE in meteor/package*.js; do\n\n  # Meteor expects package.js to be in the root directory of the checkout, so copy there our package file under that name, temporarily\n  cp $PACKAGE_FILE ./package.js\n\n  # publish package, creating it if it's the first time we're publishing\n  PACKAGE_NAME=$(grep -i name package.js | head -1 | cut -d \"'\" -f 2)\n\n  echo \"Publishing $PACKAGE_NAME...\"\n\n  # Attempt to re-publish the package - the most common operation once the initial release has\n  # been made. If the package name was changed (rare), you'll have to pass the --create flag.\n  meteor publish \"$@\"; EXIT_CODE=$?\n  ALL_EXIT_CODE=$(( $ALL_EXIT_CODE + $EXIT_CODE ))\n  if (( $EXIT_CODE == 0 )); then\n    echo \"Thanks for releasing a new version. You can see it at\"\n    echo \"https://atmospherejs.com/${PACKAGE_NAME/://}\"\n  else\n    echo \"We got an error. Please post it at https://github.com/raix/Meteor-community-discussions/issues/14\"\n  fi\n\n  # rm the temporary build files and package.js\n  rm -rf \".build.$PACKAGE_NAME\" versions.json package.js\n\ndone\n\nexit $ALL_EXIT_CODE\n"
  },
  {
    "path": "static/assets/plugins/summernote/meteor/runtests.sh",
    "content": "#!/bin/sh\n# Test Meteor package before publishing to Atmospherejs.com\n\n# Make sure Meteor is installed, per https://www.meteor.com/install.\n# The curl'ed script is totally safe; takes 2 minutes to read its source and check.\ntype meteor >/dev/null 2>&1 || { curl https://install.meteor.com/ | sh; }\n\n# sanity check: make sure we're in the root directory of the checkout\ncd \"$( dirname \"$0\" )/..\"\n\nALL_EXIT_CODE=0\n\n# test any package*.js packages we may have, e.g. package.js, package-standalone.js\nfor PACKAGE_FILE in meteor/package*.js; do\n\n  # Meteor expects package.js in the root dir of the checkout, so copy there our package file under that name, temporarily\n  cp $PACKAGE_FILE ./package.js\n\n  PACKAGE_NAME=$(grep -i name package.js | head -1 | cut -d \"'\" -f 2)\n\n  echo \"### Testing $PACKAGE_NAME...\"\n\n  # provide an invalid MONGO_URL so Meteor doesn't bog us down with an empty Mongo database\n  if [ $# -gt 0 ]; then\n    # interpret any parameter to mean we want an interactive test\n    MONGO_URL=mongodb:// meteor test-packages ./\n  else\n    # automated/CI test with phantomjs\n    spacejam --mongo-url mongodb:// test-packages ./\n    ALL_EXIT_CODES=$(( $ALL_EXIT_CODES + $? ))\n  fi\n\n  # delete temporary build files and package.js\n  rm -rf .build.* versions.json package.js\n\ndone\n\nexit $ALL_EXIT_CODES\n"
  },
  {
    "path": "static/assets/plugins/summernote/meteor/test.js",
    "content": "'use strict';\n\nTinytest.add('Instantiation', function (test) {\n  var editor = document.createElement('div');\n  document.body.appendChild(editor);\n  $(editor).summernote();\n\n  test.equal(typeof $(editor).code(), 'string', 'Instantiation');\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/plugin/summernote-ext-hello.js",
    "content": "(function (factory) {\n  /* global define */\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define(['jquery'], factory);\n  } else {\n    // Browser globals: jQuery\n    factory(window.jQuery);\n  }\n}(function ($) {\n  // template\n  var tmpl = $.summernote.renderer.getTemplate();\n\n  /**\n   * @class plugin.hello \n   * \n   * Hello Plugin  \n   */\n  $.summernote.addPlugin({\n    /** @property {String} name name of plugin */\n    name: 'hello',\n    /** \n     * @property {Object} buttons \n     * @property {Function} buttons.hello   function to make button\n     * @property {Function} buttons.helloDropdown   function to make button\n     * @property {Function} buttons.helloImage   function to make button\n     */\n    buttons: { // buttons\n      hello: function (lang, options) {\n\n        return tmpl.iconButton(options.iconPrefix + 'header', {\n          event : 'hello',\n          title: 'hello',\n          hide: true\n        });\n      },\n      helloDropdown: function (lang, options) {\n\n\n        var list = '<li><a data-event=\"helloDropdown\" href=\"#\" data-value=\"summernote\">summernote</a></li>';\n        list += '<li><a data-event=\"helloDropdown\" href=\"#\" data-value=\"codemirror\">Code Mirror</a></li>';\n        var dropdown = '<ul class=\"dropdown-menu\">' + list + '</ul>';\n\n        return tmpl.iconButton(options.iconPrefix + 'header', {\n          title: 'hello',\n          hide: true,\n          dropdown : dropdown\n        });\n      },\n      helloImage : function (lang, options) {\n        return tmpl.iconButton(options.iconPrefix + 'file-image-o', {\n          event : 'helloImage',\n          title: 'helloImage',\n          hide: true\n        });\n      }\n\n    },\n\n    /**\n     * @property {Object} events \n     * @property {Function} events.hello  run function when button that has a 'hello' event name  fires click\n     * @property {Function} events.helloDropdown run function when button that has a 'helloDropdown' event name  fires click\n     * @property {Function} events.helloImage run function when button that has a 'helloImage' event name  fires click\n     */\n    events: { // events\n      hello: function (event, editor, layoutInfo) {\n        // Get current editable node\n        var $editable = layoutInfo.editable();\n\n        // Call insertText with 'hello'\n        editor.insertText($editable, 'hello ');\n      },\n      helloDropdown: function (event, editor, layoutInfo, value) {\n        // Get current editable node\n        var $editable = layoutInfo.editable();\n\n        // Call insertText with 'hello'\n        editor.insertText($editable, 'hello ' + value + '!!!!');\n      },\n      helloImage : function (event, editor, layoutInfo) {\n        var $editable = layoutInfo.editable();\n\n        var img = $('<img src=\"http://upload.wikimedia.org/wikipedia/commons/b/b0/NewTux.svg\" />');\n        editor.insertNode($editable, img[0]);\n      }\n    }\n  });\n}));\n"
  },
  {
    "path": "static/assets/plugins/summernote/plugin/summernote-ext-hint.js",
    "content": "(function (factory) {\n  /* global define */\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define(['jquery'], factory);\n  } else {\n    // Browser globals: jQuery\n    factory(window.jQuery);\n  }\n}(function ($) {\n  // import core class\n  var range = $.summernote.core.range;\n\n  var KEY = {\n    UP: 38,\n    DOWN: 40,\n    ENTER: 13\n  };\n\n  var DROPDOWN_KEYCODES = [KEY.UP, KEY.DOWN, KEY.ENTER];\n\n  /**\n   * @class plugin.hint\n   *\n   * Hint Plugin\n   */\n  $.summernote.addPlugin({\n    /**\n     * name name of plugin\n     * @property {String}\n     **/\n    name: 'hint',\n\n    /**\n     * @property {Regex}\n     * @interface\n     */\n    match: /[a-z]+/g,\n\n    /**\n     * create list item template\n     *\n     * @interface\n     * @param {Object} search\n     * @returns {Array}  created item list\n     */\n    template: null,\n\n    /**\n     * create inserted content to add  in summernote\n     *\n     * @interface\n     * @param {String} html\n     * @param {String} keyword\n     * @return {HTMLEleemnt|String}\n     */\n    content: null,\n\n    /**\n     * load search list\n     *\n     * @interface\n     */\n    load: null,\n\n    /**\n     * @param {jQuery} $node\n     */\n    scrollTo: function ($node) {\n      var $parent = $node.parent();\n      $parent[0].scrollTop = $node[0].offsetTop - ($parent.innerHeight() / 2);\n    },\n\n    /**\n     * @param {jQuery} $popover\n     */\n    moveDown: function ($popover) {\n      var index = $popover.find('.active').index();\n      this.activate($popover, (index === -1) ? 0 : (index + 1) % $popover.children().length);\n    },\n\n    /**\n     * @param {jQuery} $popover\n     */\n    moveUp: function ($popover) {\n      var index = $popover.find('.active').index();\n      this.activate($popover, (index === -1) ? 0 : (index - 1) % $popover.children().length);\n    },\n\n    /**\n     * @param {jQuery} $popover\n     * @param {Number} i\n     */\n    activate: function ($popover, idx) {\n      idx = idx || 0;\n\n      if (idx < 0) {\n        idx = $popover.children().length - 1;\n      }\n\n      $popover.children().removeClass('active');\n      var $activeItem = $popover.children().eq(idx);\n      $activeItem.addClass('active');\n\n      this.scrollTo($activeItem);\n    },\n\n    /**\n     * @param {jQuery} $popover\n     */\n    replace: function ($popover) {\n      var wordRange = $popover.data('wordRange');\n      var $activeItem = $popover.find('.active');\n      var content = this.content($activeItem.data('item'));\n\n      if (typeof content === 'string') {\n        content = document.createTextNode(content);\n      }\n\n      $popover.removeData('wordRange');\n\n      wordRange.insertNode(content);\n      range.createFromNode(content).collapse().select();\n    },\n\n    /**\n     * @param {String} keyword\n     * @return {Object|null}\n     */\n    searchKeyword: function (keyword, callback) {\n      if (this.match.test(keyword)) {\n        var matches = this.match.exec(keyword);\n        this.search(matches[1], callback);\n      } else {\n        callback();\n      }\n    },\n\n\n    createTemplate: function (list) {\n      var items  = [];\n      list = list || [];\n\n      for (var i = 0, len = list.length; i < len; i++) {\n        var $item = $('<a class=\"list-group-item\"></a>');\n        $item.append(this.template(list[i]));\n        $item.data('item', list[i]);\n        items.push($item);\n      }\n\n      if (items.length) {\n        items[0].addClass('active');\n      }\n\n      return items;\n    },\n\n    search: function (keyword, callback) {\n      keyword = keyword || '';\n      callback();\n    },\n\n    init : function (layoutInfo) {\n      var self = this;\n\n      var $note = layoutInfo.holder();\n      var $popover = $('<div />').addClass('hint-group').css({\n        'position': 'absolute',\n        'max-height': 150,\n        'z-index' : 999,\n        'overflow' : 'hidden',\n        'display' : 'none',\n        'border' : '1px solid gray',\n        'border-radius' : '5px'\n      });\n\n      $popover.on('click', '.list-group-item', function HintItemClick() {\n        self.replace($popover);\n\n        $popover.hide();\n        $note.summernote('focus');\n      });\n\n      $(document).on('click', function HintClick() {\n        $popover.hide();\n      });\n\n      $note.on('summernote.keydown', function HintKeyDown(customEvent, nativeEvent) {\n        if ($popover.css('display') !== 'block') {\n          return true;\n        }\n\n        if (nativeEvent.keyCode === KEY.DOWN) {\n          nativeEvent.preventDefault();\n          self.moveDown($popover);\n        } else if (nativeEvent.keyCode === KEY.UP) {\n          nativeEvent.preventDefault();\n          self.moveUp($popover);\n        } else if (nativeEvent.keyCode === KEY.ENTER) {\n          nativeEvent.preventDefault();\n          self.replace($popover);\n\n          $popover.hide();\n          $note.summernote('focus');\n        }\n      });\n\n      var timer = null;\n      $note.on('summernote.keyup', function HintKeyUp(customEvent, nativeEvent) {\n        if (DROPDOWN_KEYCODES.indexOf(nativeEvent.keyCode) > -1) {\n          if (nativeEvent.keyCode === KEY.ENTER) {\n            if ($popover.css('display') === 'block') {\n              return false;\n            }\n          }\n\n        } else {\n\n          clearTimeout(timer);\n          timer = setTimeout(function () {\n            var range = $note.summernote('createRange');\n            var word = range.getWordRange();\n\n            self.searchKeyword(word.toString(), function (searchList) {\n              if (!searchList) {\n                $popover.hide();\n                return;\n              }\n\n              if (searchList && !searchList.length) {\n                $popover.hide();\n                return;\n              }\n\n              layoutInfo.popover().append($popover);\n\n              // popover below placeholder.\n              var rects = word.getClientRects();\n              var rect = rects[rects.length - 1];\n              $popover.html(self.createTemplate(searchList)).css({\n                left: rect.left,\n                top: rect.top + rect.height\n              }).data('wordRange', word).show();\n            });\n          }, self.throttle);\n\n        }\n      });\n\n      this.load($popover);\n    },\n\n    throttle : 50,\n\n    // FIXME Summernote doesn't support event pipeline yet.\n    //  - Plugin -> Base Code\n    events: {\n      ENTER: function (e, editor, layoutInfo) {\n\n        if (layoutInfo.popover().find('.hint-group').css('display') !== 'block') {\n          // apply default enter key\n          layoutInfo.holder().summernote('insertParagraph');\n        }\n\n        // prevent ENTER key\n        return true;\n      }\n    }\n  });\n}));\n"
  },
  {
    "path": "static/assets/plugins/summernote/plugin/summernote-ext-video.js",
    "content": "(function (factory) {\n  /* global define */\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define(['jquery'], factory);\n  } else {\n    // Browser globals: jQuery\n    factory(window.jQuery);\n  }\n}(function ($) {\n  // template\n  var tmpl = $.summernote.renderer.getTemplate();\n\n  // core functions: range, dom\n  var range = $.summernote.core.range;\n  var dom = $.summernote.core.dom;\n\n  /**\n   * createVideoNode\n   *  \n   * @member plugin.video\n   * @private\n   * @param {String} url\n   * @return {Node}\n   */\n  var createVideoNode = function (url) {\n    // video url patterns(youtube, instagram, vimeo, dailymotion, youku, mp4, ogg, webm)\n    var ytRegExp = /^(?:https?:\\/\\/)?(?:www\\.)?(?:youtu\\.be\\/|youtube\\.com\\/(?:embed\\/|v\\/|watch\\?v=|watch\\?.+&v=))((\\w|-){11})(?:\\S+)?$/;\n    var ytMatch = url.match(ytRegExp);\n\n    var igRegExp = /\\/\\/instagram.com\\/p\\/(.[a-zA-Z0-9]*)/;\n    var igMatch = url.match(igRegExp);\n\n    var vRegExp = /\\/\\/vine.co\\/v\\/(.[a-zA-Z0-9]*)/;\n    var vMatch = url.match(vRegExp);\n\n    var vimRegExp = /\\/\\/(player.)?vimeo.com\\/([a-z]*\\/)*([0-9]{6,11})[?]?.*/;\n    var vimMatch = url.match(vimRegExp);\n\n    var dmRegExp = /.+dailymotion.com\\/(video|hub)\\/([^_]+)[^#]*(#video=([^_&]+))?/;\n    var dmMatch = url.match(dmRegExp);\n\n    var youkuRegExp = /\\/\\/v\\.youku\\.com\\/v_show\\/id_(\\w+)=*\\.html/;\n    var youkuMatch = url.match(youkuRegExp);\n\n    var mp4RegExp = /^.+.(mp4|m4v)$/;\n    var mp4Match = url.match(mp4RegExp);\n\n    var oggRegExp = /^.+.(ogg|ogv)$/;\n    var oggMatch = url.match(oggRegExp);\n\n    var webmRegExp = /^.+.(webm)$/;\n    var webmMatch = url.match(webmRegExp);\n\n    var $video;\n    if (ytMatch && ytMatch[1].length === 11) {\n      var youtubeId = ytMatch[1];\n      $video = $('<iframe>')\n        .attr('frameborder', 0)\n        .attr('src', '//www.youtube.com/embed/' + youtubeId)\n        .attr('width', '640').attr('height', '360');\n    } else if (igMatch && igMatch[0].length) {\n      $video = $('<iframe>')\n        .attr('frameborder', 0)\n        .attr('src', igMatch[0] + '/embed/')\n        .attr('width', '612').attr('height', '710')\n        .attr('scrolling', 'no')\n        .attr('allowtransparency', 'true');\n    } else if (vMatch && vMatch[0].length) {\n      $video = $('<iframe>')\n        .attr('frameborder', 0)\n        .attr('src', vMatch[0] + '/embed/simple')\n        .attr('width', '600').attr('height', '600')\n        .attr('class', 'vine-embed');\n    } else if (vimMatch && vimMatch[3].length) {\n      $video = $('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>')\n        .attr('frameborder', 0)\n        .attr('src', '//player.vimeo.com/video/' + vimMatch[3])\n        .attr('width', '640').attr('height', '360');\n    } else if (dmMatch && dmMatch[2].length) {\n      $video = $('<iframe>')\n        .attr('frameborder', 0)\n        .attr('src', '//www.dailymotion.com/embed/video/' + dmMatch[2])\n        .attr('width', '640').attr('height', '360');\n    } else if (youkuMatch && youkuMatch[1].length) {\n      $video = $('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>')\n        .attr('frameborder', 0)\n        .attr('height', '498')\n        .attr('width', '510')\n        .attr('src', '//player.youku.com/embed/' + youkuMatch[1]);\n    } else if (mp4Match || oggMatch || webmMatch) {\n      $video = $('<video controls>')\n        .attr('src', url)\n        .attr('width', '640').attr('height', '360');\n    } else {\n      // this is not a known video link. Now what, Cat? Now what?\n      return false;\n    }\n\n    return $video[0];\n  };\n\n  /**\n   * @member plugin.video\n   * @private\n   * @param {jQuery} $editable\n   * @return {String}\n   */\n  var getTextOnRange = function ($editable) {\n    $editable.focus();\n\n    var rng = range.create();\n\n    // if range on anchor, expand range with anchor\n    if (rng.isOnAnchor()) {\n      var anchor = dom.ancestor(rng.sc, dom.isAnchor);\n      rng = range.createFromNode(anchor);\n    }\n\n    return rng.toString();\n  };\n\n  /**\n   * toggle button status\n   *  \n   * @member plugin.video\n   * @private\n   * @param {jQuery} $btn\n   * @param {Boolean} isEnable\n   */\n  var toggleBtn = function ($btn, isEnable) {\n    $btn.toggleClass('disabled', !isEnable);\n    $btn.attr('disabled', !isEnable);\n  };\n\n  /**\n   * Show video dialog and set event handlers on dialog controls.\n   *\n   * @member plugin.video\n   * @private\n   * @param {jQuery} $dialog\n   * @param {jQuery} $dialog\n   * @param {Object} text\n   * @return {Promise}\n   */\n  var showVideoDialog = function ($editable, $dialog, text) {\n    return $.Deferred(function (deferred) {\n      var $videoDialog = $dialog.find('.note-video-dialog');\n\n      var $videoUrl = $videoDialog.find('.note-video-url'),\n          $videoBtn = $videoDialog.find('.note-video-btn');\n\n      $videoDialog.one('shown.bs.modal', function () {\n        $videoUrl.val(text).on('input', function () {\n          toggleBtn($videoBtn, $videoUrl.val());\n        }).trigger('focus');\n\n        $videoBtn.click(function (event) {\n          event.preventDefault();\n\n          deferred.resolve($videoUrl.val());\n          $videoDialog.modal('hide');\n        });\n      }).one('hidden.bs.modal', function () {\n        $videoUrl.off('input');\n        $videoBtn.off('click');\n\n        if (deferred.state() === 'pending') {\n          deferred.reject();\n        }\n      }).modal('show');\n    });\n  };\n\n  /**\n   * @class plugin.video\n   *\n   * Video Plugin\n   *\n   * video plugin is to make embeded video tag.\n   *\n   * ### load script\n   *\n   * ```\n   * < script src=\"plugin/summernote-ext-video.js\"></script >\n   * ```\n   *\n   * ### use a plugin in toolbar\n   * ```\n   *    $(\"#editor\").summernote({\n   *    ...\n   *    toolbar : [\n   *        ['group', [ 'video' ]]\n   *    ]\n   *    ...    \n   *    });\n   * ```\n   */\n  $.summernote.addPlugin({\n    /** @property {String} name name of plugin */\n    name: 'video',\n    /**\n     * @property {Object} buttons\n     * @property {function(object): string} buttons.video\n     */\n    buttons: {\n      video: function (lang, options) {\n        return tmpl.iconButton(options.iconPrefix + 'youtube-play', {\n          event: 'showVideoDialog',\n          title: lang.video.video,\n          hide: true\n        });\n      }\n    },\n\n    /**\n     * @property {Object} dialogs\n     * @property {function(object, object): string} dialogs.video\n    */\n    dialogs: {\n      video: function (lang) {\n        var body = '<div class=\"form-group row-fluid\">' +\n                     '<label>' + lang.video.url + ' <small class=\"text-muted\">' + lang.video.providers + '</small></label>' +\n                     '<input class=\"note-video-url form-control span12\" type=\"text\" />' +\n                   '</div>';\n        var footer = '<button href=\"#\" class=\"btn btn-primary note-video-btn disabled\" disabled>' + lang.video.insert + '</button>';\n        return tmpl.dialog('note-video-dialog', lang.video.insert, body, footer);\n      }\n    },\n    /**\n     * @property {Object} events\n     * @property {Function} events.showVideoDialog\n     */\n    events: {\n      showVideoDialog: function (event, editor, layoutInfo) {\n        var $dialog = layoutInfo.dialog(),\n            $editable = layoutInfo.editable(),\n            text = getTextOnRange($editable);\n\n        // save current range\n        editor.saveRange($editable);\n\n        showVideoDialog($editable, $dialog, text).then(function (url) {\n          // when ok button clicked\n\n          // restore range\n          editor.restoreRange($editable);\n          \n          // build node\n          var $node = createVideoNode(url);\n          \n          if ($node) {\n            // insert video node\n            editor.insertNode($editable, $node);\n          }\n        }).fail(function () {\n          // when cancel button clicked\n          editor.restoreRange($editable);\n        });\n      }\n    },\n\n    // define language\n    langs: {\n      'en-US': {\n        video: {\n          video: 'Video',\n          videoLink: 'Video Link',\n          insert: 'Insert Video',\n          url: 'Video URL?',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion or Youku)'\n        }\n      },\n      'ar-AR': {\n        video: {\n          video: 'فيديو',\n          videoLink: 'رابط الفيديو',\n          insert: 'إدراج الفيديو',\n          url: 'رابط الفيديو',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion ou Youku)'\n        }\n      },\n      'ca-ES': {\n        video: {\n          video: 'Video',\n          videoLink: 'Enllaç del video',\n          insert: 'Inserir video',\n          url: 'URL del video?',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion, o Youku)'\n        }\n      },\n      'cs-CZ': {\n        video: {\n          video: 'Video',\n          videoLink: 'Odkaz videa',\n          insert: 'Vložit video',\n          url: 'URL videa?',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion nebo Youku)'\n        }\n      },\n      'da-DK': {\n        video: {\n          video: 'Video',\n          videoLink: 'Video Link',\n          insert: 'Indsæt Video',\n          url: 'Video URL?',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion eller Youku)'\n        }\n      },\n      'de-DE': {\n        video: {\n          video: 'Video',\n          videoLink: 'Video Link',\n          insert: 'Video einfügen',\n          url: 'Video URL?',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion, oder Youku)'\n        }\n      },\n      'es-ES': {\n        video: {\n          video: 'Video',\n          videoLink: 'Link del video',\n          insert: 'Insertar video',\n          url: '¿URL del video?',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion, o Youku)'\n        }\n      },\n      'es-EU': {\n        video: {\n          video: 'Bideoa',\n          videoLink: 'Bideorako esteka',\n          insert: 'Bideo berri bat txertatu',\n          url: 'Bideoaren URL helbidea',\n          providers: '(YouTube, Vimeo, Vine, Instagram, edo DailyMotion)'\n        }\n      },\n      'fa-IR': {\n        video: {\n          video: 'ویدیو',\n          videoLink: 'لینک ویدیو',\n          insert: 'افزودن ویدیو',\n          url: 'آدرس ویدیو ؟',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion, یا Youku)'\n        }\n      },\n      'fi-FI': {\n        video: {\n          video: 'Video',\n          videoLink: 'Linkki videoon',\n          insert: 'Lisää video',\n          url: 'Videon URL-osoite?',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion tai Youku)'\n        }\n      },\n      'fr-FR': {\n        video: {\n          video: 'Vidéo',\n          videoLink: 'Lien vidéo',\n          insert: 'Insérer une vidéo',\n          url: 'URL de la vidéo',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion ou Youku)'\n        }\n      },\n      'he-IL': {\n        video: {\n          video: 'סרטון',\n          videoLink: 'קישור לסרטון',\n          insert: 'הוסף סרטון',\n          url: 'קישור לסרטון',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion או Youku)'\n        }\n      },\n      'hu-HU': {\n        video: {\n          video: 'Videó',\n          videoLink: 'Videó hivatkozás',\n          insert: 'Videó beszúrása',\n          url: 'Videó URL címe',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion, vagy Youku)'\n        }\n      },\n      'id-ID': {\n        video: {\n          video: 'Video',\n          videoLink: 'Link video',\n          insert: 'Sisipkan video',\n          url: 'Tautan video',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion, atau Youku)'\n        }\n      },\n      'it-IT': {\n        video: {\n          video: 'Video',\n          videoLink: 'Collegamento ad un Video',\n          insert: 'Inserisci Video',\n          url: 'URL del Video',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion o Youku)'\n        }\n      },\n      'ja-JP': {\n        video: {\n          video: '動画',\n          videoLink: '動画リンク',\n          insert: '動画挿入',\n          url: '動画のURL',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion, Youku)'\n        }\n      },\n      'ko-KR': {\n        video: {\n          video: '동영상',\n          videoLink: '동영상 링크',\n          insert: '동영상 추가',\n          url: '동영상 URL',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion, Youku 사용 가능)'\n        }\n      },\n      'nb-NO': {\n        video: {\n          video: 'Video',\n          videoLink: 'Videolenke',\n          insert: 'Sett inn video',\n          url: 'Video-URL',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion eller Youku)'\n        }\n      },\n      'nl-NL': {\n        video: {\n          video: 'Video',\n          videoLink: 'Video link',\n          insert: 'Video invoegen',\n          url: 'URL van de video',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion of Youku)'\n        }\n      },\n      'pl-PL': {\n        video: {\n          video: 'Wideo',\n          videoLink: 'Adres wideo',\n          insert: 'Wstaw wideo',\n          url: 'Adres wideo',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion, lub Youku)'\n        }\n      },\n      'pt-BR': {\n        video: {\n          video: 'Vídeo',\n          videoLink: 'Link para vídeo',\n          insert: 'Inserir vídeo',\n          url: 'URL do vídeo?',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion, ou Youku)'\n        }\n      },\n      'ro-RO': {\n        video: {\n          video: 'Video',\n          videoLink: 'Link video',\n          insert: 'Inserează video',\n          url: 'URL video?',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion, sau Youku)'\n        }\n      },\n      'ru-RU': {\n        video: {\n          video: 'Видео',\n          videoLink: 'Ссылка на видео',\n          insert: 'Вставить видео',\n          url: 'URL видео',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion или Youku)'\n        }\n      },\n      'sk-SK': {\n        video: {\n          video: 'Video',\n          videoLink: 'Odkaz videa',\n          insert: 'Vložiť video',\n          url: 'URL videa?',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion nebo Youku)'\n        }\n      },\n      'sl-SI': {\n        video: {\n          video: 'Video',\n          videoLink: 'Video povezava',\n          insert: 'Vstavi video',\n          url: 'Povezava do videa',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion ali Youku)'\n        }\n      },\n      'sr-RS': {\n        video: {\n          video: 'Видео',\n          videoLink: 'Веза ка видеу',\n          insert: 'Уметни видео',\n          url: 'URL видео',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion или Youku)'\n        }\n      },\n      'sr-RS-Latin': {\n        video: {\n          video: 'Video',\n          videoLink: 'Veza ka videu',\n          insert: 'Umetni video',\n          url: 'URL video',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion ili Youku)'\n        }\n      },\n      'sv-SE': {\n        video: {\n          video: 'Filmklipp',\n          videoLink: 'Länk till filmklipp',\n          insert: 'Infoga filmklipp',\n          url: 'Länk till filmklipp',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion eller Youku)'\n        }\n      },\n      'th-TH': {\n        video: {\n          video: 'วีดีโอ',\n          videoLink: 'ลิงก์ของวีดีโอ',\n          insert: 'แทรกวีดีโอ',\n          url: 'ที่อยู่ URL ของวีดีโอ?',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion หรือ Youku)'\n        }\n      },\n      'tr-TR': {\n        video: {\n          video: 'Video',\n          videoLink: 'Video bağlantısı',\n          insert: 'Video ekle',\n          url: 'Video bağlantısı?',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion veya Youku)'\n        }\n      },\n      'uk-UA': {\n        video: {\n          video: 'Відео',\n          videoLink: 'Посилання на відео',\n          insert: 'Вставити відео',\n          url: 'URL відео',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion чи Youku)'\n        }\n      },\n      'vi-VN': {\n        video: {\n          video: 'Video',\n          videoLink: 'Đường Dẫn đến Video',\n          insert: 'Chèn Video',\n          url: 'URL',\n          providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion và Youku)'\n        }\n      },\n      'zh-CN': {\n        video: {\n          video: '视频',\n          videoLink: '视频链接',\n          insert: '插入视频',\n          url: '视频地址',\n          providers: '(优酷, Instagram, DailyMotion, Youtube等)'\n        }\n      },\n      'zh-TW': {\n        video: {\n          video: '影片',\n          videoLink: '影片連結',\n          insert: '插入影片',\n          url: '影片網址',\n          providers: '(優酷, Instagram, DailyMotion, Youtube等)'\n        }\n      }\n    }\n  });\n}));\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/css/elements.css",
    "content": "/*---------------------------------------------------\n    LESS Elements 0.9\n  ---------------------------------------------------\n    A set of useful LESS mixins\n    More info at: http://lesselements.com\n  ---------------------------------------------------*/\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/css/summernote.css",
    "content": "/*---------------------------------------------------\n    LESS Elements 0.9\n  ---------------------------------------------------\n    A set of useful LESS mixins\n    More info at: http://lesselements.com\n  ---------------------------------------------------*/\n/* Theme Variables\n ------------------------------------------*/\n/* Frame Mode Layout\n ------------------------------------------*/\n.note-editor {\n  border: 1px solid #a9a9a9;\n  position: relative;\n  overflow: hidden;\n  /* dropzone */\n  /* codeview mode */\n  /* fullscreen mode */\n  /* statusbar */\n}\n.note-editor .note-dropzone {\n  position: absolute;\n  display: none;\n  z-index: 100;\n  color: lightskyblue;\n  background-color: white;\n  opacity: 0.95;\n  pointer-event: none;\n}\n.note-editor .note-dropzone .note-dropzone-message {\n  display: table-cell;\n  vertical-align: middle;\n  text-align: center;\n  font-size: 28px;\n  font-weight: bold;\n}\n.note-editor .note-dropzone.hover {\n  color: #098ddf;\n}\n.note-editor.dragover .note-dropzone {\n  display: table;\n}\n.note-editor.codeview .note-editing-area .note-editable {\n  display: none;\n}\n.note-editor.codeview .note-editing-area .note-codable {\n  display: block;\n}\n.note-editor.fullscreen {\n  position: fixed;\n  top: 0;\n  left: 0;\n  width: 100%;\n  z-index: 1050;\n  /* bs3 modal-backdrop: 1030, bs2: 1040 */\n}\n.note-editor.fullscreen .note-editable {\n  background-color: white;\n}\n.note-editor.fullscreen .note-resizebar {\n  display: none;\n}\n.note-editor .note-editing-area {\n  position: relative;\n  overflow: hidden;\n  /* editable */\n  /* codeable */\n}\n.note-editor .note-editing-area .note-editable {\n  background-color: #fff;\n  color: #000;\n  padding: 10px;\n  overflow: auto;\n  outline: none;\n}\n.note-editor .note-editing-area .note-editable[contenteditable=true]:empty:not(:focus):before {\n  content: attr(data-placeholder);\n}\n.note-editor .note-editing-area .note-editable[contenteditable=\"false\"] {\n  background-color: #e5e5e5;\n}\n.note-editor .note-editing-area .note-codable {\n  display: none;\n  width: 100%;\n  padding: 10px;\n  border: none;\n  box-shadow: none;\n  font-family: Menlo, Monaco, monospace, sans-serif;\n  font-size: 14px;\n  color: #ccc;\n  background-color: #222;\n  resize: none;\n  /* override BS2 default style */\n  -ms-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  -webkit-box-sizing: border-box;\n  box-sizing: border-box;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n  margin-bottom: 0;\n}\n.note-editor .note-statusbar {\n  background-color: #f5f5f5;\n}\n.note-editor .note-statusbar .note-resizebar {\n  padding-top: 1px;\n  height: 8px;\n  width: 100%;\n  cursor: ns-resize;\n}\n.note-editor .note-statusbar .note-resizebar .note-icon-bar {\n  width: 20px;\n  margin: 1px auto;\n  border-top: 1px solid #a9a9a9;\n}\n/* Air Mode Layout\n------------------------------------------*/\n.note-air-editor {\n  outline: none;\n}\n/* Popover\n------------------------------------------*/\n.note-popover .popover {\n  max-width: none;\n}\n.note-popover .popover .popover-content a {\n  display: inline-block;\n  max-width: 200px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  /* for FF */\n  vertical-align: middle;\n  /* for FF */\n}\n.note-popover .popover .arrow {\n  left: 20px;\n}\n/* Popover and Toolbar (Button container)\n------------------------------------------*/\n.note-popover .popover .popover-content,\n.panel-heading.note-toolbar {\n  margin: 0;\n  padding: 0 0 5px 5px;\n  /* dropdown-menu for toolbar and popover */\n  /* color palette for toolbar and popover */\n}\n.note-popover .popover .popover-content > .btn-group,\n.panel-heading.note-toolbar > .btn-group {\n  margin-top: 5px;\n  margin-left: 0;\n  margin-right: 5px;\n}\n.note-popover .popover .popover-content .btn-group .note-table,\n.panel-heading.note-toolbar .btn-group .note-table {\n  min-width: 0;\n  padding: 5px;\n}\n.note-popover .popover .popover-content .btn-group .note-table .note-dimension-picker,\n.panel-heading.note-toolbar .btn-group .note-table .note-dimension-picker {\n  font-size: 18px;\n}\n.note-popover .popover .popover-content .btn-group .note-table .note-dimension-picker .note-dimension-picker-mousecatcher,\n.panel-heading.note-toolbar .btn-group .note-table .note-dimension-picker .note-dimension-picker-mousecatcher {\n  position: absolute !important;\n  z-index: 3;\n  width: 10em;\n  height: 10em;\n  cursor: pointer;\n}\n.note-popover .popover .popover-content .btn-group .note-table .note-dimension-picker .note-dimension-picker-unhighlighted,\n.panel-heading.note-toolbar .btn-group .note-table .note-dimension-picker .note-dimension-picker-unhighlighted {\n  position: relative !important;\n  z-index: 1;\n  width: 5em;\n  height: 5em;\n  background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIj4+Pjp6ekKlAqjAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKhmnaJzPAAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC') repeat;\n}\n.note-popover .popover .popover-content .btn-group .note-table .note-dimension-picker .note-dimension-picker-highlighted,\n.panel-heading.note-toolbar .btn-group .note-table .note-dimension-picker .note-dimension-picker-highlighted {\n  position: absolute !important;\n  z-index: 2;\n  width: 1em;\n  height: 1em;\n  background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIjd6vvD2f9LKLW+AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKwNDEVT0AAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC') repeat;\n}\n.note-popover .popover .popover-content .note-style h1,\n.panel-heading.note-toolbar .note-style h1,\n.note-popover .popover .popover-content .note-style h2,\n.panel-heading.note-toolbar .note-style h2,\n.note-popover .popover .popover-content .note-style h3,\n.panel-heading.note-toolbar .note-style h3,\n.note-popover .popover .popover-content .note-style h4,\n.panel-heading.note-toolbar .note-style h4,\n.note-popover .popover .popover-content .note-style h5,\n.panel-heading.note-toolbar .note-style h5,\n.note-popover .popover .popover-content .note-style h6,\n.panel-heading.note-toolbar .note-style h6,\n.note-popover .popover .popover-content .note-style blockquote,\n.panel-heading.note-toolbar .note-style blockquote {\n  margin: 0;\n}\n.note-popover .popover .popover-content .note-color .dropdown-toggle,\n.panel-heading.note-toolbar .note-color .dropdown-toggle {\n  width: 20px;\n  padding-left: 5px;\n}\n.note-popover .popover .popover-content .note-color .dropdown-menu,\n.panel-heading.note-toolbar .note-color .dropdown-menu {\n  min-width: 340px;\n}\n.note-popover .popover .popover-content .note-color .dropdown-menu .btn-group,\n.panel-heading.note-toolbar .note-color .dropdown-menu .btn-group {\n  margin: 0;\n}\n.note-popover .popover .popover-content .note-color .dropdown-menu .btn-group:first-child,\n.panel-heading.note-toolbar .note-color .dropdown-menu .btn-group:first-child {\n  margin: 0 5px;\n}\n.note-popover .popover .popover-content .note-color .dropdown-menu .btn-group .note-palette-title,\n.panel-heading.note-toolbar .note-color .dropdown-menu .btn-group .note-palette-title {\n  font-size: 12px;\n  margin: 2px 7px;\n  text-align: center;\n  border-bottom: 1px solid #eee;\n}\n.note-popover .popover .popover-content .note-color .dropdown-menu .btn-group .note-color-reset,\n.panel-heading.note-toolbar .note-color .dropdown-menu .btn-group .note-color-reset {\n  font-size: 11px;\n  margin: 3px;\n  padding: 0 3px;\n  cursor: pointer;\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  border-radius: 5px;\n}\n.note-popover .popover .popover-content .note-color .dropdown-menu .btn-group .note-color-row,\n.panel-heading.note-toolbar .note-color .dropdown-menu .btn-group .note-color-row {\n  height: 20px;\n}\n.note-popover .popover .popover-content .note-color .dropdown-menu .btn-group .note-color-reset:hover,\n.panel-heading.note-toolbar .note-color .dropdown-menu .btn-group .note-color-reset:hover {\n  background: #eee;\n}\n.note-popover .popover .popover-content .note-para .dropdown-menu,\n.panel-heading.note-toolbar .note-para .dropdown-menu {\n  min-width: 216px;\n  padding: 5px;\n}\n.note-popover .popover .popover-content .note-para .dropdown-menu > div:first-child,\n.panel-heading.note-toolbar .note-para .dropdown-menu > div:first-child {\n  margin-right: 5px;\n}\n.note-popover .popover .popover-content .dropdown-menu,\n.panel-heading.note-toolbar .dropdown-menu {\n  min-width: 90px;\n  /* dropdown-menu right position */\n  /* http://forrst.com/posts/Bootstrap_right_positioned_dropdown-2KB */\n  /* dropdown-menu for selectbox */\n}\n.note-popover .popover .popover-content .dropdown-menu.right,\n.panel-heading.note-toolbar .dropdown-menu.right {\n  right: 0;\n  left: auto;\n}\n.note-popover .popover .popover-content .dropdown-menu.right::before,\n.panel-heading.note-toolbar .dropdown-menu.right::before {\n  right: 9px;\n  left: auto !important;\n}\n.note-popover .popover .popover-content .dropdown-menu.right::after,\n.panel-heading.note-toolbar .dropdown-menu.right::after {\n  right: 10px;\n  left: auto !important;\n}\n.note-popover .popover .popover-content .dropdown-menu.note-check li a i,\n.panel-heading.note-toolbar .dropdown-menu.note-check li a i {\n  color: deepskyblue;\n  visibility: hidden;\n}\n.note-popover .popover .popover-content .dropdown-menu.note-check li a.checked i,\n.panel-heading.note-toolbar .dropdown-menu.note-check li a.checked i {\n  visibility: visible;\n}\n.note-popover .popover .popover-content .note-fontsize-10,\n.panel-heading.note-toolbar .note-fontsize-10 {\n  font-size: 10px;\n}\n.note-popover .popover .popover-content .note-color-palette,\n.panel-heading.note-toolbar .note-color-palette {\n  line-height: 1;\n}\n.note-popover .popover .popover-content .note-color-palette div .note-color-btn,\n.panel-heading.note-toolbar .note-color-palette div .note-color-btn {\n  width: 20px;\n  height: 20px;\n  padding: 0;\n  margin: 0;\n  border: 1px solid #fff;\n}\n.note-popover .popover .popover-content .note-color-palette div .note-color-btn:hover,\n.panel-heading.note-toolbar .note-color-palette div .note-color-btn:hover {\n  border: 1px solid #000;\n}\n/* Dialog\n------------------------------------------*/\n.note-dialog > div {\n  display: none;\n  /* BS2's hide pacth. */\n}\n.note-dialog .form-group {\n  /* overwrite BS's form-horizontal minus margins */\n  margin-left: 0;\n  margin-right: 0;\n}\n.note-dialog .note-modal-form {\n  margin: 0;\n  /* overwrite BS2's form margin bottom */\n}\n.note-dialog .note-image-dialog .note-dropzone {\n  min-height: 100px;\n  font-size: 30px;\n  line-height: 4;\n  /* vertical-align */\n  color: lightgray;\n  text-align: center;\n  border: 4px dashed lightgray;\n  margin-bottom: 10px;\n}\n.note-dialog .note-help-dialog {\n  font-size: 12px;\n  color: #ccc;\n  background-color: #222 !important;\n  -webkit-opacity: 0.9;\n  -khtml-opacity: 0.9;\n  -moz-opacity: 0.9;\n  opacity: 0.9;\n  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(opacity=90);\n  filter: alpha(opacity=90);\n  /* BS2's background pacth. */\n  background: transparent;\n  border: none;\n}\n.note-dialog .note-help-dialog .modal-content {\n  background: transparent;\n  border: 1px solid white;\n  -webkit-box-shadow: none;\n  -moz-box-shadow: none;\n  box-shadow: none;\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  border-radius: 5px;\n}\n.note-dialog .note-help-dialog a {\n  font-size: 12px;\n  color: white;\n}\n.note-dialog .note-help-dialog .title {\n  color: white;\n  font-size: 14px;\n  font-weight: bold;\n  padding-bottom: 5px;\n  margin-bottom: 10px;\n  border-bottom: white 1px solid;\n}\n.note-dialog .note-help-dialog .modal-close {\n  font-size: 14px;\n  color: #dddd00;\n  cursor: pointer;\n}\n.note-dialog .note-help-dialog .text-center {\n  margin: 10px 0 0;\n}\n.note-dialog .note-help-dialog .note-shortcut {\n  padding-top: 8px;\n  padding-bottom: 8px;\n}\n.note-dialog .note-help-dialog .note-shortcut-row {\n  margin-right: -5px;\n  margin-left: -5px;\n}\n.note-dialog .note-help-dialog .note-shortcut-col {\n  padding-right: 5px;\n  padding-left: 5px;\n}\n.note-dialog .note-help-dialog .note-shortcut-title {\n  font-size: 13px;\n  font-weight: bold;\n  color: #dddd00;\n}\n.note-dialog .note-help-dialog .note-shortcut-key {\n  font-family: \"Courier New\";\n  color: #dddd00;\n  text-align: right;\n}\n/* Handle\n------------------------------------------*/\n.note-handle {\n  /* control selection */\n}\n.note-handle .note-control-selection {\n  position: absolute;\n  display: none;\n  border: 1px solid black;\n}\n.note-handle .note-control-selection > div {\n  position: absolute;\n}\n.note-handle .note-control-selection .note-control-selection-bg {\n  width: 100%;\n  height: 100%;\n  background-color: black;\n  -webkit-opacity: 0.3;\n  -khtml-opacity: 0.3;\n  -moz-opacity: 0.3;\n  opacity: 0.3;\n  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(opacity=30);\n  filter: alpha(opacity=30);\n}\n.note-handle .note-control-selection .note-control-handle {\n  width: 7px;\n  height: 7px;\n  border: 1px solid black;\n}\n.note-handle .note-control-selection .note-control-holder {\n  width: 7px;\n  height: 7px;\n  border: 1px solid black;\n}\n.note-handle .note-control-selection .note-control-sizing {\n  width: 7px;\n  height: 7px;\n  border: 1px solid black;\n  background-color: white;\n}\n.note-handle .note-control-selection .note-control-nw {\n  top: -5px;\n  left: -5px;\n  border-right: none;\n  border-bottom: none;\n}\n.note-handle .note-control-selection .note-control-ne {\n  top: -5px;\n  right: -5px;\n  border-bottom: none;\n  border-left: none;\n}\n.note-handle .note-control-selection .note-control-sw {\n  bottom: -5px;\n  left: -5px;\n  border-top: none;\n  border-right: none;\n}\n.note-handle .note-control-selection .note-control-se {\n  right: -5px;\n  bottom: -5px;\n  cursor: se-resize;\n}\n.note-handle .note-control-selection .note-control-se.note-control-holder {\n  cursor: default;\n  border-top: none;\n  border-left: none;\n}\n.note-handle .note-control-selection .note-control-selection-info {\n  right: 0;\n  bottom: 0;\n  padding: 5px;\n  margin: 5px;\n  color: white;\n  background-color: black;\n  font-size: 12px;\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  border-radius: 5px;\n  -webkit-opacity: 0.7;\n  -khtml-opacity: 0.7;\n  -moz-opacity: 0.7;\n  opacity: 0.7;\n  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(opacity=70);\n  filter: alpha(opacity=70);\n}\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/EventHandler.js",
    "content": "define([\n  'summernote/core/agent',\n  'summernote/core/func',\n  'summernote/core/dom',\n  'summernote/core/async',\n  'summernote/core/key',\n  'summernote/core/list',\n  'summernote/editing/History',\n  'summernote/module/Editor',\n  'summernote/module/Toolbar',\n  'summernote/module/Statusbar',\n  'summernote/module/Popover',\n  'summernote/module/Handle',\n  'summernote/module/Fullscreen',\n  'summernote/module/Codeview',\n  'summernote/module/DragAndDrop',\n  'summernote/module/Clipboard',\n  'summernote/module/LinkDialog',\n  'summernote/module/ImageDialog',\n  'summernote/module/HelpDialog'\n], function (agent, func, dom, async, key, list, History,\n             Editor, Toolbar, Statusbar, Popover, Handle, Fullscreen, Codeview,\n             DragAndDrop, Clipboard, LinkDialog, ImageDialog, HelpDialog) {\n\n  /**\n   * @class EventHandler\n   *\n   * EventHandler\n   *  - TODO: new instance per a editor\n   */\n  var EventHandler = function () {\n    var self = this;\n\n    /**\n     * Modules\n     */\n    var modules = this.modules = {\n      editor: new Editor(this),\n      toolbar: new Toolbar(this),\n      statusbar: new Statusbar(this),\n      popover: new Popover(this),\n      handle: new Handle(this),\n      fullscreen: new Fullscreen(this),\n      codeview: new Codeview(this),\n      dragAndDrop: new DragAndDrop(this),\n      clipboard: new Clipboard(this),\n      linkDialog: new LinkDialog(this),\n      imageDialog: new ImageDialog(this),\n      helpDialog: new HelpDialog(this)\n    };\n\n    /**\n     * invoke module's method\n     *\n     * @param {String} moduleAndMethod - ex) 'editor.redo'\n     * @param {...*} arguments - arguments of method\n     * @return {*}\n     */\n    this.invoke = function () {\n      var moduleAndMethod = list.head(list.from(arguments));\n      var args = list.tail(list.from(arguments));\n\n      var splits = moduleAndMethod.split('.');\n      var hasSeparator = splits.length > 1;\n      var moduleName = hasSeparator && list.head(splits);\n      var methodName = hasSeparator ? list.last(splits) : list.head(splits);\n\n      var module = this.getModule(moduleName);\n      var method = module[methodName];\n\n      return method && method.apply(module, args);\n    };\n\n    /**\n     * returns module\n     *\n     * @param {String} moduleName - name of module\n     * @return {Module} - defaults is editor\n     */\n    this.getModule = function (moduleName) {\n      return this.modules[moduleName] || this.modules.editor;\n    };\n\n    /**\n     * @param {jQuery} $holder\n     * @param {Object} callbacks\n     * @param {String} eventNamespace\n     * @returns {Function}\n     */\n    var bindCustomEvent = this.bindCustomEvent = function ($holder, callbacks, eventNamespace) {\n      return function () {\n        var callback = callbacks[func.namespaceToCamel(eventNamespace, 'on')];\n        if (callback) {\n          callback.apply($holder[0], arguments);\n        }\n        return $holder.trigger('summernote.' + eventNamespace, arguments);\n      };\n    };\n\n    /**\n     * insert Images from file array.\n     *\n     * @private\n     * @param {Object} layoutInfo\n     * @param {File[]} files\n     */\n    this.insertImages = function (layoutInfo, files) {\n      var $editor = layoutInfo.editor(),\n          $editable = layoutInfo.editable(),\n          $holder = layoutInfo.holder();\n\n      var callbacks = $editable.data('callbacks');\n      var options = $editor.data('options');\n\n      // If onImageUpload options setted\n      if (callbacks.onImageUpload) {\n        bindCustomEvent($holder, callbacks, 'image.upload')(files);\n      // else insert Image as dataURL\n      } else {\n        $.each(files, function (idx, file) {\n          var filename = file.name;\n          if (options.maximumImageFileSize && options.maximumImageFileSize < file.size) {\n            bindCustomEvent($holder, callbacks, 'image.upload.error')(options.langInfo.image.maximumFileSizeError);\n          } else {\n            async.readFileAsDataURL(file).then(function (sDataURL) {\n              modules.editor.insertImage($editable, sDataURL, filename);\n            }).fail(function () {\n              bindCustomEvent($holder, callbacks, 'image.upload.error')(options.langInfo.image.maximumFileSizeError);\n            });\n          }\n        });\n      }\n    };\n\n    var commands = {\n      /**\n       * @param {Object} layoutInfo\n       */\n      showLinkDialog: function (layoutInfo) {\n        modules.linkDialog.show(layoutInfo);\n      },\n\n      /**\n       * @param {Object} layoutInfo\n       */\n      showImageDialog: function (layoutInfo) {\n        modules.imageDialog.show(layoutInfo);\n      },\n\n      /**\n       * @param {Object} layoutInfo\n       */\n      showHelpDialog: function (layoutInfo) {\n        modules.helpDialog.show(layoutInfo);\n      },\n\n      /**\n       * @param {Object} layoutInfo\n       */\n      fullscreen: function (layoutInfo) {\n        modules.fullscreen.toggle(layoutInfo);\n      },\n\n      /**\n       * @param {Object} layoutInfo\n       */\n      codeview: function (layoutInfo) {\n        modules.codeview.toggle(layoutInfo);\n      }\n    };\n\n    var hMousedown = function (event) {\n      //preventDefault Selection for FF, IE8+\n      if (dom.isImg(event.target)) {\n        event.preventDefault();\n      }\n    };\n\n    var hKeyupAndMouseup = function (event) {\n      var layoutInfo = dom.makeLayoutInfo(event.currentTarget || event.target);\n      modules.editor.removeBogus(layoutInfo.editable());\n      hToolbarAndPopoverUpdate(event);\n    };\n\n    /**\n     * update sytle info\n     * @param {Object} styleInfo\n     * @param {Object} layoutInfo\n     */\n    this.updateStyleInfo = function (styleInfo, layoutInfo) {\n      if (!styleInfo) {\n        return;\n      }\n      var isAirMode = layoutInfo.editor().data('options').airMode;\n      if (!isAirMode) {\n        modules.toolbar.update(layoutInfo.toolbar(), styleInfo);\n      }\n\n      modules.popover.update(layoutInfo.popover(), styleInfo, isAirMode);\n      modules.handle.update(layoutInfo.handle(), styleInfo, isAirMode);\n    };\n\n    var hToolbarAndPopoverUpdate = function (event) {\n      var target = event.target;\n      // delay for range after mouseup\n      setTimeout(function () {\n        var layoutInfo = dom.makeLayoutInfo(target);\n        var styleInfo = modules.editor.currentStyle(target);\n        self.updateStyleInfo(styleInfo, layoutInfo);\n      }, 0);\n    };\n\n    var hScroll = function (event) {\n      var layoutInfo = dom.makeLayoutInfo(event.currentTarget || event.target);\n      //hide popover and handle when scrolled\n      modules.popover.hide(layoutInfo.popover());\n      modules.handle.hide(layoutInfo.handle());\n    };\n\n    var hToolbarAndPopoverMousedown = function (event) {\n      // prevent default event when insertTable (FF, Webkit)\n      var $btn = $(event.target).closest('[data-event]');\n      if ($btn.length) {\n        event.preventDefault();\n      }\n    };\n\n    var hToolbarAndPopoverClick = function (event) {\n      var $btn = $(event.target).closest('[data-event]');\n\n      if (!$btn.length) {\n        return;\n      }\n\n      var eventName = $btn.attr('data-event'),\n          value = $btn.attr('data-value'),\n          hide = $btn.attr('data-hide');\n\n      var layoutInfo = dom.makeLayoutInfo(event.target);\n\n      // before command: detect control selection element($target)\n      var $target;\n      if ($.inArray(eventName, ['resize', 'floatMe', 'removeMedia', 'imageShape']) !== -1) {\n        var $selection = layoutInfo.handle().find('.note-control-selection');\n        $target = $($selection.data('target'));\n      }\n\n      // If requested, hide the popover when the button is clicked.\n      // Useful for things like showHelpDialog.\n      if (hide) {\n        $btn.parents('.popover').hide();\n      }\n\n      if ($.isFunction($.summernote.pluginEvents[eventName])) {\n        $.summernote.pluginEvents[eventName](event, modules.editor, layoutInfo, value);\n      } else if (modules.editor[eventName]) { // on command\n        var $editable = layoutInfo.editable();\n        $editable.focus();\n        modules.editor[eventName]($editable, value, $target);\n        event.preventDefault();\n      } else if (commands[eventName]) {\n        commands[eventName].call(this, layoutInfo);\n        event.preventDefault();\n      }\n\n      // after command\n      if ($.inArray(eventName, ['backColor', 'foreColor']) !== -1) {\n        var options = layoutInfo.editor().data('options', options);\n        var module = options.airMode ? modules.popover : modules.toolbar;\n        module.updateRecentColor(list.head($btn), eventName, value);\n      }\n\n      hToolbarAndPopoverUpdate(event);\n    };\n\n    var PX_PER_EM = 18;\n    var hDimensionPickerMove = function (event, options) {\n      var $picker = $(event.target.parentNode); // target is mousecatcher\n      var $dimensionDisplay = $picker.next();\n      var $catcher = $picker.find('.note-dimension-picker-mousecatcher');\n      var $highlighted = $picker.find('.note-dimension-picker-highlighted');\n      var $unhighlighted = $picker.find('.note-dimension-picker-unhighlighted');\n\n      var posOffset;\n      // HTML5 with jQuery - e.offsetX is undefined in Firefox\n      if (event.offsetX === undefined) {\n        var posCatcher = $(event.target).offset();\n        posOffset = {\n          x: event.pageX - posCatcher.left,\n          y: event.pageY - posCatcher.top\n        };\n      } else {\n        posOffset = {\n          x: event.offsetX,\n          y: event.offsetY\n        };\n      }\n\n      var dim = {\n        c: Math.ceil(posOffset.x / PX_PER_EM) || 1,\n        r: Math.ceil(posOffset.y / PX_PER_EM) || 1\n      };\n\n      $highlighted.css({ width: dim.c + 'em', height: dim.r + 'em' });\n      $catcher.attr('data-value', dim.c + 'x' + dim.r);\n\n      if (3 < dim.c && dim.c < options.insertTableMaxSize.col) {\n        $unhighlighted.css({ width: dim.c + 1 + 'em'});\n      }\n\n      if (3 < dim.r && dim.r < options.insertTableMaxSize.row) {\n        $unhighlighted.css({ height: dim.r + 1 + 'em'});\n      }\n\n      $dimensionDisplay.html(dim.c + ' x ' + dim.r);\n    };\n    \n    /**\n     * bind KeyMap on keydown\n     *\n     * @param {Object} layoutInfo\n     * @param {Object} keyMap\n     */\n    this.bindKeyMap = function (layoutInfo, keyMap) {\n      var $editor = layoutInfo.editor();\n      var $editable = layoutInfo.editable();\n\n      $editable.on('keydown', function (event) {\n        var keys = [];\n\n        // modifier\n        if (event.metaKey) { keys.push('CMD'); }\n        if (event.ctrlKey && !event.altKey) { keys.push('CTRL'); }\n        if (event.shiftKey) { keys.push('SHIFT'); }\n\n        // keycode\n        var keyName = key.nameFromCode[event.keyCode];\n        if (keyName) {\n          keys.push(keyName);\n        }\n\n        var pluginEvent;\n        var keyString = keys.join('+');\n        var eventName = keyMap[keyString];\n        if (eventName) {\n          // FIXME Summernote doesn't support event pipeline yet.\n          //  - Plugin -> Base Code\n          pluginEvent = $.summernote.pluginEvents[keyString];\n          if ($.isFunction(pluginEvent)) {\n            if (pluginEvent(event, modules.editor, layoutInfo)) {\n              return false;\n            }\n          }\n\n          pluginEvent = $.summernote.pluginEvents[eventName];\n\n          if ($.isFunction(pluginEvent)) {\n            pluginEvent(event, modules.editor, layoutInfo);\n          } else if (modules.editor[eventName]) {\n            modules.editor[eventName]($editable, $editor.data('options'));\n            event.preventDefault();\n          } else if (commands[eventName]) {\n            commands[eventName].call(this, layoutInfo);\n            event.preventDefault();\n          }\n        } else if (key.isEdit(event.keyCode)) {\n          modules.editor.afterCommand($editable);\n        }\n      });\n    };\n\n    /**\n     * attach eventhandler\n     *\n     * @param {Object} layoutInfo - layout Informations\n     * @param {Object} options - user options include custom event handlers\n     */\n    this.attach = function (layoutInfo, options) {\n      // handlers for editable\n      if (options.shortcuts) {\n        this.bindKeyMap(layoutInfo, options.keyMap[agent.isMac ? 'mac' : 'pc']);\n      }\n      layoutInfo.editable().on('mousedown', hMousedown);\n      layoutInfo.editable().on('keyup mouseup', hKeyupAndMouseup);\n      layoutInfo.editable().on('scroll', hScroll);\n\n      // handler for clipboard\n      modules.clipboard.attach(layoutInfo, options);\n\n      // handler for handle and popover\n      modules.handle.attach(layoutInfo, options);\n      layoutInfo.popover().on('click', hToolbarAndPopoverClick);\n      layoutInfo.popover().on('mousedown', hToolbarAndPopoverMousedown);\n\n      // handler for drag and drop\n      modules.dragAndDrop.attach(layoutInfo, options);\n\n      // handlers for frame mode (toolbar, statusbar)\n      if (!options.airMode) {\n        // handler for toolbar\n        layoutInfo.toolbar().on('click', hToolbarAndPopoverClick);\n        layoutInfo.toolbar().on('mousedown', hToolbarAndPopoverMousedown);\n\n        // handler for statusbar\n        modules.statusbar.attach(layoutInfo, options);\n      }\n\n      // handler for table dimension\n      var $catcherContainer = options.airMode ? layoutInfo.popover() :\n                                                layoutInfo.toolbar();\n      var $catcher = $catcherContainer.find('.note-dimension-picker-mousecatcher');\n      $catcher.css({\n        width: options.insertTableMaxSize.col + 'em',\n        height: options.insertTableMaxSize.row + 'em'\n      }).on('mousemove', function (event) {\n        hDimensionPickerMove(event, options);\n      });\n\n      // save options on editor\n      layoutInfo.editor().data('options', options);\n\n      // ret styleWithCSS for backColor / foreColor clearing with 'inherit'.\n      if (!agent.isMSIE) {\n        // [workaround] for Firefox\n        //  - protect FF Error: NS_ERROR_FAILURE: Failure\n        setTimeout(function () {\n          document.execCommand('styleWithCSS', 0, options.styleWithSpan);\n        }, 0);\n      }\n\n      // History\n      var history = new History(layoutInfo.editable());\n      layoutInfo.editable().data('NoteHistory', history);\n\n      // All editor status will be saved on editable with jquery's data\n      // for support multiple editor with singleton object.\n      layoutInfo.editable().data('callbacks', {\n        onInit: options.onInit,\n        onFocus: options.onFocus,\n        onBlur: options.onBlur,\n        onKeydown: options.onKeydown,\n        onKeyup: options.onKeyup,\n        onMousedown: options.onMousedown,\n        onEnter: options.onEnter,\n        onPaste: options.onPaste,\n        onBeforeCommand: options.onBeforeCommand,\n        onChange: options.onChange,\n        onImageUpload: options.onImageUpload,\n        onImageUploadError: options.onImageUploadError,\n        onMediaDelete: options.onMediaDelete,\n        onToolbarClick: options.onToolbarClick\n      });\n\n      var styleInfo = modules.editor.styleFromNode(layoutInfo.editable());\n      this.updateStyleInfo(styleInfo, layoutInfo);\n    };\n\n    /**\n     * attach jquery custom event\n     *\n     * @param {Object} layoutInfo - layout Informations\n     */\n    this.attachCustomEvent = function (layoutInfo, options) {\n      var $holder = layoutInfo.holder();\n      var $editable = layoutInfo.editable();\n      var callbacks = $editable.data('callbacks');\n\n      $editable.focus(bindCustomEvent($holder, callbacks, 'focus'));\n      $editable.blur(bindCustomEvent($holder, callbacks, 'blur'));\n\n      $editable.keydown(function (event) {\n        if (event.keyCode === key.code.ENTER) {\n          bindCustomEvent($holder, callbacks, 'enter').call(this, event);\n        }\n        bindCustomEvent($holder, callbacks, 'keydown').call(this, event);\n      });\n      $editable.keyup(bindCustomEvent($holder, callbacks, 'keyup'));\n\n      $editable.on('mousedown', bindCustomEvent($holder, callbacks, 'mousedown'));\n      $editable.on('mouseup', bindCustomEvent($holder, callbacks, 'mouseup'));\n      $editable.on('scroll', bindCustomEvent($holder, callbacks, 'scroll'));\n\n      $editable.on('paste', bindCustomEvent($holder, callbacks, 'paste'));\n      \n      // [workaround] IE doesn't have input events for contentEditable\n      //  - see: https://goo.gl/4bfIvA\n      var changeEventName = agent.isMSIE ? 'DOMCharacterDataModified DOMSubtreeModified DOMNodeInserted' : 'input';\n      $editable.on(changeEventName, function () {\n        bindCustomEvent($holder, callbacks, 'change')($editable.html(), $editable);\n      });\n\n      if (!options.airMode) {\n        layoutInfo.toolbar().click(bindCustomEvent($holder, callbacks, 'toolbar.click'));\n        layoutInfo.popover().click(bindCustomEvent($holder, callbacks, 'popover.click'));\n      }\n\n      // Textarea: auto filling the code before form submit.\n      if (dom.isTextarea(list.head($holder))) {\n        $holder.closest('form').submit(function (e) {\n          layoutInfo.holder().val(layoutInfo.holder().code());\n          bindCustomEvent($holder, callbacks, 'submit').call(this, e, $holder.code());\n        });\n      }\n\n      // textarea auto sync\n      if (dom.isTextarea(list.head($holder)) && options.textareaAutoSync) {\n        $holder.on('summernote.change', function () {\n          layoutInfo.holder().val(layoutInfo.holder().code());\n        });\n      }\n\n      // fire init event\n      bindCustomEvent($holder, callbacks, 'init')(layoutInfo);\n\n      // fire plugin init event\n      for (var i = 0, len = $.summernote.plugins.length; i < len; i++) {\n        if ($.isFunction($.summernote.plugins[i].init)) {\n          $.summernote.plugins[i].init(layoutInfo);\n        }\n      }\n    };\n      \n    this.detach = function (layoutInfo, options) {\n      layoutInfo.holder().off();\n      layoutInfo.editable().off();\n\n      layoutInfo.popover().off();\n      layoutInfo.handle().off();\n      layoutInfo.dialog().off();\n\n      if (!options.airMode) {\n        layoutInfo.dropzone().off();\n        layoutInfo.toolbar().off();\n        layoutInfo.statusbar().off();\n      }\n    };\n  };\n\n  return EventHandler;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/Renderer.js",
    "content": "define([\n  'summernote/core/agent',\n  'summernote/core/dom',\n  'summernote/core/func',\n  'summernote/core/list'\n], function (agent, dom, func, list) {\n  /**\n   * @class Renderer\n   *\n   * renderer\n   *\n   * rendering toolbar and editable\n   */\n  var Renderer = function () {\n\n    /**\n     * bootstrap button template\n     * @private\n     * @param {String} label button name\n     * @param {Object} [options] button options\n     * @param {String} [options.event] data-event\n     * @param {String} [options.className] button's class name\n     * @param {String} [options.value] data-value\n     * @param {String} [options.title] button's title for popup\n     * @param {String} [options.dropdown] dropdown html\n     * @param {String} [options.hide] data-hide\n     */\n    var tplButton = function (label, options) {\n      var event = options.event;\n      var value = options.value;\n      var title = options.title;\n      var className = options.className;\n      var dropdown = options.dropdown;\n      var hide = options.hide;\n\n      return (dropdown ? '<div class=\"btn-group' +\n               (className ? ' ' + className : '') + '\">' : '') +\n               '<button type=\"button\"' +\n                 ' class=\"btn btn-default btn-sm' +\n                   ((!dropdown && className) ? ' ' + className : '') +\n                   (dropdown ? ' dropdown-toggle' : '') +\n                 '\"' +\n                 (dropdown ? ' data-toggle=\"dropdown\"' : '') +\n                 (title ? ' title=\"' + title + '\"' : '') +\n                 (event ? ' data-event=\"' + event + '\"' : '') +\n                 (value ? ' data-value=\\'' + value + '\\'' : '') +\n                 (hide ? ' data-hide=\\'' + hide + '\\'' : '') +\n                 ' tabindex=\"-1\">' +\n                 label +\n                 (dropdown ? ' <span class=\"caret\"></span>' : '') +\n               '</button>' +\n               (dropdown || '') +\n             (dropdown ? '</div>' : '');\n    };\n\n    /**\n     * bootstrap icon button template\n     * @private\n     * @param {String} iconClassName\n     * @param {Object} [options]\n     * @param {String} [options.event]\n     * @param {String} [options.value]\n     * @param {String} [options.title]\n     * @param {String} [options.dropdown]\n     */\n    var tplIconButton = function (iconClassName, options) {\n      var label = '<i class=\"' + iconClassName + '\"></i>';\n      return tplButton(label, options);\n    };\n\n    /**\n     * bootstrap popover template\n     * @private\n     * @param {String} className\n     * @param {String} content\n     */\n    var tplPopover = function (className, content) {\n      var $popover = $('<div class=\"' + className + ' popover bottom in\" style=\"display: none;\">' +\n               '<div class=\"arrow\"></div>' +\n               '<div class=\"popover-content\">' +\n               '</div>' +\n             '</div>');\n\n      $popover.find('.popover-content').append(content);\n      return $popover;\n    };\n\n    /**\n     * bootstrap dialog template\n     *\n     * @param {String} className\n     * @param {String} [title='']\n     * @param {String} body\n     * @param {String} [footer='']\n     */\n    var tplDialog = function (className, title, body, footer) {\n      return '<div class=\"' + className + ' modal\" aria-hidden=\"false\">' +\n               '<div class=\"modal-dialog\">' +\n                 '<div class=\"modal-content\">' +\n                   (title ?\n                   '<div class=\"modal-header\">' +\n                     '<button type=\"button\" class=\"close\" aria-hidden=\"true\" tabindex=\"-1\">&times;</button>' +\n                     '<h4 class=\"modal-title\">' + title + '</h4>' +\n                   '</div>' : ''\n                   ) +\n                   '<div class=\"modal-body\">' + body + '</div>' +\n                   (footer ?\n                   '<div class=\"modal-footer\">' + footer + '</div>' : ''\n                   ) +\n                 '</div>' +\n               '</div>' +\n             '</div>';\n    };\n\n    /**\n     * bootstrap dropdown template\n     *\n     * @param {String|String[]} contents\n     * @param {String} [className='']\n     * @param {String} [nodeName='']\n     */\n    var tplDropdown = function (contents, className, nodeName) {\n      var classes = 'dropdown-menu' + (className ? ' ' + className : '');\n      nodeName = nodeName || 'ul';\n      if (contents instanceof Array) {\n        contents = contents.join('');\n      }\n\n      return '<' + nodeName + ' class=\"' + classes + '\">' + contents + '</' + nodeName + '>';\n    };\n\n    var tplButtonInfo = {\n      picture: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.image.image, {\n          event: 'showImageDialog',\n          title: lang.image.image,\n          hide: true\n        });\n      },\n      link: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.link.link, {\n          event: 'showLinkDialog',\n          title: lang.link.link,\n          hide: true\n        });\n      },\n      table: function (lang, options) {\n        var dropdown = [\n          '<div class=\"note-dimension-picker\">',\n          '<div class=\"note-dimension-picker-mousecatcher\" data-event=\"insertTable\" data-value=\"1x1\"></div>',\n          '<div class=\"note-dimension-picker-highlighted\"></div>',\n          '<div class=\"note-dimension-picker-unhighlighted\"></div>',\n          '</div>',\n          '<div class=\"note-dimension-display\"> 1 x 1 </div>'\n        ];\n\n        return tplIconButton(options.iconPrefix + options.icons.table.table, {\n          title: lang.table.table,\n          dropdown: tplDropdown(dropdown, 'note-table')\n        });\n      },\n      style: function (lang, options) {\n        var items = options.styleTags.reduce(function (memo, v) {\n          var label = lang.style[v === 'p' ? 'normal' : v];\n          return memo + '<li><a data-event=\"formatBlock\" href=\"#\" data-value=\"' + v + '\">' +\n                   (\n                     (v === 'p' || v === 'pre') ? label :\n                     '<' + v + '>' + label + '</' + v + '>'\n                   ) +\n                 '</a></li>';\n        }, '');\n\n        return tplIconButton(options.iconPrefix + options.icons.style.style, {\n          title: lang.style.style,\n          dropdown: tplDropdown(items)\n        });\n      },\n      fontname: function (lang, options) {\n        var realFontList = [];\n        var items = options.fontNames.reduce(function (memo, v) {\n          if (!agent.isFontInstalled(v) && !list.contains(options.fontNamesIgnoreCheck, v)) {\n            return memo;\n          }\n          realFontList.push(v);\n          return memo + '<li><a data-event=\"fontName\" href=\"#\" data-value=\"' + v + '\" style=\"font-family:\\'' + v + '\\'\">' +\n                          '<i class=\"' + options.iconPrefix + options.icons.misc.check + '\"></i> ' + v +\n                        '</a></li>';\n        }, '');\n\n        var hasDefaultFont = agent.isFontInstalled(options.defaultFontName);\n        var defaultFontName = (hasDefaultFont) ? options.defaultFontName : realFontList[0];\n\n        var label = '<span class=\"note-current-fontname\">' +\n                        defaultFontName +\n                     '</span>';\n        return tplButton(label, {\n          title: lang.font.name,\n          className: 'note-fontname',\n          dropdown: tplDropdown(items, 'note-check')\n        });\n      },\n      fontsize: function (lang, options) {\n        var items = options.fontSizes.reduce(function (memo, v) {\n          return memo + '<li><a data-event=\"fontSize\" href=\"#\" data-value=\"' + v + '\">' +\n                          '<i class=\"' + options.iconPrefix + options.icons.misc.check + '\"></i> ' + v +\n                        '</a></li>';\n        }, '');\n\n        var label = '<span class=\"note-current-fontsize\">11</span>';\n        return tplButton(label, {\n          title: lang.font.size,\n          className: 'note-fontsize',\n          dropdown: tplDropdown(items, 'note-check')\n        });\n      },\n      color: function (lang, options) {\n        var colorButtonLabel = '<i class=\"' +\n                                  options.iconPrefix + options.icons.color.recent +\n                                '\" style=\"color:black;background-color:yellow;\"></i>';\n\n        var colorButton = tplButton(colorButtonLabel, {\n          className: 'note-recent-color',\n          title: lang.color.recent,\n          event: 'color',\n          value: '{\"backColor\":\"yellow\"}'\n        });\n\n        var items = [\n          '<li><div class=\"btn-group\">',\n          '<div class=\"note-palette-title\">' + lang.color.background + '</div>',\n          '<div class=\"note-color-reset\" data-event=\"backColor\"',\n          ' data-value=\"inherit\" title=\"' + lang.color.transparent + '\">' + lang.color.setTransparent + '</div>',\n          '<div class=\"note-color-palette\" data-target-event=\"backColor\"></div>',\n          '</div><div class=\"btn-group\">',\n          '<div class=\"note-palette-title\">' + lang.color.foreground + '</div>',\n          '<div class=\"note-color-reset\" data-event=\"foreColor\" data-value=\"inherit\" title=\"' + lang.color.reset + '\">',\n          lang.color.resetToDefault,\n          '</div>',\n          '<div class=\"note-color-palette\" data-target-event=\"foreColor\"></div>',\n          '</div></li>'\n        ];\n\n        var moreButton = tplButton('', {\n          title: lang.color.more,\n          dropdown: tplDropdown(items)\n        });\n\n        return colorButton + moreButton;\n      },\n      bold: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.bold, {\n          event: 'bold',\n          title: lang.font.bold\n        });\n      },\n      italic: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.italic, {\n          event: 'italic',\n          title: lang.font.italic\n        });\n      },\n      underline: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.underline, {\n          event: 'underline',\n          title: lang.font.underline\n        });\n      },\n      strikethrough: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.strikethrough, {\n          event: 'strikethrough',\n          title: lang.font.strikethrough\n        });\n      },\n      superscript: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.superscript, {\n          event: 'superscript',\n          title: lang.font.superscript\n        });\n      },\n      subscript: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.subscript, {\n          event: 'subscript',\n          title: lang.font.subscript\n        });\n      },\n      clear: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.font.clear, {\n          event: 'removeFormat',\n          title: lang.font.clear\n        });\n      },\n      ul: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.lists.unordered, {\n          event: 'insertUnorderedList',\n          title: lang.lists.unordered\n        });\n      },\n      ol: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.lists.ordered, {\n          event: 'insertOrderedList',\n          title: lang.lists.ordered\n        });\n      },\n      paragraph: function (lang, options) {\n        var leftButton = tplIconButton(options.iconPrefix + options.icons.paragraph.left, {\n          title: lang.paragraph.left,\n          event: 'justifyLeft'\n        });\n        var centerButton = tplIconButton(options.iconPrefix + options.icons.paragraph.center, {\n          title: lang.paragraph.center,\n          event: 'justifyCenter'\n        });\n        var rightButton = tplIconButton(options.iconPrefix + options.icons.paragraph.right, {\n          title: lang.paragraph.right,\n          event: 'justifyRight'\n        });\n        var justifyButton = tplIconButton(options.iconPrefix + options.icons.paragraph.justify, {\n          title: lang.paragraph.justify,\n          event: 'justifyFull'\n        });\n\n        var outdentButton = tplIconButton(options.iconPrefix + options.icons.paragraph.outdent, {\n          title: lang.paragraph.outdent,\n          event: 'outdent'\n        });\n        var indentButton = tplIconButton(options.iconPrefix + options.icons.paragraph.indent, {\n          title: lang.paragraph.indent,\n          event: 'indent'\n        });\n\n        var dropdown = [\n          '<div class=\"note-align btn-group\">',\n          leftButton + centerButton + rightButton + justifyButton,\n          '</div><div class=\"note-list btn-group\">',\n          indentButton + outdentButton,\n          '</div>'\n        ];\n\n        return tplIconButton(options.iconPrefix + options.icons.paragraph.paragraph, {\n          title: lang.paragraph.paragraph,\n          dropdown: tplDropdown(dropdown, '', 'div')\n        });\n      },\n      height: function (lang, options) {\n        var items = options.lineHeights.reduce(function (memo, v) {\n          return memo + '<li><a data-event=\"lineHeight\" href=\"#\" data-value=\"' + parseFloat(v) + '\">' +\n                          '<i class=\"' + options.iconPrefix + options.icons.misc.check + '\"></i> ' + v +\n                        '</a></li>';\n        }, '');\n\n        return tplIconButton(options.iconPrefix + options.icons.font.height, {\n          title: lang.font.height,\n          dropdown: tplDropdown(items, 'note-check')\n        });\n\n      },\n      help: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.options.help, {\n          event: 'showHelpDialog',\n          title: lang.options.help,\n          hide: true\n        });\n      },\n      fullscreen: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.options.fullscreen, {\n          event: 'fullscreen',\n          title: lang.options.fullscreen\n        });\n      },\n      codeview: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.options.codeview, {\n          event: 'codeview',\n          title: lang.options.codeview\n        });\n      },\n      undo: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.history.undo, {\n          event: 'undo',\n          title: lang.history.undo\n        });\n      },\n      redo: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.history.redo, {\n          event: 'redo',\n          title: lang.history.redo\n        });\n      },\n      hr: function (lang, options) {\n        return tplIconButton(options.iconPrefix + options.icons.hr.insert, {\n          event: 'insertHorizontalRule',\n          title: lang.hr.insert\n        });\n      }\n    };\n\n    var tplPopovers = function (lang, options) {\n      var tplLinkPopover = function () {\n        var linkButton = tplIconButton(options.iconPrefix + options.icons.link.edit, {\n          title: lang.link.edit,\n          event: 'showLinkDialog',\n          hide: true\n        });\n        var unlinkButton = tplIconButton(options.iconPrefix + options.icons.link.unlink, {\n          title: lang.link.unlink,\n          event: 'unlink'\n        });\n        var content = '<a href=\"http://www.google.com\" target=\"_blank\">www.google.com</a>&nbsp;&nbsp;' +\n                      '<div class=\"note-insert btn-group\">' +\n                        linkButton + unlinkButton +\n                      '</div>';\n        return tplPopover('note-link-popover', content);\n      };\n\n      var tplImagePopover = function () {\n        var fullButton = tplButton('<span class=\"note-fontsize-10\">100%</span>', {\n          title: lang.image.resizeFull,\n          event: 'resize',\n          value: '1'\n        });\n        var halfButton = tplButton('<span class=\"note-fontsize-10\">50%</span>', {\n          title: lang.image.resizeHalf,\n          event: 'resize',\n          value: '0.5'\n        });\n        var quarterButton = tplButton('<span class=\"note-fontsize-10\">25%</span>', {\n          title: lang.image.resizeQuarter,\n          event: 'resize',\n          value: '0.25'\n        });\n\n        var leftButton = tplIconButton(options.iconPrefix + options.icons.image.floatLeft, {\n          title: lang.image.floatLeft,\n          event: 'floatMe',\n          value: 'left'\n        });\n        var rightButton = tplIconButton(options.iconPrefix + options.icons.image.floatRight, {\n          title: lang.image.floatRight,\n          event: 'floatMe',\n          value: 'right'\n        });\n        var justifyButton = tplIconButton(options.iconPrefix + options.icons.image.floatNone, {\n          title: lang.image.floatNone,\n          event: 'floatMe',\n          value: 'none'\n        });\n\n        var roundedButton = tplIconButton(options.iconPrefix + options.icons.image.shapeRounded, {\n          title: lang.image.shapeRounded,\n          event: 'imageShape',\n          value: 'img-rounded'\n        });\n        var circleButton = tplIconButton(options.iconPrefix + options.icons.image.shapeCircle, {\n          title: lang.image.shapeCircle,\n          event: 'imageShape',\n          value: 'img-circle'\n        });\n        var thumbnailButton = tplIconButton(options.iconPrefix + options.icons.image.shapeThumbnail, {\n          title: lang.image.shapeThumbnail,\n          event: 'imageShape',\n          value: 'img-thumbnail'\n        });\n        var noneButton = tplIconButton(options.iconPrefix + options.icons.image.shapeNone, {\n          title: lang.image.shapeNone,\n          event: 'imageShape',\n          value: ''\n        });\n\n        var removeButton = tplIconButton(options.iconPrefix + options.icons.image.remove, {\n          title: lang.image.remove,\n          event: 'removeMedia',\n          value: 'none'\n        });\n\n        var content = (options.disableResizeImage ? '' : '<div class=\"btn-group\">' + fullButton + halfButton + quarterButton + '</div>') +\n                      '<div class=\"btn-group\">' + leftButton + rightButton + justifyButton + '</div><br>' +\n                      '<div class=\"btn-group\">' + roundedButton + circleButton + thumbnailButton + noneButton + '</div>' +\n                      '<div class=\"btn-group\">' + removeButton + '</div>';\n        return tplPopover('note-image-popover', content);\n      };\n\n      var tplAirPopover = function () {\n        var $content = $('<div />');\n        for (var idx = 0, len = options.airPopover.length; idx < len; idx ++) {\n          var group = options.airPopover[idx];\n\n          var $group = $('<div class=\"note-' + group[0] + ' btn-group\">');\n          for (var i = 0, lenGroup = group[1].length; i < lenGroup; i++) {\n            var $button = $(tplButtonInfo[group[1][i]](lang, options));\n\n            $button.attr('data-name', group[1][i]);\n\n            $group.append($button);\n          }\n          $content.append($group);\n        }\n\n        return tplPopover('note-air-popover', $content.children());\n      };\n\n      var $notePopover = $('<div class=\"note-popover\" />');\n\n      $notePopover.append(tplLinkPopover());\n      $notePopover.append(tplImagePopover());\n\n      if (options.airMode) {\n        $notePopover.append(tplAirPopover());\n      }\n\n      return $notePopover;\n    };\n\n    var tplHandles = function (options) {\n      return '<div class=\"note-handle\">' +\n               '<div class=\"note-control-selection\">' +\n                 '<div class=\"note-control-selection-bg\"></div>' +\n                 '<div class=\"note-control-holder note-control-nw\"></div>' +\n                 '<div class=\"note-control-holder note-control-ne\"></div>' +\n                 '<div class=\"note-control-holder note-control-sw\"></div>' +\n                 '<div class=\"' +\n                 (options.disableResizeImage ? 'note-control-holder' : 'note-control-sizing') +\n                 ' note-control-se\"></div>' +\n                 (options.disableResizeImage ? '' : '<div class=\"note-control-selection-info\"></div>') +\n               '</div>' +\n             '</div>';\n    };\n\n    /**\n     * shortcut table template\n     * @param {String} title\n     * @param {String} body\n     */\n    var tplShortcut = function (title, keys) {\n      var keyClass = 'note-shortcut-col col-xs-6 note-shortcut-';\n      var body = [];\n\n      for (var i in keys) {\n        if (keys.hasOwnProperty(i)) {\n          body.push(\n            '<div class=\"' + keyClass + 'key\">' + keys[i].kbd + '</div>' +\n            '<div class=\"' + keyClass + 'name\">' + keys[i].text + '</div>'\n            );\n        }\n      }\n\n      return '<div class=\"note-shortcut-row row\"><div class=\"' + keyClass + 'title col-xs-offset-6\">' + title + '</div></div>' +\n             '<div class=\"note-shortcut-row row\">' + body.join('</div><div class=\"note-shortcut-row row\">') + '</div>';\n    };\n\n    var tplShortcutText = function (lang) {\n      var keys = [\n        { kbd: '⌘ + B', text: lang.font.bold },\n        { kbd: '⌘ + I', text: lang.font.italic },\n        { kbd: '⌘ + U', text: lang.font.underline },\n        { kbd: '⌘ + \\\\', text: lang.font.clear }\n      ];\n\n      return tplShortcut(lang.shortcut.textFormatting, keys);\n    };\n\n    var tplShortcutAction = function (lang) {\n      var keys = [\n        { kbd: '⌘ + Z', text: lang.history.undo },\n        { kbd: '⌘ + ⇧ + Z', text: lang.history.redo },\n        { kbd: '⌘ + ]', text: lang.paragraph.indent },\n        { kbd: '⌘ + [', text: lang.paragraph.outdent },\n        { kbd: '⌘ + ENTER', text: lang.hr.insert }\n      ];\n\n      return tplShortcut(lang.shortcut.action, keys);\n    };\n\n    var tplShortcutPara = function (lang) {\n      var keys = [\n        { kbd: '⌘ + ⇧ + L', text: lang.paragraph.left },\n        { kbd: '⌘ + ⇧ + E', text: lang.paragraph.center },\n        { kbd: '⌘ + ⇧ + R', text: lang.paragraph.right },\n        { kbd: '⌘ + ⇧ + J', text: lang.paragraph.justify },\n        { kbd: '⌘ + ⇧ + NUM7', text: lang.lists.ordered },\n        { kbd: '⌘ + ⇧ + NUM8', text: lang.lists.unordered }\n      ];\n\n      return tplShortcut(lang.shortcut.paragraphFormatting, keys);\n    };\n\n    var tplShortcutStyle = function (lang) {\n      var keys = [\n        { kbd: '⌘ + NUM0', text: lang.style.normal },\n        { kbd: '⌘ + NUM1', text: lang.style.h1 },\n        { kbd: '⌘ + NUM2', text: lang.style.h2 },\n        { kbd: '⌘ + NUM3', text: lang.style.h3 },\n        { kbd: '⌘ + NUM4', text: lang.style.h4 },\n        { kbd: '⌘ + NUM5', text: lang.style.h5 },\n        { kbd: '⌘ + NUM6', text: lang.style.h6 }\n      ];\n\n      return tplShortcut(lang.shortcut.documentStyle, keys);\n    };\n\n    var tplExtraShortcuts = function (lang, options) {\n      var extraKeys = options.extraKeys;\n      var keys = [];\n\n      for (var key in extraKeys) {\n        if (extraKeys.hasOwnProperty(key)) {\n          keys.push({ kbd: key, text: extraKeys[key] });\n        }\n      }\n\n      return tplShortcut(lang.shortcut.extraKeys, keys);\n    };\n\n    var tplShortcutTable = function (lang, options) {\n      var colClass = 'class=\"note-shortcut note-shortcut-col col-sm-6 col-xs-12\"';\n      var template = [\n        '<div ' + colClass + '>' + tplShortcutAction(lang, options) + '</div>' +\n        '<div ' + colClass + '>' + tplShortcutText(lang, options) + '</div>',\n        '<div ' + colClass + '>' + tplShortcutStyle(lang, options) + '</div>' +\n        '<div ' + colClass + '>' + tplShortcutPara(lang, options) + '</div>'\n      ];\n\n      if (options.extraKeys) {\n        template.push('<div ' + colClass + '>' + tplExtraShortcuts(lang, options) + '</div>');\n      }\n\n      return '<div class=\"note-shortcut-row row\">' +\n               template.join('</div><div class=\"note-shortcut-row row\">') +\n             '</div>';\n    };\n\n    var replaceMacKeys = function (sHtml) {\n      return sHtml.replace(/⌘/g, 'Ctrl').replace(/⇧/g, 'Shift');\n    };\n\n    var tplDialogInfo = {\n      image: function (lang, options) {\n        var imageLimitation = '';\n        if (options.maximumImageFileSize) {\n          var unit = Math.floor(Math.log(options.maximumImageFileSize) / Math.log(1024));\n          var readableSize = (options.maximumImageFileSize / Math.pow(1024, unit)).toFixed(2) * 1 +\n                             ' ' + ' KMGTP'[unit] + 'B';\n          imageLimitation = '<small>' + lang.image.maximumFileSize + ' : ' + readableSize + '</small>';\n        }\n\n        var body = '<div class=\"form-group row note-group-select-from-files\">' +\n                     '<label>' + lang.image.selectFromFiles + '</label>' +\n                     '<input class=\"note-image-input form-control\" type=\"file\" name=\"files\" accept=\"image/*\" multiple=\"multiple\" />' +\n                     imageLimitation +\n                   '</div>' +\n                   '<div class=\"form-group row\">' +\n                     '<label>' + lang.image.url + '</label>' +\n                     '<input class=\"note-image-url form-control col-md-12\" type=\"text\" />' +\n                   '</div>';\n        var footer = '<button href=\"#\" class=\"btn btn-primary note-image-btn disabled\" disabled>' + lang.image.insert + '</button>';\n        return tplDialog('note-image-dialog', lang.image.insert, body, footer);\n      },\n\n      link: function (lang, options) {\n        var body = '<div class=\"form-group row\">' +\n                     '<label>' + lang.link.textToDisplay + '</label>' +\n                     '<input class=\"note-link-text form-control col-md-12\" type=\"text\" />' +\n                   '</div>' +\n                   '<div class=\"form-group row\">' +\n                     '<label>' + lang.link.url + '</label>' +\n                     '<input class=\"note-link-url form-control col-md-12\" type=\"text\" value=\"http://\" />' +\n                   '</div>' +\n                   (!options.disableLinkTarget ?\n                     '<div class=\"checkbox\">' +\n                       '<label>' + '<input type=\"checkbox\" checked> ' +\n                         lang.link.openInNewWindow +\n                       '</label>' +\n                     '</div>' : ''\n                   );\n        var footer = '<button href=\"#\" class=\"btn btn-primary note-link-btn disabled\" disabled>' + lang.link.insert + '</button>';\n        return tplDialog('note-link-dialog', lang.link.insert, body, footer);\n      },\n\n      help: function (lang, options) {\n        var body = '<a class=\"modal-close pull-right\" aria-hidden=\"true\" tabindex=\"-1\">' + lang.shortcut.close + '</a>' +\n                   '<div class=\"title\">' + lang.shortcut.shortcuts + '</div>' +\n                   (agent.isMac ? tplShortcutTable(lang, options) : replaceMacKeys(tplShortcutTable(lang, options))) +\n                   '<p class=\"text-center\">' +\n                     '<a href=\"//summernote.org/\" target=\"_blank\">Summernote @VERSION</a> · ' +\n                     '<a href=\"//github.com/summernote/summernote\" target=\"_blank\">Project</a> · ' +\n                     '<a href=\"//github.com/summernote/summernote/issues\" target=\"_blank\">Issues</a>' +\n                   '</p>';\n        return tplDialog('note-help-dialog', '', body, '');\n      }\n    };\n\n    var tplDialogs = function (lang, options) {\n      var dialogs = '';\n\n      $.each(tplDialogInfo, function (idx, tplDialog) {\n        dialogs += tplDialog(lang, options);\n      });\n\n      return '<div class=\"note-dialog\">' + dialogs + '</div>';\n    };\n\n    var tplStatusbar = function () {\n      return '<div class=\"note-resizebar\">' +\n               '<div class=\"note-icon-bar\"></div>' +\n               '<div class=\"note-icon-bar\"></div>' +\n               '<div class=\"note-icon-bar\"></div>' +\n             '</div>';\n    };\n\n    var representShortcut = function (str) {\n      if (agent.isMac) {\n        str = str.replace('CMD', '⌘').replace('SHIFT', '⇧');\n      }\n\n      return str.replace('BACKSLASH', '\\\\')\n                .replace('SLASH', '/')\n                .replace('LEFTBRACKET', '[')\n                .replace('RIGHTBRACKET', ']');\n    };\n\n    /**\n     * createTooltip\n     *\n     * @param {jQuery} $container\n     * @param {Object} keyMap\n     * @param {String} [sPlacement]\n     */\n    var createTooltip = function ($container, keyMap, sPlacement) {\n      var invertedKeyMap = func.invertObject(keyMap);\n      var $buttons = $container.find('button');\n\n      $buttons.each(function (i, elBtn) {\n        var $btn = $(elBtn);\n        var sShortcut = invertedKeyMap[$btn.data('event')];\n        if (sShortcut) {\n          $btn.attr('title', function (i, v) {\n            return v + ' (' + representShortcut(sShortcut) + ')';\n          });\n        }\n      // bootstrap tooltip on btn-group bug\n      // https://github.com/twbs/bootstrap/issues/5687\n      }).tooltip({\n        container: 'body',\n        trigger: 'hover',\n        placement: sPlacement || 'top'\n      }).on('click', function () {\n        $(this).tooltip('hide');\n      });\n    };\n\n    // createPalette\n    var createPalette = function ($container, options) {\n      var colorInfo = options.colors;\n      $container.find('.note-color-palette').each(function () {\n        var $palette = $(this), eventName = $palette.attr('data-target-event');\n        var paletteContents = [];\n        for (var row = 0, lenRow = colorInfo.length; row < lenRow; row++) {\n          var colors = colorInfo[row];\n          var buttons = [];\n          for (var col = 0, lenCol = colors.length; col < lenCol; col++) {\n            var color = colors[col];\n            buttons.push(['<button type=\"button\" class=\"note-color-btn\" style=\"background-color:', color,\n                           ';\" data-event=\"', eventName,\n                           '\" data-value=\"', color,\n                           '\" title=\"', color,\n                           '\" data-toggle=\"button\" tabindex=\"-1\"></button>'].join(''));\n          }\n          paletteContents.push('<div class=\"note-color-row\">' + buttons.join('') + '</div>');\n        }\n        $palette.html(paletteContents.join(''));\n      });\n    };\n\n    /**\n     * create summernote layout (air mode)\n     *\n     * @param {jQuery} $holder\n     * @param {Object} options\n     */\n    this.createLayoutByAirMode = function ($holder, options) {\n      var langInfo = options.langInfo;\n      var keyMap = options.keyMap[agent.isMac ? 'mac' : 'pc'];\n      var id = func.uniqueId();\n\n      $holder.addClass('note-air-editor note-editable panel-body');\n      $holder.attr({\n        'id': 'note-editor-' + id,\n        'contentEditable': true\n      });\n\n      var body = document.body;\n\n      // create Popover\n      var $popover = $(tplPopovers(langInfo, options));\n      $popover.addClass('note-air-layout');\n      $popover.attr('id', 'note-popover-' + id);\n      $popover.appendTo(body);\n      createTooltip($popover, keyMap);\n      createPalette($popover, options);\n\n      // create Handle\n      var $handle = $(tplHandles(options));\n      $handle.addClass('note-air-layout');\n      $handle.attr('id', 'note-handle-' + id);\n      $handle.appendTo(body);\n\n      // create Dialog\n      var $dialog = $(tplDialogs(langInfo, options));\n      $dialog.addClass('note-air-layout');\n      $dialog.attr('id', 'note-dialog-' + id);\n      $dialog.find('button.close, a.modal-close').click(function () {\n        $(this).closest('.modal').modal('hide');\n      });\n      $dialog.appendTo(body);\n    };\n\n    /**\n     * create summernote layout (normal mode)\n     *\n     * @param {jQuery} $holder\n     * @param {Object} options\n     */\n    this.createLayoutByFrame = function ($holder, options) {\n      var langInfo = options.langInfo;\n\n      //01. create Editor\n      var $editor = $('<div class=\"note-editor panel panel-default\" />');\n      if (options.width) {\n        $editor.width(options.width);\n      }\n\n      //02. statusbar (resizebar)\n      if (options.height > 0) {\n        $('<div class=\"note-statusbar\">' + (options.disableResizeEditor ? '' : tplStatusbar()) + '</div>').prependTo($editor);\n      }\n\n      //03 editing area\n      var $editingArea = $('<div class=\"note-editing-area\" />');\n      //03. create editable\n      var isContentEditable = !$holder.is(':disabled');\n      var $editable = $('<div class=\"note-editable panel-body\" contentEditable=\"' + isContentEditable + '\"></div>').prependTo($editingArea);\n      \n      if (options.height) {\n        $editable.height(options.height);\n      }\n      if (options.direction) {\n        $editable.attr('dir', options.direction);\n      }\n      var placeholder = $holder.attr('placeholder') || options.placeholder;\n      if (placeholder) {\n        $editable.attr('data-placeholder', placeholder);\n      }\n\n      $editable.html(dom.html($holder) || dom.emptyPara);\n\n      //031. create codable\n      $('<textarea class=\"note-codable\"></textarea>').prependTo($editingArea);\n\n      //04. create Popover\n      var $popover = $(tplPopovers(langInfo, options)).prependTo($editingArea);\n      createPalette($popover, options);\n      createTooltip($popover, keyMap);\n\n      //05. handle(control selection, ...)\n      $(tplHandles(options)).prependTo($editingArea);\n\n      $editingArea.prependTo($editor);\n\n      //06. create Toolbar\n      var $toolbar = $('<div class=\"note-toolbar panel-heading\" />');\n      for (var idx = 0, len = options.toolbar.length; idx < len; idx ++) {\n        var groupName = options.toolbar[idx][0];\n        var groupButtons = options.toolbar[idx][1];\n\n        var $group = $('<div class=\"note-' + groupName + ' btn-group\" />');\n        for (var i = 0, btnLength = groupButtons.length; i < btnLength; i++) {\n          var buttonInfo = tplButtonInfo[groupButtons[i]];\n          // continue creating toolbar even if a button doesn't exist\n          if (!$.isFunction(buttonInfo)) { continue; }\n\n          var $button = $(buttonInfo(langInfo, options));\n          $button.attr('data-name', groupButtons[i]);  // set button's alias, becuase to get button element from $toolbar\n          $group.append($button);\n        }\n        $toolbar.append($group);\n      }\n\n      var keyMap = options.keyMap[agent.isMac ? 'mac' : 'pc'];\n      createPalette($toolbar, options);\n      createTooltip($toolbar, keyMap, 'bottom');\n      $toolbar.prependTo($editor);\n\n      //07. create Dropzone\n      $('<div class=\"note-dropzone\"><div class=\"note-dropzone-message\"></div></div>').prependTo($editor);\n\n      //08. create Dialog\n      var $dialogContainer = options.dialogsInBody ? $(document.body) : $editor;\n      var $dialog = $(tplDialogs(langInfo, options)).prependTo($dialogContainer);\n      $dialog.find('button.close, a.modal-close').click(function () {\n        $(this).closest('.modal').modal('hide');\n      });\n\n      //09. Editor/Holder switch\n      $editor.insertAfter($holder);\n      $holder.hide();\n    };\n\n    this.hasNoteEditor = function ($holder) {\n      return this.noteEditorFromHolder($holder).length > 0;\n    };\n\n    this.noteEditorFromHolder = function ($holder) {\n      if ($holder.hasClass('note-air-editor')) {\n        return $holder;\n      } else if ($holder.next().hasClass('note-editor')) {\n        return $holder.next();\n      } else {\n        return $();\n      }\n    };\n\n    /**\n     * create summernote layout\n     *\n     * @param {jQuery} $holder\n     * @param {Object} options\n     */\n    this.createLayout = function ($holder, options) {\n      if (options.airMode) {\n        this.createLayoutByAirMode($holder, options);\n      } else {\n        this.createLayoutByFrame($holder, options);\n      }\n    };\n\n    /**\n     * returns layoutInfo from holder\n     *\n     * @param {jQuery} $holder - placeholder\n     * @return {Object}\n     */\n    this.layoutInfoFromHolder = function ($holder) {\n      var $editor = this.noteEditorFromHolder($holder);\n      if (!$editor.length) {\n        return;\n      }\n\n      // connect $holder to $editor\n      $editor.data('holder', $holder);\n\n      return dom.buildLayoutInfo($editor);\n    };\n\n    /**\n     * removeLayout\n     *\n     * @param {jQuery} $holder - placeholder\n     * @param {Object} layoutInfo\n     * @param {Object} options\n     *\n     */\n    this.removeLayout = function ($holder, layoutInfo, options) {\n      if (options.airMode) {\n        $holder.removeClass('note-air-editor note-editable')\n               .removeAttr('id contentEditable');\n\n        layoutInfo.popover().remove();\n        layoutInfo.handle().remove();\n        layoutInfo.dialog().remove();\n      } else {\n        $holder.html(layoutInfo.editable().html());\n\n        if (options.dialogsInBody) {\n          layoutInfo.dialog().remove();\n        }\n        layoutInfo.editor().remove();\n        $holder.show();\n      }\n    };\n\n    /**\n     *\n     * @return {Object}\n     * @return {function(label, options=):string} return.button {@link #tplButton function to make text button}\n     * @return {function(iconClass, options=):string} return.iconButton {@link #tplIconButton function to make icon button}\n     * @return {function(className, title=, body=, footer=):string} return.dialog {@link #tplDialog function to make dialog}\n     */\n    this.getTemplate = function () {\n      return {\n        button: tplButton,\n        iconButton: tplIconButton,\n        dialog: tplDialog\n      };\n    };\n\n    /**\n     * add button information\n     *\n     * @param {String} name button name\n     * @param {Function} buttonInfo function to make button, reference to {@link #tplButton},{@link #tplIconButton}\n     */\n    this.addButtonInfo = function (name, buttonInfo) {\n      tplButtonInfo[name] = buttonInfo;\n    };\n\n    /**\n     *\n     * @param {String} name\n     * @param {Function} dialogInfo function to make dialog, reference to {@link #tplDialog}\n     */\n    this.addDialogInfo = function (name, dialogInfo) {\n      tplDialogInfo[name] = dialogInfo;\n    };\n  };\n\n  return Renderer;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/app.js",
    "content": "require.config({\n  baseUrl: 'src/js',\n  paths: {\n    jquery: '//code.jquery.com/jquery-1.11.3',\n    bootstrap: '//netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min',\n    summernotevideo: '/../../plugin/summernote-ext-video',\n    CodeMirror: '//cdnjs.cloudflare.com/ajax/libs/codemirror/3.20.0/codemirror',\n    CodeMirrorXml: '//cdnjs.cloudflare.com/ajax/libs/codemirror/3.20.0/mode/xml/xml.min',\n    CodeMirrorFormatting: '//cdnjs.cloudflare.com/ajax/libs/codemirror/2.36.0/formatting.min'\n  },\n  shim: {\n    bootstrap: ['jquery'],\n    CodeMirror: { exports: 'CodeMirror' },\n    CodeMirrorXml: ['CodeMirror'],\n    CodeMirrorFormatting: ['CodeMirror', 'CodeMirrorXml'],\n    summernotevideo: ['summernote']\n  },\n  packages: [{\n    name: 'summernote',\n    location: './',\n    main: 'summernote'\n  }]\n});\n\nrequire([\n  'jquery', 'bootstrap', 'CodeMirrorFormatting',\n  'summernote', 'summernotevideo'\n], function ($) {\n  // summernote\n  $('.summernote').summernote({\n    height: 300,                  // set editable area's height\n    focus: true,                  // set focus editable area after summernote loaded\n    tabsize: 2,                   // size of tab\n    placeholder: 'Type your message here...', // set editable area's placeholder text\n    codemirror: {                 // code mirror options\n      mode: 'text/html',\n      htmlMode: true,\n      lineNumbers: true,\n      theme: 'monokai'\n    }\n  });\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/core/agent.js",
    "content": "define(['jquery'], function ($) {\n  if (!Array.prototype.reduce) {\n    /**\n     * Array.prototype.reduce polyfill\n     *\n     * @param {Function} callback\n     * @param {Value} [initialValue]\n     * @return {Value}\n     *\n     * @see http://goo.gl/WNriQD\n     */\n    Array.prototype.reduce = function (callback) {\n      var t = Object(this), len = t.length >>> 0, k = 0, value;\n      if (arguments.length === 2) {\n        value = arguments[1];\n      } else {\n        while (k < len && !(k in t)) {\n          k++;\n        }\n        if (k >= len) {\n          throw new TypeError('Reduce of empty array with no initial value');\n        }\n        value = t[k++];\n      }\n      for (; k < len; k++) {\n        if (k in t) {\n          value = callback(value, t[k], k, t);\n        }\n      }\n      return value;\n    };\n  }\n\n  if ('function' !== typeof Array.prototype.filter) {\n    /**\n     * Array.prototype.filter polyfill\n     *\n     * @param {Function} func\n     * @return {Array}\n     *\n     * @see http://goo.gl/T1KFnq\n     */\n    Array.prototype.filter = function (func) {\n      var t = Object(this), len = t.length >>> 0;\n\n      var res = [];\n      var thisArg = arguments.length >= 2 ? arguments[1] : void 0;\n      for (var i = 0; i < len; i++) {\n        if (i in t) {\n          var val = t[i];\n          if (func.call(thisArg, val, i, t)) {\n            res.push(val);\n          }\n        }\n      }\n  \n      return res;\n    };\n  }\n\n  if (!Array.prototype.map) {\n    /**\n     * Array.prototype.map polyfill\n     *\n     * @param {Function} callback\n     * @return {Array}\n     *\n     * @see https://goo.gl/SMWaMK\n     */\n    Array.prototype.map = function (callback, thisArg) {\n      var T, A, k;\n      if (this === null) {\n        throw new TypeError(' this is null or not defined');\n      }\n\n      var O = Object(this);\n      var len = O.length >>> 0;\n      if (typeof callback !== 'function') {\n        throw new TypeError(callback + ' is not a function');\n      }\n  \n      if (arguments.length > 1) {\n        T = thisArg;\n      }\n  \n      A = new Array(len);\n      k = 0;\n  \n      while (k < len) {\n        var kValue, mappedValue;\n        if (k in O) {\n          kValue = O[k];\n          mappedValue = callback.call(T, kValue, k, O);\n          A[k] = mappedValue;\n        }\n        k++;\n      }\n      return A;\n    };\n  }\n\n  var isSupportAmd = typeof define === 'function' && define.amd;\n\n  /**\n   * returns whether font is installed or not.\n   *\n   * @param {String} fontName\n   * @return {Boolean}\n   */\n  var isFontInstalled = function (fontName) {\n    var testFontName = fontName === 'Comic Sans MS' ? 'Courier New' : 'Comic Sans MS';\n    var $tester = $('<div>').css({\n      position: 'absolute',\n      left: '-9999px',\n      top: '-9999px',\n      fontSize: '200px'\n    }).text('mmmmmmmmmwwwwwww').appendTo(document.body);\n\n    var originalWidth = $tester.css('fontFamily', testFontName).width();\n    var width = $tester.css('fontFamily', fontName + ',' + testFontName).width();\n\n    $tester.remove();\n\n    return originalWidth !== width;\n  };\n\n  var userAgent = navigator.userAgent;\n  var isMSIE = /MSIE|Trident/i.test(userAgent);\n  var browserVersion;\n  if (isMSIE) {\n    var matches = /MSIE (\\d+[.]\\d+)/.exec(userAgent);\n    if (matches) {\n      browserVersion = parseFloat(matches[1]);\n    }\n    matches = /Trident\\/.*rv:([0-9]{1,}[\\.0-9]{0,})/.exec(userAgent);\n    if (matches) {\n      browserVersion = parseFloat(matches[1]);\n    }\n  }\n\n  /**\n   * @class core.agent\n   *\n   * Object which check platform and agent\n   *\n   * @singleton\n   * @alternateClassName agent\n   */\n  var agent = {\n    /** @property {Boolean} [isMac=false] true if this agent is Mac  */\n    isMac: navigator.appVersion.indexOf('Mac') > -1,\n    /** @property {Boolean} [isMSIE=false] true if this agent is a Internet Explorer  */\n    isMSIE: isMSIE,\n    /** @property {Boolean} [isFF=false] true if this agent is a Firefox  */\n    isFF: /firefox/i.test(userAgent),\n    isWebkit: /webkit/i.test(userAgent),\n    /** @property {Boolean} [isSafari=false] true if this agent is a Safari  */\n    isSafari: /safari/i.test(userAgent),\n    /** @property {Float} browserVersion current browser version  */\n    browserVersion: browserVersion,\n    /** @property {String} jqueryVersion current jQuery version string  */\n    jqueryVersion: parseFloat($.fn.jquery),\n    isSupportAmd: isSupportAmd,\n    hasCodeMirror: isSupportAmd ? require.specified('CodeMirror') : !!window.CodeMirror,\n    isFontInstalled: isFontInstalled,\n    isW3CRangeSupport: !!document.createRange\n  };\n\n  return agent;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/core/async.js",
    "content": "define('summernote/core/async', function () {\n  /**\n   * @class core.async\n   *\n   * Async functions which returns `Promise`\n   *\n   * @singleton\n   * @alternateClassName async\n   */\n  var async = (function () {\n    /**\n     * @method readFileAsDataURL\n     *\n     * read contents of file as representing URL\n     *\n     * @param {File} file\n     * @return {Promise} - then: sDataUrl\n     */\n    var readFileAsDataURL = function (file) {\n      return $.Deferred(function (deferred) {\n        $.extend(new FileReader(), {\n          onload: function (e) {\n            var sDataURL = e.target.result;\n            deferred.resolve(sDataURL);\n          },\n          onerror: function () {\n            deferred.reject(this);\n          }\n        }).readAsDataURL(file);\n      }).promise();\n    };\n  \n    /**\n     * @method createImage\n     *\n     * create `<image>` from url string\n     *\n     * @param {String} sUrl\n     * @param {String} filename\n     * @return {Promise} - then: $image\n     */\n    var createImage = function (sUrl, filename) {\n      return $.Deferred(function (deferred) {\n        var $img = $('<img>');\n\n        $img.one('load', function () {\n          $img.off('error abort');\n          deferred.resolve($img);\n        }).one('error abort', function () {\n          $img.off('load').detach();\n          deferred.reject($img);\n        }).css({\n          display: 'none'\n        }).appendTo(document.body).attr({\n          'src': sUrl,\n          'data-filename': filename\n        });\n      }).promise();\n    };\n\n    return {\n      readFileAsDataURL: readFileAsDataURL,\n      createImage: createImage\n    };\n  })();\n\n  return async;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/core/dom.js",
    "content": "define([\n  'summernote/core/func',\n  'summernote/core/list',\n  'summernote/core/agent'\n], function (func, list, agent) {\n\n  var NBSP_CHAR = String.fromCharCode(160);\n  var ZERO_WIDTH_NBSP_CHAR = '\\ufeff';\n\n  /**\n   * @class core.dom\n   *\n   * Dom functions\n   *\n   * @singleton\n   * @alternateClassName dom\n   */\n  var dom = (function () {\n    /**\n     * @method isEditable\n     *\n     * returns whether node is `note-editable` or not.\n     *\n     * @param {Node} node\n     * @return {Boolean}\n     */\n    var isEditable = function (node) {\n      return node && $(node).hasClass('note-editable');\n    };\n\n    /**\n     * @method isControlSizing\n     *\n     * returns whether node is `note-control-sizing` or not.\n     *\n     * @param {Node} node\n     * @return {Boolean}\n     */\n    var isControlSizing = function (node) {\n      return node && $(node).hasClass('note-control-sizing');\n    };\n\n    /**\n     * @method  buildLayoutInfo\n     *\n     * build layoutInfo from $editor(.note-editor)\n     *\n     * @param {jQuery} $editor\n     * @return {Object}\n     * @return {Function} return.editor\n     * @return {Node} return.dropzone\n     * @return {Node} return.toolbar\n     * @return {Node} return.editable\n     * @return {Node} return.codable\n     * @return {Node} return.popover\n     * @return {Node} return.handle\n     * @return {Node} return.dialog\n     */\n    var buildLayoutInfo = function ($editor) {\n      var makeFinder;\n\n      // air mode\n      if ($editor.hasClass('note-air-editor')) {\n        var id = list.last($editor.attr('id').split('-'));\n        makeFinder = function (sIdPrefix) {\n          return function () { return $(sIdPrefix + id); };\n        };\n\n        return {\n          editor: function () { return $editor; },\n          holder : function () { return $editor.data('holder'); },\n          editable: function () { return $editor; },\n          popover: makeFinder('#note-popover-'),\n          handle: makeFinder('#note-handle-'),\n          dialog: makeFinder('#note-dialog-')\n        };\n\n        // frame mode\n      } else {\n        makeFinder = function (className, $base) {\n          $base = $base || $editor;\n          return function () { return $base.find(className); };\n        };\n\n        var options = $editor.data('options');\n        var $dialogHolder = (options && options.dialogsInBody) ? $(document.body) : null;\n\n        return {\n          editor: function () { return $editor; },\n          holder : function () { return $editor.data('holder'); },\n          dropzone: makeFinder('.note-dropzone'),\n          toolbar: makeFinder('.note-toolbar'),\n          editable: makeFinder('.note-editable'),\n          codable: makeFinder('.note-codable'),\n          statusbar: makeFinder('.note-statusbar'),\n          popover: makeFinder('.note-popover'),\n          handle: makeFinder('.note-handle'),\n          dialog: makeFinder('.note-dialog', $dialogHolder)\n        };\n      }\n    };\n\n    /**\n     * returns makeLayoutInfo from editor's descendant node.\n     *\n     * @private\n     * @param {Node} descendant\n     * @return {Object}\n     */\n    var makeLayoutInfo = function (descendant) {\n      var $target = $(descendant).closest('.note-editor, .note-air-editor, .note-air-layout');\n\n      if (!$target.length) {\n        return null;\n      }\n\n      var $editor;\n      if ($target.is('.note-editor, .note-air-editor')) {\n        $editor = $target;\n      } else {\n        $editor = $('#note-editor-' + list.last($target.attr('id').split('-')));\n      }\n\n      return buildLayoutInfo($editor);\n    };\n\n    /**\n     * @method makePredByNodeName\n     *\n     * returns predicate which judge whether nodeName is same\n     *\n     * @param {String} nodeName\n     * @return {Function}\n     */\n    var makePredByNodeName = function (nodeName) {\n      nodeName = nodeName.toUpperCase();\n      return function (node) {\n        return node && node.nodeName.toUpperCase() === nodeName;\n      };\n    };\n\n    /**\n     * @method isText\n     *\n     *\n     *\n     * @param {Node} node\n     * @return {Boolean} true if node's type is text(3)\n     */\n    var isText = function (node) {\n      return node && node.nodeType === 3;\n    };\n\n    /**\n     * ex) br, col, embed, hr, img, input, ...\n     * @see http://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements\n     */\n    var isVoid = function (node) {\n      return node && /^BR|^IMG|^HR|^IFRAME|^BUTTON/.test(node.nodeName.toUpperCase());\n    };\n\n    var isPara = function (node) {\n      if (isEditable(node)) {\n        return false;\n      }\n\n      // Chrome(v31.0), FF(v25.0.1) use DIV for paragraph\n      return node && /^DIV|^P|^LI|^H[1-7]/.test(node.nodeName.toUpperCase());\n    };\n\n    var isLi = makePredByNodeName('LI');\n\n    var isPurePara = function (node) {\n      return isPara(node) && !isLi(node);\n    };\n\n    var isTable = makePredByNodeName('TABLE');\n\n    var isInline = function (node) {\n      return !isBodyContainer(node) &&\n             !isList(node) &&\n             !isHr(node) &&\n             !isPara(node) &&\n             !isTable(node) &&\n             !isBlockquote(node);\n    };\n\n    var isList = function (node) {\n      return node && /^UL|^OL/.test(node.nodeName.toUpperCase());\n    };\n\n    var isHr = makePredByNodeName('HR');\n\n    var isCell = function (node) {\n      return node && /^TD|^TH/.test(node.nodeName.toUpperCase());\n    };\n\n    var isBlockquote = makePredByNodeName('BLOCKQUOTE');\n\n    var isBodyContainer = function (node) {\n      return isCell(node) || isBlockquote(node) || isEditable(node);\n    };\n\n    var isAnchor = makePredByNodeName('A');\n\n    var isParaInline = function (node) {\n      return isInline(node) && !!ancestor(node, isPara);\n    };\n\n    var isBodyInline = function (node) {\n      return isInline(node) && !ancestor(node, isPara);\n    };\n\n    var isBody = makePredByNodeName('BODY');\n\n    /**\n     * returns whether nodeB is closest sibling of nodeA\n     *\n     * @param {Node} nodeA\n     * @param {Node} nodeB\n     * @return {Boolean}\n     */\n    var isClosestSibling = function (nodeA, nodeB) {\n      return nodeA.nextSibling === nodeB ||\n             nodeA.previousSibling === nodeB;\n    };\n\n    /**\n     * returns array of closest siblings with node\n     *\n     * @param {Node} node\n     * @param {function} [pred] - predicate function\n     * @return {Node[]}\n     */\n    var withClosestSiblings = function (node, pred) {\n      pred = pred || func.ok;\n\n      var siblings = [];\n      if (node.previousSibling && pred(node.previousSibling)) {\n        siblings.push(node.previousSibling);\n      }\n      siblings.push(node);\n      if (node.nextSibling && pred(node.nextSibling)) {\n        siblings.push(node.nextSibling);\n      }\n      return siblings;\n    };\n\n    /**\n     * blank HTML for cursor position\n     * - [workaround] old IE only works with &nbsp;\n     * - [workaround] IE11 and other browser works with bogus br\n     */\n    var blankHTML = agent.isMSIE && agent.browserVersion < 11 ? '&nbsp;' : '<br>';\n\n    /**\n     * @method nodeLength\n     *\n     * returns #text's text size or element's childNodes size\n     *\n     * @param {Node} node\n     */\n    var nodeLength = function (node) {\n      if (isText(node)) {\n        return node.nodeValue.length;\n      }\n\n      return node.childNodes.length;\n    };\n\n    /**\n     * returns whether node is empty or not.\n     *\n     * @param {Node} node\n     * @return {Boolean}\n     */\n    var isEmpty = function (node) {\n      var len = nodeLength(node);\n\n      if (len === 0) {\n        return true;\n      } else if (!isText(node) && len === 1 && node.innerHTML === blankHTML) {\n        // ex) <p><br></p>, <span><br></span>\n        return true;\n      } else if (list.all(node.childNodes, isText) && node.innerHTML === '') {\n        // ex) <p></p>, <span></span>\n        return true;\n      }\n\n      return false;\n    };\n\n    /**\n     * padding blankHTML if node is empty (for cursor position)\n     */\n    var paddingBlankHTML = function (node) {\n      if (!isVoid(node) && !nodeLength(node)) {\n        node.innerHTML = blankHTML;\n      }\n    };\n\n    /**\n     * find nearest ancestor predicate hit\n     *\n     * @param {Node} node\n     * @param {Function} pred - predicate function\n     */\n    var ancestor = function (node, pred) {\n      while (node) {\n        if (pred(node)) { return node; }\n        if (isEditable(node)) { break; }\n\n        node = node.parentNode;\n      }\n      return null;\n    };\n\n    /**\n     * find nearest ancestor only single child blood line and predicate hit\n     *\n     * @param {Node} node\n     * @param {Function} pred - predicate function\n     */\n    var singleChildAncestor = function (node, pred) {\n      node = node.parentNode;\n\n      while (node) {\n        if (nodeLength(node) !== 1) { break; }\n        if (pred(node)) { return node; }\n        if (isEditable(node)) { break; }\n\n        node = node.parentNode;\n      }\n      return null;\n    };\n\n    /**\n     * returns new array of ancestor nodes (until predicate hit).\n     *\n     * @param {Node} node\n     * @param {Function} [optional] pred - predicate function\n     */\n    var listAncestor = function (node, pred) {\n      pred = pred || func.fail;\n\n      var ancestors = [];\n      ancestor(node, function (el) {\n        if (!isEditable(el)) {\n          ancestors.push(el);\n        }\n\n        return pred(el);\n      });\n      return ancestors;\n    };\n\n    /**\n     * find farthest ancestor predicate hit\n     */\n    var lastAncestor = function (node, pred) {\n      var ancestors = listAncestor(node);\n      return list.last(ancestors.filter(pred));\n    };\n\n    /**\n     * returns common ancestor node between two nodes.\n     *\n     * @param {Node} nodeA\n     * @param {Node} nodeB\n     */\n    var commonAncestor = function (nodeA, nodeB) {\n      var ancestors = listAncestor(nodeA);\n      for (var n = nodeB; n; n = n.parentNode) {\n        if ($.inArray(n, ancestors) > -1) { return n; }\n      }\n      return null; // difference document area\n    };\n\n    /**\n     * listing all previous siblings (until predicate hit).\n     *\n     * @param {Node} node\n     * @param {Function} [optional] pred - predicate function\n     */\n    var listPrev = function (node, pred) {\n      pred = pred || func.fail;\n\n      var nodes = [];\n      while (node) {\n        if (pred(node)) { break; }\n        nodes.push(node);\n        node = node.previousSibling;\n      }\n      return nodes;\n    };\n\n    /**\n     * listing next siblings (until predicate hit).\n     *\n     * @param {Node} node\n     * @param {Function} [pred] - predicate function\n     */\n    var listNext = function (node, pred) {\n      pred = pred || func.fail;\n\n      var nodes = [];\n      while (node) {\n        if (pred(node)) { break; }\n        nodes.push(node);\n        node = node.nextSibling;\n      }\n      return nodes;\n    };\n\n    /**\n     * listing descendant nodes\n     *\n     * @param {Node} node\n     * @param {Function} [pred] - predicate function\n     */\n    var listDescendant = function (node, pred) {\n      var descendents = [];\n      pred = pred || func.ok;\n\n      // start DFS(depth first search) with node\n      (function fnWalk(current) {\n        if (node !== current && pred(current)) {\n          descendents.push(current);\n        }\n        for (var idx = 0, len = current.childNodes.length; idx < len; idx++) {\n          fnWalk(current.childNodes[idx]);\n        }\n      })(node);\n\n      return descendents;\n    };\n\n    /**\n     * wrap node with new tag.\n     *\n     * @param {Node} node\n     * @param {Node} tagName of wrapper\n     * @return {Node} - wrapper\n     */\n    var wrap = function (node, wrapperName) {\n      var parent = node.parentNode;\n      var wrapper = $('<' + wrapperName + '>')[0];\n\n      parent.insertBefore(wrapper, node);\n      wrapper.appendChild(node);\n\n      return wrapper;\n    };\n\n    /**\n     * insert node after preceding\n     *\n     * @param {Node} node\n     * @param {Node} preceding - predicate function\n     */\n    var insertAfter = function (node, preceding) {\n      var next = preceding.nextSibling, parent = preceding.parentNode;\n      if (next) {\n        parent.insertBefore(node, next);\n      } else {\n        parent.appendChild(node);\n      }\n      return node;\n    };\n\n    /**\n     * append elements.\n     *\n     * @param {Node} node\n     * @param {Collection} aChild\n     */\n    var appendChildNodes = function (node, aChild) {\n      $.each(aChild, function (idx, child) {\n        node.appendChild(child);\n      });\n      return node;\n    };\n\n    /**\n     * returns whether boundaryPoint is left edge or not.\n     *\n     * @param {BoundaryPoint} point\n     * @return {Boolean}\n     */\n    var isLeftEdgePoint = function (point) {\n      return point.offset === 0;\n    };\n\n    /**\n     * returns whether boundaryPoint is right edge or not.\n     *\n     * @param {BoundaryPoint} point\n     * @return {Boolean}\n     */\n    var isRightEdgePoint = function (point) {\n      return point.offset === nodeLength(point.node);\n    };\n\n    /**\n     * returns whether boundaryPoint is edge or not.\n     *\n     * @param {BoundaryPoint} point\n     * @return {Boolean}\n     */\n    var isEdgePoint = function (point) {\n      return isLeftEdgePoint(point) || isRightEdgePoint(point);\n    };\n\n    /**\n     * returns wheter node is left edge of ancestor or not.\n     *\n     * @param {Node} node\n     * @param {Node} ancestor\n     * @return {Boolean}\n     */\n    var isLeftEdgeOf = function (node, ancestor) {\n      while (node && node !== ancestor) {\n        if (position(node) !== 0) {\n          return false;\n        }\n        node = node.parentNode;\n      }\n\n      return true;\n    };\n\n    /**\n     * returns whether node is right edge of ancestor or not.\n     *\n     * @param {Node} node\n     * @param {Node} ancestor\n     * @return {Boolean}\n     */\n    var isRightEdgeOf = function (node, ancestor) {\n      while (node && node !== ancestor) {\n        if (position(node) !== nodeLength(node.parentNode) - 1) {\n          return false;\n        }\n        node = node.parentNode;\n      }\n\n      return true;\n    };\n\n    /**\n     * returns whether point is left edge of ancestor or not.\n     * @param {BoundaryPoint} point\n     * @param {Node} ancestor\n     * @return {Boolean}\n     */\n    var isLeftEdgePointOf = function (point, ancestor) {\n      return isLeftEdgePoint(point) && isLeftEdgeOf(point.node, ancestor);\n    };\n\n    /**\n     * returns whether point is right edge of ancestor or not.\n     * @param {BoundaryPoint} point\n     * @param {Node} ancestor\n     * @return {Boolean}\n     */\n    var isRightEdgePointOf = function (point, ancestor) {\n      return isRightEdgePoint(point) && isRightEdgeOf(point.node, ancestor);\n    };\n\n    /**\n     * returns offset from parent.\n     *\n     * @param {Node} node\n     */\n    var position = function (node) {\n      var offset = 0;\n      while ((node = node.previousSibling)) {\n        offset += 1;\n      }\n      return offset;\n    };\n\n    var hasChildren = function (node) {\n      return !!(node && node.childNodes && node.childNodes.length);\n    };\n\n    /**\n     * returns previous boundaryPoint\n     *\n     * @param {BoundaryPoint} point\n     * @param {Boolean} isSkipInnerOffset\n     * @return {BoundaryPoint}\n     */\n    var prevPoint = function (point, isSkipInnerOffset) {\n      var node, offset;\n\n      if (point.offset === 0) {\n        if (isEditable(point.node)) {\n          return null;\n        }\n\n        node = point.node.parentNode;\n        offset = position(point.node);\n      } else if (hasChildren(point.node)) {\n        node = point.node.childNodes[point.offset - 1];\n        offset = nodeLength(node);\n      } else {\n        node = point.node;\n        offset = isSkipInnerOffset ? 0 : point.offset - 1;\n      }\n\n      return {\n        node: node,\n        offset: offset\n      };\n    };\n\n    /**\n     * returns next boundaryPoint\n     *\n     * @param {BoundaryPoint} point\n     * @param {Boolean} isSkipInnerOffset\n     * @return {BoundaryPoint}\n     */\n    var nextPoint = function (point, isSkipInnerOffset) {\n      var node, offset;\n\n      if (nodeLength(point.node) === point.offset) {\n        if (isEditable(point.node)) {\n          return null;\n        }\n\n        node = point.node.parentNode;\n        offset = position(point.node) + 1;\n      } else if (hasChildren(point.node)) {\n        node = point.node.childNodes[point.offset];\n        offset = 0;\n      } else {\n        node = point.node;\n        offset = isSkipInnerOffset ? nodeLength(point.node) : point.offset + 1;\n      }\n\n      return {\n        node: node,\n        offset: offset\n      };\n    };\n\n    /**\n     * returns whether pointA and pointB is same or not.\n     *\n     * @param {BoundaryPoint} pointA\n     * @param {BoundaryPoint} pointB\n     * @return {Boolean}\n     */\n    var isSamePoint = function (pointA, pointB) {\n      return pointA.node === pointB.node && pointA.offset === pointB.offset;\n    };\n\n    /**\n     * returns whether point is visible (can set cursor) or not.\n     * \n     * @param {BoundaryPoint} point\n     * @return {Boolean}\n     */\n    var isVisiblePoint = function (point) {\n      if (isText(point.node) || !hasChildren(point.node) || isEmpty(point.node)) {\n        return true;\n      }\n\n      var leftNode = point.node.childNodes[point.offset - 1];\n      var rightNode = point.node.childNodes[point.offset];\n      if ((!leftNode || isVoid(leftNode)) && (!rightNode || isVoid(rightNode))) {\n        return true;\n      }\n\n      return false;\n    };\n\n    /**\n     * @method prevPointUtil\n     *\n     * @param {BoundaryPoint} point\n     * @param {Function} pred\n     * @return {BoundaryPoint}\n     */\n    var prevPointUntil = function (point, pred) {\n      while (point) {\n        if (pred(point)) {\n          return point;\n        }\n\n        point = prevPoint(point);\n      }\n\n      return null;\n    };\n\n    /**\n     * @method nextPointUntil\n     *\n     * @param {BoundaryPoint} point\n     * @param {Function} pred\n     * @return {BoundaryPoint}\n     */\n    var nextPointUntil = function (point, pred) {\n      while (point) {\n        if (pred(point)) {\n          return point;\n        }\n\n        point = nextPoint(point);\n      }\n\n      return null;\n    };\n\n    /**\n     * returns whether point has character or not.\n     *\n     * @param {Point} point\n     * @return {Boolean}\n     */\n    var isCharPoint = function (point) {\n      if (!isText(point.node)) {\n        return false;\n      }\n\n      var ch = point.node.nodeValue.charAt(point.offset - 1);\n      return ch && (ch !== ' ' && ch !== NBSP_CHAR);\n    };\n\n    /**\n     * @method walkPoint\n     *\n     * @param {BoundaryPoint} startPoint\n     * @param {BoundaryPoint} endPoint\n     * @param {Function} handler\n     * @param {Boolean} isSkipInnerOffset\n     */\n    var walkPoint = function (startPoint, endPoint, handler, isSkipInnerOffset) {\n      var point = startPoint;\n\n      while (point) {\n        handler(point);\n\n        if (isSamePoint(point, endPoint)) {\n          break;\n        }\n\n        var isSkipOffset = isSkipInnerOffset &&\n                           startPoint.node !== point.node &&\n                           endPoint.node !== point.node;\n        point = nextPoint(point, isSkipOffset);\n      }\n    };\n\n    /**\n     * @method makeOffsetPath\n     *\n     * return offsetPath(array of offset) from ancestor\n     *\n     * @param {Node} ancestor - ancestor node\n     * @param {Node} node\n     */\n    var makeOffsetPath = function (ancestor, node) {\n      var ancestors = listAncestor(node, func.eq(ancestor));\n      return ancestors.map(position).reverse();\n    };\n\n    /**\n     * @method fromOffsetPath\n     *\n     * return element from offsetPath(array of offset)\n     *\n     * @param {Node} ancestor - ancestor node\n     * @param {array} offsets - offsetPath\n     */\n    var fromOffsetPath = function (ancestor, offsets) {\n      var current = ancestor;\n      for (var i = 0, len = offsets.length; i < len; i++) {\n        if (current.childNodes.length <= offsets[i]) {\n          current = current.childNodes[current.childNodes.length - 1];\n        } else {\n          current = current.childNodes[offsets[i]];\n        }\n      }\n      return current;\n    };\n\n    /**\n     * @method splitNode\n     *\n     * split element or #text\n     *\n     * @param {BoundaryPoint} point\n     * @param {Object} [options]\n     * @param {Boolean} [options.isSkipPaddingBlankHTML] - default: false\n     * @param {Boolean} [options.isNotSplitEdgePoint] - default: false\n     * @return {Node} right node of boundaryPoint\n     */\n    var splitNode = function (point, options) {\n      var isSkipPaddingBlankHTML = options && options.isSkipPaddingBlankHTML;\n      var isNotSplitEdgePoint = options && options.isNotSplitEdgePoint;\n\n      // edge case\n      if (isEdgePoint(point) && (isText(point.node) || isNotSplitEdgePoint)) {\n        if (isLeftEdgePoint(point)) {\n          return point.node;\n        } else if (isRightEdgePoint(point)) {\n          return point.node.nextSibling;\n        }\n      }\n\n      // split #text\n      if (isText(point.node)) {\n        return point.node.splitText(point.offset);\n      } else {\n        var childNode = point.node.childNodes[point.offset];\n        var clone = insertAfter(point.node.cloneNode(false), point.node);\n        appendChildNodes(clone, listNext(childNode));\n\n        if (!isSkipPaddingBlankHTML) {\n          paddingBlankHTML(point.node);\n          paddingBlankHTML(clone);\n        }\n\n        return clone;\n      }\n    };\n\n    /**\n     * @method splitTree\n     *\n     * split tree by point\n     *\n     * @param {Node} root - split root\n     * @param {BoundaryPoint} point\n     * @param {Object} [options]\n     * @param {Boolean} [options.isSkipPaddingBlankHTML] - default: false\n     * @param {Boolean} [options.isNotSplitEdgePoint] - default: false\n     * @return {Node} right node of boundaryPoint\n     */\n    var splitTree = function (root, point, options) {\n      // ex) [#text, <span>, <p>]\n      var ancestors = listAncestor(point.node, func.eq(root));\n\n      if (!ancestors.length) {\n        return null;\n      } else if (ancestors.length === 1) {\n        return splitNode(point, options);\n      }\n\n      return ancestors.reduce(function (node, parent) {\n        if (node === point.node) {\n          node = splitNode(point, options);\n        }\n\n        return splitNode({\n          node: parent,\n          offset: node ? dom.position(node) : nodeLength(parent)\n        }, options);\n      });\n    };\n\n    /**\n     * split point\n     *\n     * @param {Point} point\n     * @param {Boolean} isInline\n     * @return {Object}\n     */\n    var splitPoint = function (point, isInline) {\n      // find splitRoot, container\n      //  - inline: splitRoot is a child of paragraph\n      //  - block: splitRoot is a child of bodyContainer\n      var pred = isInline ? isPara : isBodyContainer;\n      var ancestors = listAncestor(point.node, pred);\n      var topAncestor = list.last(ancestors) || point.node;\n\n      var splitRoot, container;\n      if (pred(topAncestor)) {\n        splitRoot = ancestors[ancestors.length - 2];\n        container = topAncestor;\n      } else {\n        splitRoot = topAncestor;\n        container = splitRoot.parentNode;\n      }\n\n      // if splitRoot is exists, split with splitTree\n      var pivot = splitRoot && splitTree(splitRoot, point, {\n        isSkipPaddingBlankHTML: isInline,\n        isNotSplitEdgePoint: isInline\n      });\n\n      // if container is point.node, find pivot with point.offset\n      if (!pivot && container === point.node) {\n        pivot = point.node.childNodes[point.offset];\n      }\n\n      return {\n        rightNode: pivot,\n        container: container\n      };\n    };\n\n    var create = function (nodeName) {\n      return document.createElement(nodeName);\n    };\n\n    var createText = function (text) {\n      return document.createTextNode(text);\n    };\n\n    /**\n     * @method remove\n     *\n     * remove node, (isRemoveChild: remove child or not)\n     *\n     * @param {Node} node\n     * @param {Boolean} isRemoveChild\n     */\n    var remove = function (node, isRemoveChild) {\n      if (!node || !node.parentNode) { return; }\n      if (node.removeNode) { return node.removeNode(isRemoveChild); }\n\n      var parent = node.parentNode;\n      if (!isRemoveChild) {\n        var nodes = [];\n        var i, len;\n        for (i = 0, len = node.childNodes.length; i < len; i++) {\n          nodes.push(node.childNodes[i]);\n        }\n\n        for (i = 0, len = nodes.length; i < len; i++) {\n          parent.insertBefore(nodes[i], node);\n        }\n      }\n\n      parent.removeChild(node);\n    };\n\n    /**\n     * @method removeWhile\n     *\n     * @param {Node} node\n     * @param {Function} pred\n     */\n    var removeWhile = function (node, pred) {\n      while (node) {\n        if (isEditable(node) || !pred(node)) {\n          break;\n        }\n\n        var parent = node.parentNode;\n        remove(node);\n        node = parent;\n      }\n    };\n\n    /**\n     * @method replace\n     *\n     * replace node with provided nodeName\n     *\n     * @param {Node} node\n     * @param {String} nodeName\n     * @return {Node} - new node\n     */\n    var replace = function (node, nodeName) {\n      if (node.nodeName.toUpperCase() === nodeName.toUpperCase()) {\n        return node;\n      }\n\n      var newNode = create(nodeName);\n\n      if (node.style.cssText) {\n        newNode.style.cssText = node.style.cssText;\n      }\n\n      appendChildNodes(newNode, list.from(node.childNodes));\n      insertAfter(newNode, node);\n      remove(node);\n\n      return newNode;\n    };\n\n    var isTextarea = makePredByNodeName('TEXTAREA');\n\n    /**\n     * @param {jQuery} $node\n     * @param {Boolean} [stripLinebreaks] - default: false\n     */\n    var value = function ($node, stripLinebreaks) {\n      var val = isTextarea($node[0]) ? $node.val() : $node.html();\n      if (stripLinebreaks) {\n        return val.replace(/[\\n\\r]/g, '');\n      }\n      return val;\n    };\n\n    /**\n     * @method html\n     *\n     * get the HTML contents of node\n     *\n     * @param {jQuery} $node\n     * @param {Boolean} [isNewlineOnBlock]\n     */\n    var html = function ($node, isNewlineOnBlock) {\n      var markup = value($node);\n\n      if (isNewlineOnBlock) {\n        var regexTag = /<(\\/?)(\\b(?!!)[^>\\s]*)(.*?)(\\s*\\/?>)/g;\n        markup = markup.replace(regexTag, function (match, endSlash, name) {\n          name = name.toUpperCase();\n          var isEndOfInlineContainer = /^DIV|^TD|^TH|^P|^LI|^H[1-7]/.test(name) &&\n                                       !!endSlash;\n          var isBlockNode = /^BLOCKQUOTE|^TABLE|^TBODY|^TR|^HR|^UL|^OL/.test(name);\n\n          return match + ((isEndOfInlineContainer || isBlockNode) ? '\\n' : '');\n        });\n        markup = $.trim(markup);\n      }\n\n      return markup;\n    };\n\n    return {\n      /** @property {String} NBSP_CHAR */\n      NBSP_CHAR: NBSP_CHAR,\n      /** @property {String} ZERO_WIDTH_NBSP_CHAR */\n      ZERO_WIDTH_NBSP_CHAR: ZERO_WIDTH_NBSP_CHAR,\n      /** @property {String} blank */\n      blank: blankHTML,\n      /** @property {String} emptyPara */\n      emptyPara: '<p>' + blankHTML + '</p>',\n      makePredByNodeName: makePredByNodeName,\n      isEditable: isEditable,\n      isControlSizing: isControlSizing,\n      buildLayoutInfo: buildLayoutInfo,\n      makeLayoutInfo: makeLayoutInfo,\n      isText: isText,\n      isVoid: isVoid,\n      isPara: isPara,\n      isPurePara: isPurePara,\n      isInline: isInline,\n      isBlock: func.not(isInline),\n      isBodyInline: isBodyInline,\n      isBody: isBody,\n      isParaInline: isParaInline,\n      isList: isList,\n      isTable: isTable,\n      isCell: isCell,\n      isBlockquote: isBlockquote,\n      isBodyContainer: isBodyContainer,\n      isAnchor: isAnchor,\n      isDiv: makePredByNodeName('DIV'),\n      isLi: isLi,\n      isBR: makePredByNodeName('BR'),\n      isSpan: makePredByNodeName('SPAN'),\n      isB: makePredByNodeName('B'),\n      isU: makePredByNodeName('U'),\n      isS: makePredByNodeName('S'),\n      isI: makePredByNodeName('I'),\n      isImg: makePredByNodeName('IMG'),\n      isTextarea: isTextarea,\n      isEmpty: isEmpty,\n      isEmptyAnchor: func.and(isAnchor, isEmpty),\n      isClosestSibling: isClosestSibling,\n      withClosestSiblings: withClosestSiblings,\n      nodeLength: nodeLength,\n      isLeftEdgePoint: isLeftEdgePoint,\n      isRightEdgePoint: isRightEdgePoint,\n      isEdgePoint: isEdgePoint,\n      isLeftEdgeOf: isLeftEdgeOf,\n      isRightEdgeOf: isRightEdgeOf,\n      isLeftEdgePointOf: isLeftEdgePointOf,\n      isRightEdgePointOf: isRightEdgePointOf,\n      prevPoint: prevPoint,\n      nextPoint: nextPoint,\n      isSamePoint: isSamePoint,\n      isVisiblePoint: isVisiblePoint,\n      prevPointUntil: prevPointUntil,\n      nextPointUntil: nextPointUntil,\n      isCharPoint: isCharPoint,\n      walkPoint: walkPoint,\n      ancestor: ancestor,\n      singleChildAncestor: singleChildAncestor,\n      listAncestor: listAncestor,\n      lastAncestor: lastAncestor,\n      listNext: listNext,\n      listPrev: listPrev,\n      listDescendant: listDescendant,\n      commonAncestor: commonAncestor,\n      wrap: wrap,\n      insertAfter: insertAfter,\n      appendChildNodes: appendChildNodes,\n      position: position,\n      hasChildren: hasChildren,\n      makeOffsetPath: makeOffsetPath,\n      fromOffsetPath: fromOffsetPath,\n      splitTree: splitTree,\n      splitPoint: splitPoint,\n      create: create,\n      createText: createText,\n      remove: remove,\n      removeWhile: removeWhile,\n      replace: replace,\n      html: html,\n      value: value\n    };\n  })();\n\n  return dom;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/core/func.js",
    "content": "define('summernote/core/func', function () {\n  /**\n   * @class core.func\n   *\n   * func utils (for high-order func's arg)\n   *\n   * @singleton\n   * @alternateClassName func\n   */\n  var func = (function () {\n    var eq = function (itemA) {\n      return function (itemB) {\n        return itemA === itemB;\n      };\n    };\n\n    var eq2 = function (itemA, itemB) {\n      return itemA === itemB;\n    };\n\n    var peq2 = function (propName) {\n      return function (itemA, itemB) {\n        return itemA[propName] === itemB[propName];\n      };\n    };\n\n    var ok = function () {\n      return true;\n    };\n\n    var fail = function () {\n      return false;\n    };\n\n    var not = function (f) {\n      return function () {\n        return !f.apply(f, arguments);\n      };\n    };\n\n    var and = function (fA, fB) {\n      return function (item) {\n        return fA(item) && fB(item);\n      };\n    };\n\n    var self = function (a) {\n      return a;\n    };\n\n    var idCounter = 0;\n\n    /**\n     * generate a globally-unique id\n     *\n     * @param {String} [prefix]\n     */\n    var uniqueId = function (prefix) {\n      var id = ++idCounter + '';\n      return prefix ? prefix + id : id;\n    };\n\n    /**\n     * returns bnd (bounds) from rect\n     *\n     * - IE Compatability Issue: http://goo.gl/sRLOAo\n     * - Scroll Issue: http://goo.gl/sNjUc\n     *\n     * @param {Rect} rect\n     * @return {Object} bounds\n     * @return {Number} bounds.top\n     * @return {Number} bounds.left\n     * @return {Number} bounds.width\n     * @return {Number} bounds.height\n     */\n    var rect2bnd = function (rect) {\n      var $document = $(document);\n      return {\n        top: rect.top + $document.scrollTop(),\n        left: rect.left + $document.scrollLeft(),\n        width: rect.right - rect.left,\n        height: rect.bottom - rect.top\n      };\n    };\n\n    /**\n     * returns a copy of the object where the keys have become the values and the values the keys.\n     * @param {Object} obj\n     * @return {Object}\n     */\n    var invertObject = function (obj) {\n      var inverted = {};\n      for (var key in obj) {\n        if (obj.hasOwnProperty(key)) {\n          inverted[obj[key]] = key;\n        }\n      }\n      return inverted;\n    };\n\n    /**\n     * @param {String} namespace\n     * @param {String} [prefix]\n     * @return {String}\n     */\n    var namespaceToCamel = function (namespace, prefix) {\n      prefix = prefix || '';\n      return prefix + namespace.split('.').map(function (name) {\n        return name.substring(0, 1).toUpperCase() + name.substring(1);\n      }).join('');\n    };\n\n    return {\n      eq: eq,\n      eq2: eq2,\n      peq2: peq2,\n      ok: ok,\n      fail: fail,\n      self: self,\n      not: not,\n      and: and,\n      uniqueId: uniqueId,\n      rect2bnd: rect2bnd,\n      invertObject: invertObject,\n      namespaceToCamel: namespaceToCamel\n    };\n  })();\n\n  return func;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/core/key.js",
    "content": "define([\n  'summernote/core/list',\n  'summernote/core/func'\n], function (list, func) {\n  /**\n   * @class core.key\n   *\n   * Object for keycodes.\n   *\n   * @singleton\n   * @alternateClassName key\n   */\n  var key = (function () {\n    var keyMap = {\n      'BACKSPACE': 8,\n      'TAB': 9,\n      'ENTER': 13,\n      'SPACE': 32,\n\n      // Number: 0-9\n      'NUM0': 48,\n      'NUM1': 49,\n      'NUM2': 50,\n      'NUM3': 51,\n      'NUM4': 52,\n      'NUM5': 53,\n      'NUM6': 54,\n      'NUM7': 55,\n      'NUM8': 56,\n\n      // Alphabet: a-z\n      'B': 66,\n      'E': 69,\n      'I': 73,\n      'J': 74,\n      'K': 75,\n      'L': 76,\n      'R': 82,\n      'S': 83,\n      'U': 85,\n      'V': 86,\n      'Y': 89,\n      'Z': 90,\n\n      'SLASH': 191,\n      'LEFTBRACKET': 219,\n      'BACKSLASH': 220,\n      'RIGHTBRACKET': 221\n    };\n\n    return {\n      /**\n       * @method isEdit\n       *\n       * @param {Number} keyCode\n       * @return {Boolean}\n       */\n      isEdit: function (keyCode) {\n        return list.contains([8, 9, 13, 32], keyCode);\n      },\n      /**\n       * @method isMove\n       *\n       * @param {Number} keyCode\n       * @return {Boolean}\n       */\n      isMove: function (keyCode) {\n        return list.contains([37, 38, 39, 40], keyCode);\n      },\n      /**\n       * @property {Object} nameFromCode\n       * @property {String} nameFromCode.8 \"BACKSPACE\"\n       */\n      nameFromCode: func.invertObject(keyMap),\n      code: keyMap\n    };\n  })();\n\n  return key;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/core/list.js",
    "content": "define(['summernote/core/func'], function (func) {\n  /**\n   * @class core.list\n   *\n   * list utils\n   *\n   * @singleton\n   * @alternateClassName list\n   */\n  var list = (function () {\n    /**\n     * returns the first item of an array.\n     *\n     * @param {Array} array\n     */\n    var head = function (array) {\n      return array[0];\n    };\n\n    /**\n     * returns the last item of an array.\n     *\n     * @param {Array} array\n     */\n    var last = function (array) {\n      return array[array.length - 1];\n    };\n\n    /**\n     * returns everything but the last entry of the array.\n     *\n     * @param {Array} array\n     */\n    var initial = function (array) {\n      return array.slice(0, array.length - 1);\n    };\n\n    /**\n     * returns the rest of the items in an array.\n     *\n     * @param {Array} array\n     */\n    var tail = function (array) {\n      return array.slice(1);\n    };\n\n    /**\n     * returns item of array\n     */\n    var find = function (array, pred) {\n      for (var idx = 0, len = array.length; idx < len; idx ++) {\n        var item = array[idx];\n        if (pred(item)) {\n          return item;\n        }\n      }\n    };\n\n    /**\n     * returns true if all of the values in the array pass the predicate truth test.\n     */\n    var all = function (array, pred) {\n      for (var idx = 0, len = array.length; idx < len; idx ++) {\n        if (!pred(array[idx])) {\n          return false;\n        }\n      }\n      return true;\n    };\n\n    /**\n     * returns index of item\n     */\n    var indexOf = function (array, item) {\n      return $.inArray(item, array);\n    };\n\n    /**\n     * returns true if the value is present in the list.\n     */\n    var contains = function (array, item) {\n      return indexOf(array, item) !== -1;\n    };\n\n    /**\n     * get sum from a list\n     *\n     * @param {Array} array - array\n     * @param {Function} fn - iterator\n     */\n    var sum = function (array, fn) {\n      fn = fn || func.self;\n      return array.reduce(function (memo, v) {\n        return memo + fn(v);\n      }, 0);\n    };\n  \n    /**\n     * returns a copy of the collection with array type.\n     * @param {Collection} collection - collection eg) node.childNodes, ...\n     */\n    var from = function (collection) {\n      var result = [], idx = -1, length = collection.length;\n      while (++idx < length) {\n        result[idx] = collection[idx];\n      }\n      return result;\n    };\n  \n    /**\n     * cluster elements by predicate function.\n     *\n     * @param {Array} array - array\n     * @param {Function} fn - predicate function for cluster rule\n     * @param {Array[]}\n     */\n    var clusterBy = function (array, fn) {\n      if (!array.length) { return []; }\n      var aTail = tail(array);\n      return aTail.reduce(function (memo, v) {\n        var aLast = last(memo);\n        if (fn(last(aLast), v)) {\n          aLast[aLast.length] = v;\n        } else {\n          memo[memo.length] = [v];\n        }\n        return memo;\n      }, [[head(array)]]);\n    };\n  \n    /**\n     * returns a copy of the array with all falsy values removed\n     *\n     * @param {Array} array - array\n     * @param {Function} fn - predicate function for cluster rule\n     */\n    var compact = function (array) {\n      var aResult = [];\n      for (var idx = 0, len = array.length; idx < len; idx ++) {\n        if (array[idx]) { aResult.push(array[idx]); }\n      }\n      return aResult;\n    };\n\n    /**\n     * produces a duplicate-free version of the array\n     *\n     * @param {Array} array\n     */\n    var unique = function (array) {\n      var results = [];\n\n      for (var idx = 0, len = array.length; idx < len; idx ++) {\n        if (!contains(results, array[idx])) {\n          results.push(array[idx]);\n        }\n      }\n\n      return results;\n    };\n\n    /**\n     * returns next item.\n     * @param {Array} array\n     */\n    var next = function (array, item) {\n      var idx = indexOf(array, item);\n      if (idx === -1) { return null; }\n\n      return array[idx + 1];\n    };\n\n    /**\n     * returns prev item.\n     * @param {Array} array\n     */\n    var prev = function (array, item) {\n      var idx = indexOf(array, item);\n      if (idx === -1) { return null; }\n\n      return array[idx - 1];\n    };\n  \n    return { head: head, last: last, initial: initial, tail: tail,\n             prev: prev, next: next, find: find, contains: contains,\n             all: all, sum: sum, from: from,\n             clusterBy: clusterBy, compact: compact, unique: unique };\n  })();\n\n  return list;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/core/range.js",
    "content": "define([\n  'summernote/core/agent',\n  'summernote/core/func',\n  'summernote/core/list',\n  'summernote/core/dom'\n], function (agent, func, list, dom) {\n\n  var range = (function () {\n\n    /**\n     * return boundaryPoint from TextRange, inspired by Andy Na's HuskyRange.js\n     *\n     * @param {TextRange} textRange\n     * @param {Boolean} isStart\n     * @return {BoundaryPoint}\n     *\n     * @see http://msdn.microsoft.com/en-us/library/ie/ms535872(v=vs.85).aspx\n     */\n    var textRangeToPoint = function (textRange, isStart) {\n      var container = textRange.parentElement(), offset;\n  \n      var tester = document.body.createTextRange(), prevContainer;\n      var childNodes = list.from(container.childNodes);\n      for (offset = 0; offset < childNodes.length; offset++) {\n        if (dom.isText(childNodes[offset])) {\n          continue;\n        }\n        tester.moveToElementText(childNodes[offset]);\n        if (tester.compareEndPoints('StartToStart', textRange) >= 0) {\n          break;\n        }\n        prevContainer = childNodes[offset];\n      }\n  \n      if (offset !== 0 && dom.isText(childNodes[offset - 1])) {\n        var textRangeStart = document.body.createTextRange(), curTextNode = null;\n        textRangeStart.moveToElementText(prevContainer || container);\n        textRangeStart.collapse(!prevContainer);\n        curTextNode = prevContainer ? prevContainer.nextSibling : container.firstChild;\n  \n        var pointTester = textRange.duplicate();\n        pointTester.setEndPoint('StartToStart', textRangeStart);\n        var textCount = pointTester.text.replace(/[\\r\\n]/g, '').length;\n  \n        while (textCount > curTextNode.nodeValue.length && curTextNode.nextSibling) {\n          textCount -= curTextNode.nodeValue.length;\n          curTextNode = curTextNode.nextSibling;\n        }\n  \n        /* jshint ignore:start */\n        var dummy = curTextNode.nodeValue; // enforce IE to re-reference curTextNode, hack\n        /* jshint ignore:end */\n  \n        if (isStart && curTextNode.nextSibling && dom.isText(curTextNode.nextSibling) &&\n            textCount === curTextNode.nodeValue.length) {\n          textCount -= curTextNode.nodeValue.length;\n          curTextNode = curTextNode.nextSibling;\n        }\n  \n        container = curTextNode;\n        offset = textCount;\n      }\n  \n      return {\n        cont: container,\n        offset: offset\n      };\n    };\n    \n    /**\n     * return TextRange from boundary point (inspired by google closure-library)\n     * @param {BoundaryPoint} point\n     * @return {TextRange}\n     */\n    var pointToTextRange = function (point) {\n      var textRangeInfo = function (container, offset) {\n        var node, isCollapseToStart;\n  \n        if (dom.isText(container)) {\n          var prevTextNodes = dom.listPrev(container, func.not(dom.isText));\n          var prevContainer = list.last(prevTextNodes).previousSibling;\n          node =  prevContainer || container.parentNode;\n          offset += list.sum(list.tail(prevTextNodes), dom.nodeLength);\n          isCollapseToStart = !prevContainer;\n        } else {\n          node = container.childNodes[offset] || container;\n          if (dom.isText(node)) {\n            return textRangeInfo(node, 0);\n          }\n  \n          offset = 0;\n          isCollapseToStart = false;\n        }\n  \n        return {\n          node: node,\n          collapseToStart: isCollapseToStart,\n          offset: offset\n        };\n      };\n  \n      var textRange = document.body.createTextRange();\n      var info = textRangeInfo(point.node, point.offset);\n  \n      textRange.moveToElementText(info.node);\n      textRange.collapse(info.collapseToStart);\n      textRange.moveStart('character', info.offset);\n      return textRange;\n    };\n    \n    /**\n     * Wrapped Range\n     *\n     * @constructor\n     * @param {Node} sc - start container\n     * @param {Number} so - start offset\n     * @param {Node} ec - end container\n     * @param {Number} eo - end offset\n     */\n    var WrappedRange = function (sc, so, ec, eo) {\n      this.sc = sc;\n      this.so = so;\n      this.ec = ec;\n      this.eo = eo;\n  \n      // nativeRange: get nativeRange from sc, so, ec, eo\n      var nativeRange = function () {\n        if (agent.isW3CRangeSupport) {\n          var w3cRange = document.createRange();\n          w3cRange.setStart(sc, so);\n          w3cRange.setEnd(ec, eo);\n\n          return w3cRange;\n        } else {\n          var textRange = pointToTextRange({\n            node: sc,\n            offset: so\n          });\n\n          textRange.setEndPoint('EndToEnd', pointToTextRange({\n            node: ec,\n            offset: eo\n          }));\n\n          return textRange;\n        }\n      };\n\n      this.getPoints = function () {\n        return {\n          sc: sc,\n          so: so,\n          ec: ec,\n          eo: eo\n        };\n      };\n\n      this.getStartPoint = function () {\n        return {\n          node: sc,\n          offset: so\n        };\n      };\n\n      this.getEndPoint = function () {\n        return {\n          node: ec,\n          offset: eo\n        };\n      };\n\n      /**\n       * select update visible range\n       */\n      this.select = function () {\n        var nativeRng = nativeRange();\n        if (agent.isW3CRangeSupport) {\n          var selection = document.getSelection();\n          if (selection.rangeCount > 0) {\n            selection.removeAllRanges();\n          }\n          selection.addRange(nativeRng);\n        } else {\n          nativeRng.select();\n        }\n        \n        return this;\n      };\n\n      /**\n       * @return {WrappedRange}\n       */\n      this.normalize = function () {\n\n        /**\n         * @param {BoundaryPoint} point\n         * @param {Boolean} isLeftToRight\n         * @return {BoundaryPoint}\n         */\n        var getVisiblePoint = function (point, isLeftToRight) {\n          if ((dom.isVisiblePoint(point) && !dom.isEdgePoint(point)) ||\n              (dom.isVisiblePoint(point) && dom.isRightEdgePoint(point) && !isLeftToRight) ||\n              (dom.isVisiblePoint(point) && dom.isLeftEdgePoint(point) && isLeftToRight) ||\n              (dom.isVisiblePoint(point) && dom.isBlock(point.node) && dom.isEmpty(point.node))) {\n            return point;\n          }\n\n          // point on block's edge\n          var block = dom.ancestor(point.node, dom.isBlock);\n          if (((dom.isLeftEdgePointOf(point, block) || dom.isVoid(dom.prevPoint(point).node)) && !isLeftToRight) ||\n              ((dom.isRightEdgePointOf(point, block) || dom.isVoid(dom.nextPoint(point).node)) && isLeftToRight)) {\n\n            // returns point already on visible point\n            if (dom.isVisiblePoint(point)) {\n              return point;\n            }\n            // reverse direction \n            isLeftToRight = !isLeftToRight;\n          }\n\n          var nextPoint = isLeftToRight ? dom.nextPointUntil(dom.nextPoint(point), dom.isVisiblePoint) :\n                                          dom.prevPointUntil(dom.prevPoint(point), dom.isVisiblePoint);\n          return nextPoint || point;\n        };\n\n        var endPoint = getVisiblePoint(this.getEndPoint(), false);\n        var startPoint = this.isCollapsed() ? endPoint : getVisiblePoint(this.getStartPoint(), true);\n\n        return new WrappedRange(\n          startPoint.node,\n          startPoint.offset,\n          endPoint.node,\n          endPoint.offset\n        );\n      };\n\n      /**\n       * returns matched nodes on range\n       *\n       * @param {Function} [pred] - predicate function\n       * @param {Object} [options]\n       * @param {Boolean} [options.includeAncestor]\n       * @param {Boolean} [options.fullyContains]\n       * @return {Node[]}\n       */\n      this.nodes = function (pred, options) {\n        pred = pred || func.ok;\n\n        var includeAncestor = options && options.includeAncestor;\n        var fullyContains = options && options.fullyContains;\n\n        // TODO compare points and sort\n        var startPoint = this.getStartPoint();\n        var endPoint = this.getEndPoint();\n\n        var nodes = [];\n        var leftEdgeNodes = [];\n\n        dom.walkPoint(startPoint, endPoint, function (point) {\n          if (dom.isEditable(point.node)) {\n            return;\n          }\n\n          var node;\n          if (fullyContains) {\n            if (dom.isLeftEdgePoint(point)) {\n              leftEdgeNodes.push(point.node);\n            }\n            if (dom.isRightEdgePoint(point) && list.contains(leftEdgeNodes, point.node)) {\n              node = point.node;\n            }\n          } else if (includeAncestor) {\n            node = dom.ancestor(point.node, pred);\n          } else {\n            node = point.node;\n          }\n\n          if (node && pred(node)) {\n            nodes.push(node);\n          }\n        }, true);\n\n        return list.unique(nodes);\n      };\n\n      /**\n       * returns commonAncestor of range\n       * @return {Element} - commonAncestor\n       */\n      this.commonAncestor = function () {\n        return dom.commonAncestor(sc, ec);\n      };\n\n      /**\n       * returns expanded range by pred\n       *\n       * @param {Function} pred - predicate function\n       * @return {WrappedRange}\n       */\n      this.expand = function (pred) {\n        var startAncestor = dom.ancestor(sc, pred);\n        var endAncestor = dom.ancestor(ec, pred);\n\n        if (!startAncestor && !endAncestor) {\n          return new WrappedRange(sc, so, ec, eo);\n        }\n\n        var boundaryPoints = this.getPoints();\n\n        if (startAncestor) {\n          boundaryPoints.sc = startAncestor;\n          boundaryPoints.so = 0;\n        }\n\n        if (endAncestor) {\n          boundaryPoints.ec = endAncestor;\n          boundaryPoints.eo = dom.nodeLength(endAncestor);\n        }\n\n        return new WrappedRange(\n          boundaryPoints.sc,\n          boundaryPoints.so,\n          boundaryPoints.ec,\n          boundaryPoints.eo\n        );\n      };\n\n      /**\n       * @param {Boolean} isCollapseToStart\n       * @return {WrappedRange}\n       */\n      this.collapse = function (isCollapseToStart) {\n        if (isCollapseToStart) {\n          return new WrappedRange(sc, so, sc, so);\n        } else {\n          return new WrappedRange(ec, eo, ec, eo);\n        }\n      };\n\n      /**\n       * splitText on range\n       */\n      this.splitText = function () {\n        var isSameContainer = sc === ec;\n        var boundaryPoints = this.getPoints();\n\n        if (dom.isText(ec) && !dom.isEdgePoint(this.getEndPoint())) {\n          ec.splitText(eo);\n        }\n\n        if (dom.isText(sc) && !dom.isEdgePoint(this.getStartPoint())) {\n          boundaryPoints.sc = sc.splitText(so);\n          boundaryPoints.so = 0;\n\n          if (isSameContainer) {\n            boundaryPoints.ec = boundaryPoints.sc;\n            boundaryPoints.eo = eo - so;\n          }\n        }\n\n        return new WrappedRange(\n          boundaryPoints.sc,\n          boundaryPoints.so,\n          boundaryPoints.ec,\n          boundaryPoints.eo\n        );\n      };\n\n      /**\n       * delete contents on range\n       * @return {WrappedRange}\n       */\n      this.deleteContents = function () {\n        if (this.isCollapsed()) {\n          return this;\n        }\n\n        var rng = this.splitText();\n        var nodes = rng.nodes(null, {\n          fullyContains: true\n        });\n\n        // find new cursor point\n        var point = dom.prevPointUntil(rng.getStartPoint(), function (point) {\n          return !list.contains(nodes, point.node);\n        });\n\n        var emptyParents = [];\n        $.each(nodes, function (idx, node) {\n          // find empty parents\n          var parent = node.parentNode;\n          if (point.node !== parent && dom.nodeLength(parent) === 1) {\n            emptyParents.push(parent);\n          }\n          dom.remove(node, false);\n        });\n\n        // remove empty parents\n        $.each(emptyParents, function (idx, node) {\n          dom.remove(node, false);\n        });\n\n        return new WrappedRange(\n          point.node,\n          point.offset,\n          point.node,\n          point.offset\n        ).normalize();\n      };\n      \n      /**\n       * makeIsOn: return isOn(pred) function\n       */\n      var makeIsOn = function (pred) {\n        return function () {\n          var ancestor = dom.ancestor(sc, pred);\n          return !!ancestor && (ancestor === dom.ancestor(ec, pred));\n        };\n      };\n  \n      // isOnEditable: judge whether range is on editable or not\n      this.isOnEditable = makeIsOn(dom.isEditable);\n      // isOnList: judge whether range is on list node or not\n      this.isOnList = makeIsOn(dom.isList);\n      // isOnAnchor: judge whether range is on anchor node or not\n      this.isOnAnchor = makeIsOn(dom.isAnchor);\n      // isOnAnchor: judge whether range is on cell node or not\n      this.isOnCell = makeIsOn(dom.isCell);\n\n      /**\n       * @param {Function} pred\n       * @return {Boolean}\n       */\n      this.isLeftEdgeOf = function (pred) {\n        if (!dom.isLeftEdgePoint(this.getStartPoint())) {\n          return false;\n        }\n\n        var node = dom.ancestor(this.sc, pred);\n        return node && dom.isLeftEdgeOf(this.sc, node);\n      };\n\n      /**\n       * returns whether range was collapsed or not\n       */\n      this.isCollapsed = function () {\n        return sc === ec && so === eo;\n      };\n\n      /**\n       * wrap inline nodes which children of body with paragraph\n       *\n       * @return {WrappedRange}\n       */\n      this.wrapBodyInlineWithPara = function () {\n        if (dom.isBodyContainer(sc) && dom.isEmpty(sc)) {\n          sc.innerHTML = dom.emptyPara;\n          return new WrappedRange(sc.firstChild, 0, sc.firstChild, 0);\n        }\n\n        /**\n         * [workaround] firefox often create range on not visible point. so normalize here.\n         *  - firefox: |<p>text</p>|\n         *  - chrome: <p>|text|</p>\n         */\n        var rng = this.normalize();\n        if (dom.isParaInline(sc) || dom.isPara(sc)) {\n          return rng;\n        }\n\n        // find inline top ancestor\n        var topAncestor;\n        if (dom.isInline(rng.sc)) {\n          var ancestors = dom.listAncestor(rng.sc, func.not(dom.isInline));\n          topAncestor = list.last(ancestors);\n          if (!dom.isInline(topAncestor)) {\n            topAncestor = ancestors[ancestors.length - 2] || rng.sc.childNodes[rng.so];\n          }\n        } else {\n          topAncestor = rng.sc.childNodes[rng.so > 0 ? rng.so - 1 : 0];\n        }\n\n        // siblings not in paragraph\n        var inlineSiblings = dom.listPrev(topAncestor, dom.isParaInline).reverse();\n        inlineSiblings = inlineSiblings.concat(dom.listNext(topAncestor.nextSibling, dom.isParaInline));\n\n        // wrap with paragraph\n        if (inlineSiblings.length) {\n          var para = dom.wrap(list.head(inlineSiblings), 'p');\n          dom.appendChildNodes(para, list.tail(inlineSiblings));\n        }\n\n        return this.normalize();\n      };\n\n      /**\n       * insert node at current cursor\n       *\n       * @param {Node} node\n       * @return {Node}\n       */\n      this.insertNode = function (node) {\n        var rng = this.wrapBodyInlineWithPara().deleteContents();\n        var info = dom.splitPoint(rng.getStartPoint(), dom.isInline(node));\n\n        if (info.rightNode) {\n          info.rightNode.parentNode.insertBefore(node, info.rightNode);\n        } else {\n          info.container.appendChild(node);\n        }\n\n        return node;\n      };\n\n      /**\n       * insert html at current cursor\n       */\n      this.pasteHTML = function (markup) {\n        var contentsContainer = $('<div></div>').html(markup)[0];\n        var childNodes = list.from(contentsContainer.childNodes);\n\n        var rng = this.wrapBodyInlineWithPara().deleteContents();\n\n        return childNodes.reverse().map(function (childNode) {\n          return rng.insertNode(childNode);\n        }).reverse();\n      };\n  \n      /**\n       * returns text in range\n       *\n       * @return {String}\n       */\n      this.toString = function () {\n        var nativeRng = nativeRange();\n        return agent.isW3CRangeSupport ? nativeRng.toString() : nativeRng.text;\n      };\n\n      /**\n       * returns range for word before cursor\n       *\n       * @param {Boolean} [findAfter] - find after cursor, default: false\n       * @return {WrappedRange}\n       */\n      this.getWordRange = function (findAfter) {\n        var endPoint = this.getEndPoint();\n\n        if (!dom.isCharPoint(endPoint)) {\n          return this;\n        }\n\n        var startPoint = dom.prevPointUntil(endPoint, function (point) {\n          return !dom.isCharPoint(point);\n        });\n\n        if (findAfter) {\n          endPoint = dom.nextPointUntil(endPoint, function (point) {\n            return !dom.isCharPoint(point);\n          });\n        }\n\n        return new WrappedRange(\n          startPoint.node,\n          startPoint.offset,\n          endPoint.node,\n          endPoint.offset\n        );\n      };\n  \n      /**\n       * create offsetPath bookmark\n       *\n       * @param {Node} editable\n       */\n      this.bookmark = function (editable) {\n        return {\n          s: {\n            path: dom.makeOffsetPath(editable, sc),\n            offset: so\n          },\n          e: {\n            path: dom.makeOffsetPath(editable, ec),\n            offset: eo\n          }\n        };\n      };\n\n      /**\n       * create offsetPath bookmark base on paragraph\n       *\n       * @param {Node[]} paras\n       */\n      this.paraBookmark = function (paras) {\n        return {\n          s: {\n            path: list.tail(dom.makeOffsetPath(list.head(paras), sc)),\n            offset: so\n          },\n          e: {\n            path: list.tail(dom.makeOffsetPath(list.last(paras), ec)),\n            offset: eo\n          }\n        };\n      };\n\n      /**\n       * getClientRects\n       * @return {Rect[]}\n       */\n      this.getClientRects = function () {\n        var nativeRng = nativeRange();\n        return nativeRng.getClientRects();\n      };\n    };\n\n  /**\n   * @class core.range\n   *\n   * Data structure\n   *  * BoundaryPoint: a point of dom tree\n   *  * BoundaryPoints: two boundaryPoints corresponding to the start and the end of the Range\n   *\n   * See to http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Position\n   *\n   * @singleton\n   * @alternateClassName range\n   */\n    return {\n      /**\n       * @method\n       * \n       * create Range Object From arguments or Browser Selection\n       *\n       * @param {Node} sc - start container\n       * @param {Number} so - start offset\n       * @param {Node} ec - end container\n       * @param {Number} eo - end offset\n       * @return {WrappedRange}\n       */\n      create : function (sc, so, ec, eo) {\n        if (!arguments.length) { // from Browser Selection\n          if (agent.isW3CRangeSupport) {\n            var selection = document.getSelection();\n            if (!selection || selection.rangeCount === 0) {\n              return null;\n            } else if (dom.isBody(selection.anchorNode)) {\n              // Firefox: returns entire body as range on initialization. We won't never need it.\n              return null;\n            }\n  \n            var nativeRng = selection.getRangeAt(0);\n            sc = nativeRng.startContainer;\n            so = nativeRng.startOffset;\n            ec = nativeRng.endContainer;\n            eo = nativeRng.endOffset;\n          } else { // IE8: TextRange\n            var textRange = document.selection.createRange();\n            var textRangeEnd = textRange.duplicate();\n            textRangeEnd.collapse(false);\n            var textRangeStart = textRange;\n            textRangeStart.collapse(true);\n  \n            var startPoint = textRangeToPoint(textRangeStart, true),\n            endPoint = textRangeToPoint(textRangeEnd, false);\n\n            // same visible point case: range was collapsed.\n            if (dom.isText(startPoint.node) && dom.isLeftEdgePoint(startPoint) &&\n                dom.isTextNode(endPoint.node) && dom.isRightEdgePoint(endPoint) &&\n                endPoint.node.nextSibling === startPoint.node) {\n              startPoint = endPoint;\n            }\n\n            sc = startPoint.cont;\n            so = startPoint.offset;\n            ec = endPoint.cont;\n            eo = endPoint.offset;\n          }\n        } else if (arguments.length === 2) { //collapsed\n          ec = sc;\n          eo = so;\n        }\n        return new WrappedRange(sc, so, ec, eo);\n      },\n\n      /**\n       * @method \n       * \n       * create WrappedRange from node\n       *\n       * @param {Node} node\n       * @return {WrappedRange}\n       */\n      createFromNode: function (node) {\n        var sc = node;\n        var so = 0;\n        var ec = node;\n        var eo = dom.nodeLength(ec);\n\n        // browsers can't target a picture or void node\n        if (dom.isVoid(sc)) {\n          so = dom.listPrev(sc).length - 1;\n          sc = sc.parentNode;\n        }\n        if (dom.isBR(ec)) {\n          eo = dom.listPrev(ec).length - 1;\n          ec = ec.parentNode;\n        } else if (dom.isVoid(ec)) {\n          eo = dom.listPrev(ec).length;\n          ec = ec.parentNode;\n        }\n\n        return this.create(sc, so, ec, eo);\n      },\n\n      /**\n       * create WrappedRange from node after position\n       *\n       * @param {Node} node\n       * @return {WrappedRange}\n       */\n      createFromNodeBefore: function (node) {\n        return this.createFromNode(node).collapse(true);\n      },\n\n      /**\n       * create WrappedRange from node after position\n       *\n       * @param {Node} node\n       * @return {WrappedRange}\n       */\n      createFromNodeAfter: function (node) {\n        return this.createFromNode(node).collapse();\n      },\n\n      /**\n       * @method \n       * \n       * create WrappedRange from bookmark\n       *\n       * @param {Node} editable\n       * @param {Object} bookmark\n       * @return {WrappedRange}\n       */\n      createFromBookmark : function (editable, bookmark) {\n        var sc = dom.fromOffsetPath(editable, bookmark.s.path);\n        var so = bookmark.s.offset;\n        var ec = dom.fromOffsetPath(editable, bookmark.e.path);\n        var eo = bookmark.e.offset;\n        return new WrappedRange(sc, so, ec, eo);\n      },\n\n      /**\n       * @method \n       *\n       * create WrappedRange from paraBookmark\n       *\n       * @param {Object} bookmark\n       * @param {Node[]} paras\n       * @return {WrappedRange}\n       */\n      createFromParaBookmark: function (bookmark, paras) {\n        var so = bookmark.s.offset;\n        var eo = bookmark.e.offset;\n        var sc = dom.fromOffsetPath(list.head(paras), bookmark.s.path);\n        var ec = dom.fromOffsetPath(list.last(paras), bookmark.e.path);\n\n        return new WrappedRange(sc, so, ec, eo);\n      }\n    };\n  })();\n\n  return range;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/defaults.js",
    "content": "define('summernote/defaults', function () {\n  /**\n   * @class defaults \n   * \n   * @singleton\n   */\n  var defaults = {\n    /** @property */\n    version: '@VERSION',\n\n    /**\n     * \n     * for event options, reference to EventHandler.attach\n     * \n     * @property {Object} options \n     * @property {String/Number} [options.width=null] set editor width \n     * @property {String/Number} [options.height=null] set editor height, ex) 300\n     * @property {String/Number} options.minHeight set minimum height of editor\n     * @property {String/Number} options.maxHeight\n     * @property {String/Number} options.focus \n     * @property {Number} options.tabsize \n     * @property {Boolean} options.styleWithSpan\n     * @property {Object} options.codemirror\n     * @property {Object} [options.codemirror.mode='text/html']\n     * @property {Object} [options.codemirror.htmlMode=true]\n     * @property {Object} [options.codemirror.lineNumbers=true]\n     * @property {String} [options.lang=en-US] language 'en-US', 'ko-KR', ...\n     * @property {String} [options.direction=null] text direction, ex) 'rtl'\n     * @property {Array} [options.toolbar]\n     * @property {Boolean} [options.airMode=false]\n     * @property {Array} [options.airPopover]\n     * @property {Fucntion} [options.onInit] initialize\n     * @property {Fucntion} [options.onsubmit]\n     */\n    options: {\n      width: null,                  // set editor width\n      height: null,                 // set editor height, ex) 300\n\n      minHeight: null,              // set minimum height of editor\n      maxHeight: null,              // set maximum height of editor\n\n      focus: false,                 // set focus to editable area after initializing summernote\n\n      tabsize: 4,                   // size of tab ex) 2 or 4\n      styleWithSpan: true,          // style with span (Chrome and FF only)\n\n      disableLinkTarget: false,     // hide link Target Checkbox\n      disableDragAndDrop: false,    // disable drag and drop event\n      disableResizeEditor: false,   // disable resizing editor\n      disableResizeImage: false,    // disable resizing image\n\n      shortcuts: true,              // enable keyboard shortcuts\n\n      textareaAutoSync: true,       // enable textarea auto sync\n\n      placeholder: false,           // enable placeholder text\n      prettifyHtml: true,           // enable prettifying html while toggling codeview\n\n      iconPrefix: 'fa fa-',         // prefix for css icon classes\n\n      icons: {\n        font: {\n          bold: 'bold',\n          italic: 'italic',\n          underline: 'underline',\n          clear: 'eraser',\n          height: 'text-height',\n          strikethrough: 'strikethrough',\n          superscript: 'superscript',\n          subscript: 'subscript'\n        },\n        image: {\n          image: 'picture-o',\n          floatLeft: 'align-left',\n          floatRight: 'align-right',\n          floatNone: 'align-justify',\n          shapeRounded: 'square',\n          shapeCircle: 'circle-o',\n          shapeThumbnail: 'picture-o',\n          shapeNone: 'times',\n          remove: 'trash-o'\n        },\n        link: {\n          link: 'link',\n          unlink: 'unlink',\n          edit: 'edit'\n        },\n        table: {\n          table: 'table'\n        },\n        hr: {\n          insert: 'minus'\n        },\n        style: {\n          style: 'magic'\n        },\n        lists: {\n          unordered: 'list-ul',\n          ordered: 'list-ol'\n        },\n        options: {\n          help: 'question',\n          fullscreen: 'arrows-alt',\n          codeview: 'code'\n        },\n        paragraph: {\n          paragraph: 'align-left',\n          outdent: 'outdent',\n          indent: 'indent',\n          left: 'align-left',\n          center: 'align-center',\n          right: 'align-right',\n          justify: 'align-justify'\n        },\n        color: {\n          recent: 'font'\n        },\n        history: {\n          undo: 'undo',\n          redo: 'repeat'\n        },\n        misc: {\n          check: 'check'\n        }\n      },\n\n      dialogsInBody: false,          // false will add dialogs into editor\n\n      codemirror: {                 // codemirror options\n        mode: 'text/html',\n        htmlMode: true,\n        lineNumbers: true\n      },\n\n      // language\n      lang: 'en-US',                // language 'en-US', 'ko-KR', ...\n      direction: null,              // text direction, ex) 'rtl'\n\n      // toolbar\n      toolbar: [\n        ['style', ['style']],\n        ['font', ['bold', 'italic', 'underline', 'clear']],\n        // ['font', ['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 'clear']],\n        ['fontname', ['fontname']],\n        ['fontsize', ['fontsize']],\n        ['color', ['color']],\n        ['para', ['ul', 'ol', 'paragraph']],\n        ['height', ['height']],\n        ['table', ['table']],\n        ['insert', ['link', 'picture', 'hr']],\n        ['view', ['fullscreen', 'codeview']],\n        ['help', ['help']]\n      ],\n\n      plugin : { },\n\n      // air mode: inline editor\n      airMode: false,\n      // airPopover: [\n      //   ['style', ['style']],\n      //   ['font', ['bold', 'italic', 'underline', 'clear']],\n      //   ['fontname', ['fontname']],\n      //   ['color', ['color']],\n      //   ['para', ['ul', 'ol', 'paragraph']],\n      //   ['height', ['height']],\n      //   ['table', ['table']],\n      //   ['insert', ['link', 'picture']],\n      //   ['help', ['help']]\n      // ],\n      airPopover: [\n        ['color', ['color']],\n        ['font', ['bold', 'underline', 'clear']],\n        ['para', ['ul', 'paragraph']],\n        ['table', ['table']],\n        ['insert', ['link', 'picture']]\n      ],\n\n      // style tag\n      styleTags: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'],\n\n      // default fontName\n      defaultFontName: 'Helvetica Neue',\n\n      // fontName\n      fontNames: [\n        'Arial', 'Arial Black', 'Comic Sans MS', 'Courier New',\n        'Helvetica Neue', 'Helvetica', 'Impact', 'Lucida Grande',\n        'Tahoma', 'Times New Roman', 'Verdana'\n      ],\n      fontNamesIgnoreCheck: [],\n\n      fontSizes: ['8', '9', '10', '11', '12', '14', '18', '24', '36'],\n\n      // pallete colors(n x n)\n      colors: [\n        ['#000000', '#424242', '#636363', '#9C9C94', '#CEC6CE', '#EFEFEF', '#F7F7F7', '#FFFFFF'],\n        ['#FF0000', '#FF9C00', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF', '#9C00FF', '#FF00FF'],\n        ['#F7C6CE', '#FFE7CE', '#FFEFC6', '#D6EFD6', '#CEDEE7', '#CEE7F7', '#D6D6E7', '#E7D6DE'],\n        ['#E79C9C', '#FFC69C', '#FFE79C', '#B5D6A5', '#A5C6CE', '#9CC6EF', '#B5A5D6', '#D6A5BD'],\n        ['#E76363', '#F7AD6B', '#FFD663', '#94BD7B', '#73A5AD', '#6BADDE', '#8C7BC6', '#C67BA5'],\n        ['#CE0000', '#E79439', '#EFC631', '#6BA54A', '#4A7B8C', '#3984C6', '#634AA5', '#A54A7B'],\n        ['#9C0000', '#B56308', '#BD9400', '#397B21', '#104A5A', '#085294', '#311873', '#731842'],\n        ['#630000', '#7B3900', '#846300', '#295218', '#083139', '#003163', '#21104A', '#4A1031']\n      ],\n\n      // lineHeight\n      lineHeights: ['1.0', '1.2', '1.4', '1.5', '1.6', '1.8', '2.0', '3.0'],\n\n      // insertTable max size\n      insertTableMaxSize: {\n        col: 10,\n        row: 10\n      },\n\n      // image\n      maximumImageFileSize: null, // size in bytes, null = no limit\n\n      // callbacks\n      oninit: null,             // initialize\n      onfocus: null,            // editable has focus\n      onblur: null,             // editable out of focus\n      onenter: null,            // enter key pressed\n      onkeyup: null,            // keyup\n      onkeydown: null,          // keydown\n      onImageUpload: null,      // imageUpload\n      onImageUploadError: null, // imageUploadError\n      onMediaDelete: null,      // media delete\n      onToolbarClick: null,\n      onsubmit: null,\n\n      /**\n       * manipulate link address when user create link\n       * @param {String} sLinkUrl\n       * @return {String}\n       */\n      onCreateLink: function (sLinkUrl) {\n        if (sLinkUrl.indexOf('@') !== -1 && sLinkUrl.indexOf(':') === -1) {\n          sLinkUrl =  'mailto:' + sLinkUrl;\n        }\n\n        return sLinkUrl;\n      },\n\n      keyMap: {\n        pc: {\n          'ENTER': 'insertParagraph',\n          'CTRL+Z': 'undo',\n          'CTRL+Y': 'redo',\n          'TAB': 'tab',\n          'SHIFT+TAB': 'untab',\n          'CTRL+B': 'bold',\n          'CTRL+I': 'italic',\n          'CTRL+U': 'underline',\n          'CTRL+SHIFT+S': 'strikethrough',\n          'CTRL+BACKSLASH': 'removeFormat',\n          'CTRL+SHIFT+L': 'justifyLeft',\n          'CTRL+SHIFT+E': 'justifyCenter',\n          'CTRL+SHIFT+R': 'justifyRight',\n          'CTRL+SHIFT+J': 'justifyFull',\n          'CTRL+SHIFT+NUM7': 'insertUnorderedList',\n          'CTRL+SHIFT+NUM8': 'insertOrderedList',\n          'CTRL+LEFTBRACKET': 'outdent',\n          'CTRL+RIGHTBRACKET': 'indent',\n          'CTRL+NUM0': 'formatPara',\n          'CTRL+NUM1': 'formatH1',\n          'CTRL+NUM2': 'formatH2',\n          'CTRL+NUM3': 'formatH3',\n          'CTRL+NUM4': 'formatH4',\n          'CTRL+NUM5': 'formatH5',\n          'CTRL+NUM6': 'formatH6',\n          'CTRL+ENTER': 'insertHorizontalRule',\n          'CTRL+K': 'showLinkDialog'\n        },\n\n        mac: {\n          'ENTER': 'insertParagraph',\n          'CMD+Z': 'undo',\n          'CMD+SHIFT+Z': 'redo',\n          'TAB': 'tab',\n          'SHIFT+TAB': 'untab',\n          'CMD+B': 'bold',\n          'CMD+I': 'italic',\n          'CMD+U': 'underline',\n          'CMD+SHIFT+S': 'strikethrough',\n          'CMD+BACKSLASH': 'removeFormat',\n          'CMD+SHIFT+L': 'justifyLeft',\n          'CMD+SHIFT+E': 'justifyCenter',\n          'CMD+SHIFT+R': 'justifyRight',\n          'CMD+SHIFT+J': 'justifyFull',\n          'CMD+SHIFT+NUM7': 'insertUnorderedList',\n          'CMD+SHIFT+NUM8': 'insertOrderedList',\n          'CMD+LEFTBRACKET': 'outdent',\n          'CMD+RIGHTBRACKET': 'indent',\n          'CMD+NUM0': 'formatPara',\n          'CMD+NUM1': 'formatH1',\n          'CMD+NUM2': 'formatH2',\n          'CMD+NUM3': 'formatH3',\n          'CMD+NUM4': 'formatH4',\n          'CMD+NUM5': 'formatH5',\n          'CMD+NUM6': 'formatH6',\n          'CMD+ENTER': 'insertHorizontalRule',\n          'CMD+K': 'showLinkDialog'\n        }\n      }\n    },\n\n    // default language: en-US\n    lang: {\n      'en-US': {\n        font: {\n          bold: 'Bold',\n          italic: 'Italic',\n          underline: 'Underline',\n          clear: 'Remove Font Style',\n          height: 'Line Height',\n          name: 'Font Family',\n          strikethrough: 'Strikethrough',\n          subscript: 'Subscript',\n          superscript: 'Superscript',\n          size: 'Font Size'\n        },\n        image: {\n          image: 'Picture',\n          insert: 'Insert Image',\n          resizeFull: 'Resize Full',\n          resizeHalf: 'Resize Half',\n          resizeQuarter: 'Resize Quarter',\n          floatLeft: 'Float Left',\n          floatRight: 'Float Right',\n          floatNone: 'Float None',\n          shapeRounded: 'Shape: Rounded',\n          shapeCircle: 'Shape: Circle',\n          shapeThumbnail: 'Shape: Thumbnail',\n          shapeNone: 'Shape: None',\n          dragImageHere: 'Drag image or text here',\n          dropImage: 'Drop image or Text',\n          selectFromFiles: 'Select from files',\n          maximumFileSize: 'Maximum file size',\n          maximumFileSizeError: 'Maximum file size exceeded.',\n          url: 'Image URL',\n          remove: 'Remove Image'\n        },\n        link: {\n          link: 'Link',\n          insert: 'Insert Link',\n          unlink: 'Unlink',\n          edit: 'Edit',\n          textToDisplay: 'Text to display',\n          url: 'To what URL should this link go?',\n          openInNewWindow: 'Open in new window'\n        },\n        table: {\n          table: 'Table'\n        },\n        hr: {\n          insert: 'Insert Horizontal Rule'\n        },\n        style: {\n          style: 'Style',\n          normal: 'Normal',\n          blockquote: 'Quote',\n          pre: 'Code',\n          h1: 'Header 1',\n          h2: 'Header 2',\n          h3: 'Header 3',\n          h4: 'Header 4',\n          h5: 'Header 5',\n          h6: 'Header 6'\n        },\n        lists: {\n          unordered: 'Unordered list',\n          ordered: 'Ordered list'\n        },\n        options: {\n          help: 'Help',\n          fullscreen: 'Full Screen',\n          codeview: 'Code View'\n        },\n        paragraph: {\n          paragraph: 'Paragraph',\n          outdent: 'Outdent',\n          indent: 'Indent',\n          left: 'Align left',\n          center: 'Align center',\n          right: 'Align right',\n          justify: 'Justify full'\n        },\n        color: {\n          recent: 'Recent Color',\n          more: 'More Color',\n          background: 'Background Color',\n          foreground: 'Foreground Color',\n          transparent: 'Transparent',\n          setTransparent: 'Set transparent',\n          reset: 'Reset',\n          resetToDefault: 'Reset to default'\n        },\n        shortcut: {\n          shortcuts: 'Keyboard shortcuts',\n          close: 'Close',\n          textFormatting: 'Text formatting',\n          action: 'Action',\n          paragraphFormatting: 'Paragraph formatting',\n          documentStyle: 'Document Style',\n          extraKeys: 'Extra keys'\n        },\n        history: {\n          undo: 'Undo',\n          redo: 'Redo'\n        }\n      }\n    }\n  };\n\n  return defaults;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/editing/Bullet.js",
    "content": "define([\n  'summernote/core/list',\n  'summernote/core/func',\n  'summernote/core/dom',\n  'summernote/core/range'\n], function (list, func, dom, range) {\n\n  /**\n   * @class editing.Bullet\n   *\n   * @alternateClassName Bullet\n   */\n  var Bullet = function () {\n    /**\n     * @method insertOrderedList\n     *\n     * toggle ordered list\n     *\n     * @type command\n     */\n    this.insertOrderedList = function () {\n      this.toggleList('OL');\n    };\n\n    /**\n     * @method insertUnorderedList\n     *\n     * toggle unordered list\n     *\n     * @type command\n     */\n    this.insertUnorderedList = function () {\n      this.toggleList('UL');\n    };\n\n    /**\n     * @method indent\n     *\n     * indent\n     *\n     * @type command\n     */\n    this.indent = function () {\n      var self = this;\n      var rng = range.create().wrapBodyInlineWithPara();\n\n      var paras = rng.nodes(dom.isPara, { includeAncestor: true });\n      var clustereds = list.clusterBy(paras, func.peq2('parentNode'));\n\n      $.each(clustereds, function (idx, paras) {\n        var head = list.head(paras);\n        if (dom.isLi(head)) {\n          self.wrapList(paras, head.parentNode.nodeName);\n        } else {\n          $.each(paras, function (idx, para) {\n            $(para).css('marginLeft', function (idx, val) {\n              return (parseInt(val, 10) || 0) + 25;\n            });\n          });\n        }\n      });\n\n      rng.select();\n    };\n\n    /**\n     * @method outdent\n     *\n     * outdent\n     *\n     * @type command\n     */\n    this.outdent = function () {\n      var self = this;\n      var rng = range.create().wrapBodyInlineWithPara();\n\n      var paras = rng.nodes(dom.isPara, { includeAncestor: true });\n      var clustereds = list.clusterBy(paras, func.peq2('parentNode'));\n\n      $.each(clustereds, function (idx, paras) {\n        var head = list.head(paras);\n        if (dom.isLi(head)) {\n          self.releaseList([paras]);\n        } else {\n          $.each(paras, function (idx, para) {\n            $(para).css('marginLeft', function (idx, val) {\n              val = (parseInt(val, 10) || 0);\n              return val > 25 ? val - 25 : '';\n            });\n          });\n        }\n      });\n\n      rng.select();\n    };\n\n    /**\n     * @method toggleList\n     *\n     * toggle list\n     *\n     * @param {String} listName - OL or UL\n     */\n    this.toggleList = function (listName) {\n      var self = this;\n      var rng = range.create().wrapBodyInlineWithPara();\n\n      var paras = rng.nodes(dom.isPara, { includeAncestor: true });\n      var bookmark = rng.paraBookmark(paras);\n      var clustereds = list.clusterBy(paras, func.peq2('parentNode'));\n\n      // paragraph to list\n      if (list.find(paras, dom.isPurePara)) {\n        var wrappedParas = [];\n        $.each(clustereds, function (idx, paras) {\n          wrappedParas = wrappedParas.concat(self.wrapList(paras, listName));\n        });\n        paras = wrappedParas;\n      // list to paragraph or change list style\n      } else {\n        var diffLists = rng.nodes(dom.isList, {\n          includeAncestor: true\n        }).filter(function (listNode) {\n          return !$.nodeName(listNode, listName);\n        });\n\n        if (diffLists.length) {\n          $.each(diffLists, function (idx, listNode) {\n            dom.replace(listNode, listName);\n          });\n        } else {\n          paras = this.releaseList(clustereds, true);\n        }\n      }\n\n      range.createFromParaBookmark(bookmark, paras).select();\n    };\n\n    /**\n     * @method wrapList\n     *\n     * @param {Node[]} paras\n     * @param {String} listName\n     * @return {Node[]}\n     */\n    this.wrapList = function (paras, listName) {\n      var head = list.head(paras);\n      var last = list.last(paras);\n\n      var prevList = dom.isList(head.previousSibling) && head.previousSibling;\n      var nextList = dom.isList(last.nextSibling) && last.nextSibling;\n\n      var listNode = prevList || dom.insertAfter(dom.create(listName || 'UL'), last);\n\n      // P to LI\n      paras = paras.map(function (para) {\n        return dom.isPurePara(para) ? dom.replace(para, 'LI') : para;\n      });\n\n      // append to list(<ul>, <ol>)\n      dom.appendChildNodes(listNode, paras);\n\n      if (nextList) {\n        dom.appendChildNodes(listNode, list.from(nextList.childNodes));\n        dom.remove(nextList);\n      }\n\n      return paras;\n    };\n\n    /**\n     * @method releaseList\n     *\n     * @param {Array[]} clustereds\n     * @param {Boolean} isEscapseToBody\n     * @return {Node[]}\n     */\n    this.releaseList = function (clustereds, isEscapseToBody) {\n      var releasedParas = [];\n\n      $.each(clustereds, function (idx, paras) {\n        var head = list.head(paras);\n        var last = list.last(paras);\n\n        var headList = isEscapseToBody ? dom.lastAncestor(head, dom.isList) :\n                                         head.parentNode;\n        var lastList = headList.childNodes.length > 1 ? dom.splitTree(headList, {\n          node: last.parentNode,\n          offset: dom.position(last) + 1\n        }, {\n          isSkipPaddingBlankHTML: true\n        }) : null;\n\n        var middleList = dom.splitTree(headList, {\n          node: head.parentNode,\n          offset: dom.position(head)\n        }, {\n          isSkipPaddingBlankHTML: true\n        });\n\n        paras = isEscapseToBody ? dom.listDescendant(middleList, dom.isLi) :\n                                  list.from(middleList.childNodes).filter(dom.isLi);\n\n        // LI to P\n        if (isEscapseToBody || !dom.isList(headList.parentNode)) {\n          paras = paras.map(function (para) {\n            return dom.replace(para, 'P');\n          });\n        }\n\n        $.each(list.from(paras).reverse(), function (idx, para) {\n          dom.insertAfter(para, headList);\n        });\n\n        // remove empty lists\n        var rootLists = list.compact([headList, middleList, lastList]);\n        $.each(rootLists, function (idx, rootList) {\n          var listNodes = [rootList].concat(dom.listDescendant(rootList, dom.isList));\n          $.each(listNodes.reverse(), function (idx, listNode) {\n            if (!dom.nodeLength(listNode)) {\n              dom.remove(listNode, true);\n            }\n          });\n        });\n\n        releasedParas = releasedParas.concat(paras);\n      });\n\n      return releasedParas;\n    };\n  };\n\n  return Bullet;\n});\n\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/editing/History.js",
    "content": "define(['summernote/core/range'], function (range) {\n  /**\n   * @class editing.History\n   *\n   * Editor History\n   *\n   */\n  var History = function ($editable) {\n    var stack = [], stackOffset = -1;\n    var editable = $editable[0];\n\n    var makeSnapshot = function () {\n      var rng = range.create();\n      var emptyBookmark = {s: {path: [], offset: 0}, e: {path: [], offset: 0}};\n\n      return {\n        contents: $editable.html(),\n        bookmark: (rng ? rng.bookmark(editable) : emptyBookmark)\n      };\n    };\n\n    var applySnapshot = function (snapshot) {\n      if (snapshot.contents !== null) {\n        $editable.html(snapshot.contents);\n      }\n      if (snapshot.bookmark !== null) {\n        range.createFromBookmark(editable, snapshot.bookmark).select();\n      }\n    };\n\n    /**\n     * undo\n     */\n    this.undo = function () {\n      // Create snap shot if not yet recorded\n      if ($editable.html() !== stack[stackOffset].contents) {\n        this.recordUndo();\n      }\n\n      if (0 < stackOffset) {\n        stackOffset--;\n        applySnapshot(stack[stackOffset]);\n      }\n    };\n\n    /**\n     * redo\n     */\n    this.redo = function () {\n      if (stack.length - 1 > stackOffset) {\n        stackOffset++;\n        applySnapshot(stack[stackOffset]);\n      }\n    };\n\n    /**\n     * recorded undo\n     */\n    this.recordUndo = function () {\n      stackOffset++;\n\n      // Wash out stack after stackOffset\n      if (stack.length > stackOffset) {\n        stack = stack.slice(0, stackOffset);\n      }\n\n      // Create new snapshot and push it to the end\n      stack.push(makeSnapshot());\n    };\n\n    // Create first undo stack\n    this.recordUndo();\n  };\n\n  return History;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/editing/Style.js",
    "content": "define([\n  'summernote/core/agent',\n  'summernote/core/func',\n  'summernote/core/list',\n  'summernote/core/dom'\n], function (agent, func, list, dom) {\n  /**\n   * @class editing.Style\n   *\n   * Style\n   *\n   */\n  var Style = function () {\n    /**\n     * @method jQueryCSS\n     *\n     * [workaround] for old jQuery\n     * passing an array of style properties to .css()\n     * will result in an object of property-value pairs.\n     * (compability with version < 1.9)\n     *\n     * @private\n     * @param  {jQuery} $obj\n     * @param  {Array} propertyNames - An array of one or more CSS properties.\n     * @return {Object}\n     */\n    var jQueryCSS = function ($obj, propertyNames) {\n      if (agent.jqueryVersion < 1.9) {\n        var result = {};\n        $.each(propertyNames, function (idx, propertyName) {\n          result[propertyName] = $obj.css(propertyName);\n        });\n        return result;\n      }\n      return $obj.css.call($obj, propertyNames);\n    };\n\n    /**\n     * returns style object from node\n     *\n     * @param {jQuery} $node\n     * @return {Object}\n     */\n    this.fromNode = function ($node) {\n      var properties = ['font-family', 'font-size', 'text-align', 'list-style-type', 'line-height'];\n      var styleInfo = jQueryCSS($node, properties) || {};\n      styleInfo['font-size'] = parseInt(styleInfo['font-size'], 10);\n      return styleInfo;\n    };\n\n    /**\n     * paragraph level style\n     *\n     * @param {WrappedRange} rng\n     * @param {Object} styleInfo\n     */\n    this.stylePara = function (rng, styleInfo) {\n      $.each(rng.nodes(dom.isPara, {\n        includeAncestor: true\n      }), function (idx, para) {\n        $(para).css(styleInfo);\n      });\n    };\n\n    /**\n     * insert and returns styleNodes on range.\n     *\n     * @param {WrappedRange} rng\n     * @param {Object} [options] - options for styleNodes\n     * @param {String} [options.nodeName] - default: `SPAN`\n     * @param {Boolean} [options.expandClosestSibling] - default: `false`\n     * @param {Boolean} [options.onlyPartialContains] - default: `false`\n     * @return {Node[]}\n     */\n    this.styleNodes = function (rng, options) {\n      rng = rng.splitText();\n\n      var nodeName = options && options.nodeName || 'SPAN';\n      var expandClosestSibling = !!(options && options.expandClosestSibling);\n      var onlyPartialContains = !!(options && options.onlyPartialContains);\n\n      if (rng.isCollapsed()) {\n        return [rng.insertNode(dom.create(nodeName))];\n      }\n\n      var pred = dom.makePredByNodeName(nodeName);\n      var nodes = rng.nodes(dom.isText, {\n        fullyContains: true\n      }).map(function (text) {\n        return dom.singleChildAncestor(text, pred) || dom.wrap(text, nodeName);\n      });\n\n      if (expandClosestSibling) {\n        if (onlyPartialContains) {\n          var nodesInRange = rng.nodes();\n          // compose with partial contains predication\n          pred = func.and(pred, function (node) {\n            return list.contains(nodesInRange, node);\n          });\n        }\n\n        return nodes.map(function (node) {\n          var siblings = dom.withClosestSiblings(node, pred);\n          var head = list.head(siblings);\n          var tails = list.tail(siblings);\n          $.each(tails, function (idx, elem) {\n            dom.appendChildNodes(head, elem.childNodes);\n            dom.remove(elem);\n          });\n          return list.head(siblings);\n        });\n      } else {\n        return nodes;\n      }\n    };\n\n    /**\n     * get current style on cursor\n     *\n     * @param {WrappedRange} rng\n     * @return {Object} - object contains style properties.\n     */\n    this.current = function (rng) {\n      var $cont = $(dom.isText(rng.sc) ? rng.sc.parentNode : rng.sc);\n      var styleInfo = this.fromNode($cont);\n\n      // document.queryCommandState for toggle state\n      styleInfo['font-bold'] = document.queryCommandState('bold') ? 'bold' : 'normal';\n      styleInfo['font-italic'] = document.queryCommandState('italic') ? 'italic' : 'normal';\n      styleInfo['font-underline'] = document.queryCommandState('underline') ? 'underline' : 'normal';\n      styleInfo['font-strikethrough'] = document.queryCommandState('strikeThrough') ? 'strikethrough' : 'normal';\n      styleInfo['font-superscript'] = document.queryCommandState('superscript') ? 'superscript' : 'normal';\n      styleInfo['font-subscript'] = document.queryCommandState('subscript') ? 'subscript' : 'normal';\n\n      // list-style-type to list-style(unordered, ordered)\n      if (!rng.isOnList()) {\n        styleInfo['list-style'] = 'none';\n      } else {\n        var aOrderedType = ['circle', 'disc', 'disc-leading-zero', 'square'];\n        var isUnordered = $.inArray(styleInfo['list-style-type'], aOrderedType) > -1;\n        styleInfo['list-style'] = isUnordered ? 'unordered' : 'ordered';\n      }\n\n      var para = dom.ancestor(rng.sc, dom.isPara);\n      if (para && para.style['line-height']) {\n        styleInfo['line-height'] = para.style.lineHeight;\n      } else {\n        var lineHeight = parseInt(styleInfo['line-height'], 10) / parseInt(styleInfo['font-size'], 10);\n        styleInfo['line-height'] = lineHeight.toFixed(1);\n      }\n\n      styleInfo.anchor = rng.isOnAnchor() && dom.ancestor(rng.sc, dom.isAnchor);\n      styleInfo.ancestors = dom.listAncestor(rng.sc, dom.isEditable);\n      styleInfo.range = rng;\n\n      return styleInfo;\n    };\n  };\n\n  return Style;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/editing/Table.js",
    "content": "define([\n  'summernote/core/dom', 'summernote/core/range', 'summernote/core/list'\n], function (dom, range, list) {\n  /**\n   * @class editing.Table\n   *\n   * Table\n   *\n   */\n  var Table = function () {\n    /**\n     * handle tab key\n     *\n     * @param {WrappedRange} rng\n     * @param {Boolean} isShift\n     */\n    this.tab = function (rng, isShift) {\n      var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);\n      var table = dom.ancestor(cell, dom.isTable);\n      var cells = dom.listDescendant(table, dom.isCell);\n\n      var nextCell = list[isShift ? 'prev' : 'next'](cells, cell);\n      if (nextCell) {\n        range.create(nextCell, 0).select();\n      }\n    };\n\n    /**\n     * create empty table element\n     *\n     * @param {Number} rowCount\n     * @param {Number} colCount\n     * @return {Node}\n     */\n    this.createTable = function (colCount, rowCount) {\n      var tds = [], tdHTML;\n      for (var idxCol = 0; idxCol < colCount; idxCol++) {\n        tds.push('<td>' + dom.blank + '</td>');\n      }\n      tdHTML = tds.join('');\n\n      var trs = [], trHTML;\n      for (var idxRow = 0; idxRow < rowCount; idxRow++) {\n        trs.push('<tr>' + tdHTML + '</tr>');\n      }\n      trHTML = trs.join('');\n      return $('<table class=\"table table-bordered\">' + trHTML + '</table>')[0];\n    };\n  };\n  return Table;\n});\n\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/editing/Typing.js",
    "content": "define([\n  'summernote/core/dom',\n  'summernote/core/range',\n  'summernote/editing/Bullet'\n], function (dom, range, Bullet) {\n\n  /**\n   * @class editing.Typing\n   *\n   * Typing\n   *\n   */\n  var Typing = function () {\n\n    // a Bullet instance to toggle lists off\n    var bullet = new Bullet();\n\n    /**\n     * insert tab\n     *\n     * @param {jQuery} $editable\n     * @param {WrappedRange} rng\n     * @param {Number} tabsize\n     */\n    this.insertTab = function ($editable, rng, tabsize) {\n      var tab = dom.createText(new Array(tabsize + 1).join(dom.NBSP_CHAR));\n      rng = rng.deleteContents();\n      rng.insertNode(tab, true);\n\n      rng = range.create(tab, tabsize);\n      rng.select();\n    };\n\n    /**\n     * insert paragraph\n     */\n    this.insertParagraph = function () {\n      var rng = range.create();\n\n      // deleteContents on range.\n      rng = rng.deleteContents();\n\n      // Wrap range if it needs to be wrapped by paragraph\n      rng = rng.wrapBodyInlineWithPara();\n\n      // finding paragraph\n      var splitRoot = dom.ancestor(rng.sc, dom.isPara);\n\n      var nextPara;\n      // on paragraph: split paragraph\n      if (splitRoot) {\n        // if it is an empty line with li\n        if (dom.isEmpty(splitRoot) && dom.isLi(splitRoot)) {\n          // disable UL/OL and escape!\n          bullet.toggleList(splitRoot.parentNode.nodeName);\n          return;\n        // if new line has content (not a line break)\n        } else {\n          nextPara = dom.splitTree(splitRoot, rng.getStartPoint());\n\n          var emptyAnchors = dom.listDescendant(splitRoot, dom.isEmptyAnchor);\n          emptyAnchors = emptyAnchors.concat(dom.listDescendant(nextPara, dom.isEmptyAnchor));\n\n          $.each(emptyAnchors, function (idx, anchor) {\n            dom.remove(anchor);\n          });\n        }\n      // no paragraph: insert empty paragraph\n      } else {\n        var next = rng.sc.childNodes[rng.so];\n        nextPara = $(dom.emptyPara)[0];\n        if (next) {\n          rng.sc.insertBefore(nextPara, next);\n        } else {\n          rng.sc.appendChild(nextPara);\n        }\n      }\n\n      range.create(nextPara, 0).normalize().select();\n\n    };\n\n  };\n\n  return Typing;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/intro.js",
    "content": "/**\n * Super simple wysiwyg editor on Bootstrap v@VERSION\n * http://summernote.org/\n *\n * summernote.js\n * Copyright 2013-2015 Alan Hong. and other contributors\n * summernote may be freely distributed under the MIT license./\n *\n * Date: @DATE\n */\n(function (factory) {\n  /* global define */\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define(['jquery'], factory);\n  } else {\n    // Browser globals: jQuery\n    factory(window.jQuery);\n  }\n}(function ($) {\n  'use strict';\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/module/Button.js",
    "content": "define([\n  'summernote/core/list',\n  'summernote/core/agent'\n], function (list, agent) {\n  /**\n   * @class module.Button\n   *\n   * Button\n   */\n  var Button = function () {\n    /**\n     * update button status\n     *\n     * @param {jQuery} $container\n     * @param {Object} styleInfo\n     */\n    this.update = function ($container, styleInfo) {\n      /**\n       * handle dropdown's check mark (for fontname, fontsize, lineHeight).\n       * @param {jQuery} $btn\n       * @param {Number} value\n       */\n      var checkDropdownMenu = function ($btn, value) {\n        $btn.find('.dropdown-menu li a').each(function () {\n          // always compare string to avoid creating another func.\n          var isChecked = ($(this).data('value') + '') === (value + '');\n          this.className = isChecked ? 'checked' : '';\n        });\n      };\n\n      /**\n       * update button state(active or not).\n       *\n       * @private\n       * @param {String} selector\n       * @param {Function} pred\n       */\n      var btnState = function (selector, pred) {\n        var $btn = $container.find(selector);\n        $btn.toggleClass('active', pred());\n      };\n\n      if (styleInfo.image) {\n        var $img = $(styleInfo.image);\n\n        btnState('button[data-event=\"imageShape\"][data-value=\"img-rounded\"]', function () {\n          return $img.hasClass('img-rounded');\n        });\n        btnState('button[data-event=\"imageShape\"][data-value=\"img-circle\"]', function () {\n          return $img.hasClass('img-circle');\n        });\n        btnState('button[data-event=\"imageShape\"][data-value=\"img-thumbnail\"]', function () {\n          return $img.hasClass('img-thumbnail');\n        });\n        btnState('button[data-event=\"imageShape\"]:not([data-value])', function () {\n          return !$img.is('.img-rounded, .img-circle, .img-thumbnail');\n        });\n\n        var imgFloat = $img.css('float');\n        btnState('button[data-event=\"floatMe\"][data-value=\"left\"]', function () {\n          return imgFloat === 'left';\n        });\n        btnState('button[data-event=\"floatMe\"][data-value=\"right\"]', function () {\n          return imgFloat === 'right';\n        });\n        btnState('button[data-event=\"floatMe\"][data-value=\"none\"]', function () {\n          return imgFloat !== 'left' && imgFloat !== 'right';\n        });\n\n        var style = $img.attr('style');\n        btnState('button[data-event=\"resize\"][data-value=\"1\"]', function () {\n          return !!/(^|\\s)(max-)?width\\s*:\\s*100%/.test(style);\n        });\n        btnState('button[data-event=\"resize\"][data-value=\"0.5\"]', function () {\n          return !!/(^|\\s)(max-)?width\\s*:\\s*50%/.test(style);\n        });\n        btnState('button[data-event=\"resize\"][data-value=\"0.25\"]', function () {\n          return !!/(^|\\s)(max-)?width\\s*:\\s*25%/.test(style);\n        });\n        return;\n      }\n\n      // fontname\n      var $fontname = $container.find('.note-fontname');\n      if ($fontname.length) {\n        var selectedFont = styleInfo['font-family'];\n        if (!!selectedFont) {\n\n          var list = selectedFont.split(',');\n          for (var i = 0, len = list.length; i < len; i++) {\n            selectedFont = list[i].replace(/[\\'\\\"]/g, '').replace(/\\s+$/, '').replace(/^\\s+/, '');\n            if (agent.isFontInstalled(selectedFont)) {\n              break;\n            }\n          }\n          \n          $fontname.find('.note-current-fontname').text(selectedFont);\n          checkDropdownMenu($fontname, selectedFont);\n\n        }\n      }\n\n      // fontsize\n      var $fontsize = $container.find('.note-fontsize');\n      $fontsize.find('.note-current-fontsize').text(styleInfo['font-size']);\n      checkDropdownMenu($fontsize, parseFloat(styleInfo['font-size']));\n\n      // lineheight\n      var $lineHeight = $container.find('.note-height');\n      checkDropdownMenu($lineHeight, parseFloat(styleInfo['line-height']));\n\n      btnState('button[data-event=\"bold\"]', function () {\n        return styleInfo['font-bold'] === 'bold';\n      });\n      btnState('button[data-event=\"italic\"]', function () {\n        return styleInfo['font-italic'] === 'italic';\n      });\n      btnState('button[data-event=\"underline\"]', function () {\n        return styleInfo['font-underline'] === 'underline';\n      });\n      btnState('button[data-event=\"strikethrough\"]', function () {\n        return styleInfo['font-strikethrough'] === 'strikethrough';\n      });\n      btnState('button[data-event=\"superscript\"]', function () {\n        return styleInfo['font-superscript'] === 'superscript';\n      });\n      btnState('button[data-event=\"subscript\"]', function () {\n        return styleInfo['font-subscript'] === 'subscript';\n      });\n      btnState('button[data-event=\"justifyLeft\"]', function () {\n        return styleInfo['text-align'] === 'left' || styleInfo['text-align'] === 'start';\n      });\n      btnState('button[data-event=\"justifyCenter\"]', function () {\n        return styleInfo['text-align'] === 'center';\n      });\n      btnState('button[data-event=\"justifyRight\"]', function () {\n        return styleInfo['text-align'] === 'right';\n      });\n      btnState('button[data-event=\"justifyFull\"]', function () {\n        return styleInfo['text-align'] === 'justify';\n      });\n      btnState('button[data-event=\"insertUnorderedList\"]', function () {\n        return styleInfo['list-style'] === 'unordered';\n      });\n      btnState('button[data-event=\"insertOrderedList\"]', function () {\n        return styleInfo['list-style'] === 'ordered';\n      });\n    };\n\n    /**\n     * update recent color\n     *\n     * @param {Node} button\n     * @param {String} eventName\n     * @param {Mixed} value\n     */\n    this.updateRecentColor = function (button, eventName, value) {\n      var $color = $(button).closest('.note-color');\n      var $recentColor = $color.find('.note-recent-color');\n      var colorInfo = JSON.parse($recentColor.attr('data-value'));\n      colorInfo[eventName] = value;\n      $recentColor.attr('data-value', JSON.stringify(colorInfo));\n      var sKey = eventName === 'backColor' ? 'background-color' : 'color';\n      $recentColor.find('i').css(sKey, value);\n    };\n  };\n\n  return Button;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/module/Clipboard.js",
    "content": "define([\n  'summernote/core/list',\n  'summernote/core/dom',\n  'summernote/core/key',\n  'summernote/core/agent'\n], function (list, dom, key, agent) {\n  var Clipboard = function (handler) {\n    var $paste;\n\n    this.attach = function (layoutInfo) {\n      // [workaround] getting image from clipboard\n      //  - IE11 and Firefox: CTRL+v hook\n      //  - Webkit: event.clipboardData\n      if ((agent.isMSIE && agent.browserVersion > 10) || agent.isFF) {\n        $paste = $('<div />').attr('contenteditable', true).css({\n          position : 'absolute',\n          left : -100000,\n          opacity : 0\n        });\n\n        layoutInfo.editable().on('keydown', function (e) {\n          if (e.ctrlKey && e.keyCode === key.code.V) {\n            handler.invoke('saveRange', layoutInfo.editable());\n            $paste.focus();\n\n            setTimeout(function () {\n              pasteByHook(layoutInfo);\n            }, 0);\n          }\n        });\n\n        layoutInfo.editable().before($paste);\n      } else {\n        layoutInfo.editable().on('paste', pasteByEvent);\n      }\n    };\n\n    var pasteByHook = function (layoutInfo) {\n      var $editable = layoutInfo.editable();\n      var node = $paste[0].firstChild;\n\n      if (dom.isImg(node)) {\n        var dataURI = node.src;\n        var decodedData = atob(dataURI.split(',')[1]);\n        var array = new Uint8Array(decodedData.length);\n        for (var i = 0; i < decodedData.length; i++) {\n          array[i] = decodedData.charCodeAt(i);\n        }\n\n        var blob = new Blob([array], { type : 'image/png' });\n        blob.name = 'clipboard.png';\n\n        handler.invoke('restoreRange', $editable);\n        handler.invoke('focus', $editable);\n        handler.insertImages(layoutInfo, [blob]);\n      } else {\n        var pasteContent = $('<div />').html($paste.html()).html();\n        handler.invoke('restoreRange', $editable);\n        handler.invoke('focus', $editable);\n\n        if (pasteContent) {\n          handler.invoke('pasteHTML', $editable, pasteContent);\n        }\n      }\n\n      $paste.empty();\n    };\n\n    /**\n     * paste by clipboard event\n     *\n     * @param {Event} event\n     */\n    var pasteByEvent = function (event) {\n      var clipboardData = event.originalEvent.clipboardData;\n      var layoutInfo = dom.makeLayoutInfo(event.currentTarget || event.target);\n      var $editable = layoutInfo.editable();\n\n      if (clipboardData && clipboardData.items && clipboardData.items.length) {\n        var item = list.head(clipboardData.items);\n        if (item.kind === 'file' && item.type.indexOf('image/') !== -1) {\n          handler.insertImages(layoutInfo, [item.getAsFile()]);\n        }\n        handler.invoke('editor.afterCommand', $editable);\n      }\n    };\n  };\n\n  return Clipboard;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/module/Codeview.js",
    "content": "define([\n  'summernote/core/agent',\n  'summernote/core/dom'\n], function (agent, dom) {\n\n  var CodeMirror;\n  if (agent.hasCodeMirror) {\n    if (agent.isSupportAmd) {\n      require(['CodeMirror'], function (cm) {\n        CodeMirror = cm;\n      });\n    } else {\n      CodeMirror = window.CodeMirror;\n    }\n  }\n\n  /**\n   * @class Codeview\n   */\n  var Codeview = function (handler) {\n\n    this.sync = function (layoutInfo) {\n      var isCodeview = handler.invoke('codeview.isActivated', layoutInfo);\n      if (isCodeview && agent.hasCodeMirror) {\n        layoutInfo.codable().data('cmEditor').save();\n      }\n    };\n\n    /**\n     * @param {Object} layoutInfo\n     * @return {Boolean}\n     */\n    this.isActivated = function (layoutInfo) {\n      var $editor = layoutInfo.editor();\n      return $editor.hasClass('codeview');\n    };\n\n    /**\n     * toggle codeview\n     *\n     * @param {Object} layoutInfo\n     */\n    this.toggle = function (layoutInfo) {\n      if (this.isActivated(layoutInfo)) {\n        this.deactivate(layoutInfo);\n      } else {\n        this.activate(layoutInfo);\n      }\n    };\n\n    /**\n     * activate code view\n     *\n     * @param {Object} layoutInfo\n     */\n    this.activate = function (layoutInfo) {\n      var $editor = layoutInfo.editor(),\n          $toolbar = layoutInfo.toolbar(),\n          $editable = layoutInfo.editable(),\n          $codable = layoutInfo.codable(),\n          $popover = layoutInfo.popover(),\n          $handle = layoutInfo.handle();\n\n      var options = $editor.data('options');\n\n      $codable.val(dom.html($editable, options.prettifyHtml));\n      $codable.height($editable.height());\n\n      handler.invoke('toolbar.updateCodeview', $toolbar, true);\n      handler.invoke('popover.hide', $popover);\n      handler.invoke('handle.hide', $handle);\n\n      $editor.addClass('codeview');\n\n      $codable.focus();\n\n      // activate CodeMirror as codable\n      if (agent.hasCodeMirror) {\n        var cmEditor = CodeMirror.fromTextArea($codable[0], options.codemirror);\n\n        // CodeMirror TernServer\n        if (options.codemirror.tern) {\n          var server = new CodeMirror.TernServer(options.codemirror.tern);\n          cmEditor.ternServer = server;\n          cmEditor.on('cursorActivity', function (cm) {\n            server.updateArgHints(cm);\n          });\n        }\n\n        // CodeMirror hasn't Padding.\n        cmEditor.setSize(null, $editable.outerHeight());\n        $codable.data('cmEditor', cmEditor);\n      }\n    };\n\n    /**\n     * deactivate code view\n     *\n     * @param {Object} layoutInfo\n     */\n    this.deactivate = function (layoutInfo) {\n      var $holder = layoutInfo.holder(),\n          $editor = layoutInfo.editor(),\n          $toolbar = layoutInfo.toolbar(),\n          $editable = layoutInfo.editable(),\n          $codable = layoutInfo.codable();\n\n      var options = $editor.data('options');\n\n      // deactivate CodeMirror as codable\n      if (agent.hasCodeMirror) {\n        var cmEditor = $codable.data('cmEditor');\n        $codable.val(cmEditor.getValue());\n        cmEditor.toTextArea();\n      }\n\n      var value = dom.value($codable, options.prettifyHtml) || dom.emptyPara;\n      var isChange = $editable.html() !== value;\n\n      $editable.html(value);\n      $editable.height(options.height ? $codable.height() : 'auto');\n      $editor.removeClass('codeview');\n\n      if (isChange) {\n        handler.bindCustomEvent(\n          $holder, $editable.data('callbacks'), 'change'\n        )($editable.html(), $editable);\n      }\n\n      $editable.focus();\n\n      handler.invoke('toolbar.updateCodeview', $toolbar, false);\n    };\n  };\n\n  return Codeview;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/module/DragAndDrop.js",
    "content": "define([\n  'summernote/core/dom'\n], function (dom) {\n  var DragAndDrop = function (handler) {\n    var $document = $(document);\n\n    /**\n     * attach Drag and Drop Events\n     *\n     * @param {Object} layoutInfo - layout Informations\n     * @param {Object} options\n     */\n    this.attach = function (layoutInfo, options) {\n      if (options.airMode || options.disableDragAndDrop) {\n        // prevent default drop event\n        $document.on('drop', function (e) {\n          e.preventDefault();\n        });\n      } else {\n        this.attachDragAndDropEvent(layoutInfo, options);\n      }\n    };\n\n    /**\n     * attach Drag and Drop Events\n     *\n     * @param {Object} layoutInfo - layout Informations\n     * @param {Object} options\n     */\n    this.attachDragAndDropEvent = function (layoutInfo, options) {\n      var collection = $(),\n          $editor = layoutInfo.editor(),\n          $dropzone = layoutInfo.dropzone(),\n          $dropzoneMessage = $dropzone.find('.note-dropzone-message');\n\n      // show dropzone on dragenter when dragging a object to document\n      // -but only if the editor is visible, i.e. has a positive width and height\n      $document.on('dragenter', function (e) {\n        var isCodeview = handler.invoke('codeview.isActivated', layoutInfo);\n        var hasEditorSize = $editor.width() > 0 && $editor.height() > 0;\n        if (!isCodeview && !collection.length && hasEditorSize) {\n          $editor.addClass('dragover');\n          $dropzone.width($editor.width());\n          $dropzone.height($editor.height());\n          $dropzoneMessage.text(options.langInfo.image.dragImageHere);\n        }\n        collection = collection.add(e.target);\n      }).on('dragleave', function (e) {\n        collection = collection.not(e.target);\n        if (!collection.length) {\n          $editor.removeClass('dragover');\n        }\n      }).on('drop', function () {\n        collection = $();\n        $editor.removeClass('dragover');\n      });\n\n      // change dropzone's message on hover.\n      $dropzone.on('dragenter', function () {\n        $dropzone.addClass('hover');\n        $dropzoneMessage.text(options.langInfo.image.dropImage);\n      }).on('dragleave', function () {\n        $dropzone.removeClass('hover');\n        $dropzoneMessage.text(options.langInfo.image.dragImageHere);\n      });\n\n      // attach dropImage\n      $dropzone.on('drop', function (event) {\n\n        var dataTransfer = event.originalEvent.dataTransfer;\n        var layoutInfo = dom.makeLayoutInfo(event.currentTarget || event.target);\n\n        if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {\n          event.preventDefault();\n          layoutInfo.editable().focus();\n          handler.insertImages(layoutInfo, dataTransfer.files);\n        } else {\n          var insertNodefunc = function () {\n            layoutInfo.holder().summernote('insertNode', this);\n          };\n\n          for (var i = 0, len = dataTransfer.types.length; i < len; i++) {\n            var type = dataTransfer.types[i];\n            var content = dataTransfer.getData(type);\n\n            if (type.toLowerCase().indexOf('text') > -1) {\n              layoutInfo.holder().summernote('pasteHTML', content);\n            } else {\n              $(content).each(insertNodefunc);\n            }\n          }\n        }\n      }).on('dragover', false); // prevent default dragover event\n    };\n  };\n\n  return DragAndDrop;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/module/Editor.js",
    "content": "define([\n  'summernote/core/agent',\n  'summernote/core/func',\n  'summernote/core/list',\n  'summernote/core/dom',\n  'summernote/core/range',\n  'summernote/core/async',\n  'summernote/editing/Style',\n  'summernote/editing/Typing',\n  'summernote/editing/Table',\n  'summernote/editing/Bullet'\n], function (agent, func, list, dom, range, async,\n             Style, Typing, Table, Bullet) {\n\n  var KEY_BOGUS = 'bogus';\n\n  /**\n   * @class editing.Editor\n   *\n   * Editor\n   *\n   */\n  var Editor = function (handler) {\n\n    var self = this;\n    var style = new Style();\n    var table = new Table();\n    var typing = new Typing();\n    var bullet = new Bullet();\n\n    /**\n     * @method createRange\n     *\n     * create range\n     *\n     * @param {jQuery} $editable\n     * @return {WrappedRange}\n     */\n    this.createRange = function ($editable) {\n      this.focus($editable);\n      return range.create();\n    };\n\n    /**\n     * @method saveRange\n     *\n     * save current range\n     *\n     * @param {jQuery} $editable\n     * @param {Boolean} [thenCollapse=false]\n     */\n    this.saveRange = function ($editable, thenCollapse) {\n      this.focus($editable);\n      $editable.data('range', range.create());\n      if (thenCollapse) {\n        range.create().collapse().select();\n      }\n    };\n\n    /**\n     * @method saveRange\n     *\n     * save current node list to $editable.data('childNodes')\n     *\n     * @param {jQuery} $editable\n     */\n    this.saveNode = function ($editable) {\n      // copy child node reference\n      var copy = [];\n      for (var key  = 0, len = $editable[0].childNodes.length; key < len; key++) {\n        copy.push($editable[0].childNodes[key]);\n      }\n      $editable.data('childNodes', copy);\n    };\n\n    /**\n     * @method restoreRange\n     *\n     * restore lately range\n     *\n     * @param {jQuery} $editable\n     */\n    this.restoreRange = function ($editable) {\n      var rng = $editable.data('range');\n      if (rng) {\n        rng.select();\n        this.focus($editable);\n      }\n    };\n\n    /**\n     * @method restoreNode\n     *\n     * restore lately node list\n     *\n     * @param {jQuery} $editable\n     */\n    this.restoreNode = function ($editable) {\n      $editable.html('');\n      var child = $editable.data('childNodes');\n      for (var index = 0, len = child.length; index < len; index++) {\n        $editable[0].appendChild(child[index]);\n      }\n    };\n\n    /**\n     * @method currentStyle\n     *\n     * current style\n     *\n     * @param {Node} target\n     * @return {Object|Boolean} unfocus\n     */\n    this.currentStyle = function (target) {\n      var rng = range.create();\n      var styleInfo =  rng && rng.isOnEditable() ? style.current(rng.normalize()) : {};\n      if (dom.isImg(target)) {\n        styleInfo.image = target;\n      }\n      return styleInfo;\n    };\n\n    /**\n     * style from node\n     *\n     * @param {jQuery} $node\n     * @return {Object}\n     */\n    this.styleFromNode = function ($node) {\n      return style.fromNode($node);\n    };\n\n    var triggerOnBeforeChange = function ($editable) {\n      var $holder = dom.makeLayoutInfo($editable).holder();\n      handler.bindCustomEvent(\n        $holder, $editable.data('callbacks'), 'before.command'\n      )($editable.html(), $editable);\n    };\n\n    var triggerOnChange = function ($editable) {\n      var $holder = dom.makeLayoutInfo($editable).holder();\n      handler.bindCustomEvent(\n        $holder, $editable.data('callbacks'), 'change'\n      )($editable.html(), $editable);\n    };\n\n    /**\n     * @method undo\n     * undo\n     * @param {jQuery} $editable\n     */\n    this.undo = function ($editable) {\n      triggerOnBeforeChange($editable);\n      $editable.data('NoteHistory').undo();\n      triggerOnChange($editable);\n    };\n\n    /**\n     * @method redo\n     * redo\n     * @param {jQuery} $editable\n     */\n    this.redo = function ($editable) {\n      triggerOnBeforeChange($editable);\n      $editable.data('NoteHistory').redo();\n      triggerOnChange($editable);\n    };\n\n    /**\n     * @method beforeCommand\n     * before command\n     * @param {jQuery} $editable\n     */\n    var beforeCommand = this.beforeCommand = function ($editable) {\n      triggerOnBeforeChange($editable);\n      // keep focus on editable before command execution\n      self.focus($editable);\n    };\n\n    /**\n     * @method afterCommand\n     * after command\n     * @param {jQuery} $editable\n     * @param {Boolean} isPreventTrigger\n     */\n    var afterCommand = this.afterCommand = function ($editable, isPreventTrigger) {\n      $editable.data('NoteHistory').recordUndo();\n      if (!isPreventTrigger) {\n        triggerOnChange($editable);\n      }\n    };\n\n    /**\n     * @method bold\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method italic\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method underline\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method strikethrough\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method formatBlock\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method superscript\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method subscript\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method justifyLeft\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method justifyCenter\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method justifyRight\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method justifyFull\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method formatBlock\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method removeFormat\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method backColor\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method foreColor\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method insertHorizontalRule\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /**\n     * @method fontName\n     *\n     * change font name\n     *\n     * @param {jQuery} $editable\n     * @param {Mixed} value\n     */\n\n    /* jshint ignore:start */\n    // native commands(with execCommand), generate function for execCommand\n    var commands = ['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript',\n                    'justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull',\n                    'formatBlock', 'removeFormat',\n                    'backColor', 'foreColor', 'fontName'];\n\n    for (var idx = 0, len = commands.length; idx < len; idx ++) {\n      this[commands[idx]] = (function (sCmd) {\n        return function ($editable, value) {\n          beforeCommand($editable);\n\n          document.execCommand(sCmd, false, value);\n\n          afterCommand($editable, true);\n        };\n      })(commands[idx]);\n    }\n    /* jshint ignore:end */\n\n    /**\n     * @method tab\n     *\n     * handle tab key\n     *\n     * @param {jQuery} $editable\n     * @param {Object} options\n     */\n    this.tab = function ($editable, options) {\n      var rng = this.createRange($editable);\n      if (rng.isCollapsed() && rng.isOnCell()) {\n        table.tab(rng);\n      } else {\n        beforeCommand($editable);\n        typing.insertTab($editable, rng, options.tabsize);\n        afterCommand($editable);\n      }\n    };\n\n    /**\n     * @method untab\n     *\n     * handle shift+tab key\n     *\n     */\n    this.untab = function ($editable) {\n      var rng = this.createRange($editable);\n      if (rng.isCollapsed() && rng.isOnCell()) {\n        table.tab(rng, true);\n      }\n    };\n\n    /**\n     * @method insertParagraph\n     *\n     * insert paragraph\n     *\n     * @param {Node} $editable\n     */\n    this.insertParagraph = function ($editable) {\n      beforeCommand($editable);\n      typing.insertParagraph($editable);\n      afterCommand($editable);\n    };\n\n    /**\n     * @method insertOrderedList\n     *\n     * @param {jQuery} $editable\n     */\n    this.insertOrderedList = function ($editable) {\n      beforeCommand($editable);\n      bullet.insertOrderedList($editable);\n      afterCommand($editable);\n    };\n\n    /**\n     * @param {jQuery} $editable\n     */\n    this.insertUnorderedList = function ($editable) {\n      beforeCommand($editable);\n      bullet.insertUnorderedList($editable);\n      afterCommand($editable);\n    };\n\n    /**\n     * @param {jQuery} $editable\n     */\n    this.indent = function ($editable) {\n      beforeCommand($editable);\n      bullet.indent($editable);\n      afterCommand($editable);\n    };\n\n    /**\n     * @param {jQuery} $editable\n     */\n    this.outdent = function ($editable) {\n      beforeCommand($editable);\n      bullet.outdent($editable);\n      afterCommand($editable);\n    };\n\n    /**\n     * insert image\n     *\n     * @param {jQuery} $editable\n     * @param {String} sUrl\n     */\n    this.insertImage = function ($editable, sUrl, filename) {\n      async.createImage(sUrl, filename).then(function ($image) {\n        beforeCommand($editable);\n        $image.css({\n          display: '',\n          width: Math.min($editable.width(), $image.width())\n        });\n        range.create().insertNode($image[0]);\n        range.createFromNodeAfter($image[0]).select();\n        afterCommand($editable);\n      }).fail(function () {\n        var $holder = dom.makeLayoutInfo($editable).holder();\n        handler.bindCustomEvent(\n          $holder, $editable.data('callbacks'), 'image.upload.error'\n        )();\n      });\n    };\n\n    /**\n     * @method insertNode\n     * insert node\n     * @param {Node} $editable\n     * @param {Node} node\n     */\n    this.insertNode = function ($editable, node) {\n      beforeCommand($editable);\n      range.create().insertNode(node);\n      range.createFromNodeAfter(node).select();\n      afterCommand($editable);\n    };\n\n    /**\n     * insert text\n     * @param {Node} $editable\n     * @param {String} text\n     */\n    this.insertText = function ($editable, text) {\n      beforeCommand($editable);\n      var textNode = range.create().insertNode(dom.createText(text));\n      range.create(textNode, dom.nodeLength(textNode)).select();\n      afterCommand($editable);\n    };\n\n    /**\n     * paste HTML\n     * @param {Node} $editable\n     * @param {String} markup\n     */\n    this.pasteHTML = function ($editable, markup) {\n      beforeCommand($editable);\n      var contents = range.create().pasteHTML(markup);\n      range.createFromNodeAfter(list.last(contents)).select();\n      afterCommand($editable);\n    };\n\n    /**\n     * formatBlock\n     *\n     * @param {jQuery} $editable\n     * @param {String} tagName\n     */\n    this.formatBlock = function ($editable, tagName) {\n      beforeCommand($editable);\n      // [workaround] for MSIE, IE need `<`\n      tagName = agent.isMSIE ? '<' + tagName + '>' : tagName;\n      document.execCommand('FormatBlock', false, tagName);\n      afterCommand($editable);\n    };\n\n    this.formatPara = function ($editable) {\n      beforeCommand($editable);\n      this.formatBlock($editable, 'P');\n      afterCommand($editable);\n    };\n\n    /* jshint ignore:start */\n    for (var idx = 1; idx <= 6; idx ++) {\n      this['formatH' + idx] = function (idx) {\n        return function ($editable) {\n          this.formatBlock($editable, 'H' + idx);\n        };\n      }(idx);\n    };\n    /* jshint ignore:end */\n\n    /**\n     * fontSize\n     *\n     * @param {jQuery} $editable\n     * @param {String} value - px\n     */\n    this.fontSize = function ($editable, value) {\n      var rng = range.create();\n\n      if (rng.isCollapsed()) {\n        var spans = style.styleNodes(rng);\n        var firstSpan = list.head(spans);\n\n        $(spans).css({\n          'font-size': value + 'px'\n        });\n\n        // [workaround] added styled bogus span for style\n        //  - also bogus character needed for cursor position\n        if (firstSpan && !dom.nodeLength(firstSpan)) {\n          firstSpan.innerHTML = dom.ZERO_WIDTH_NBSP_CHAR;\n          range.createFromNodeAfter(firstSpan.firstChild).select();\n          $editable.data(KEY_BOGUS, firstSpan);\n        }\n      } else {\n        beforeCommand($editable);\n        $(style.styleNodes(rng)).css({\n          'font-size': value + 'px'\n        });\n        afterCommand($editable);\n      }\n    };\n\n    /**\n     * insert horizontal rule\n     * @param {jQuery} $editable\n     */\n    this.insertHorizontalRule = function ($editable) {\n      beforeCommand($editable);\n\n      var rng = range.create();\n      var hrNode = rng.insertNode($('<HR/>')[0]);\n      if (hrNode.nextSibling) {\n        range.create(hrNode.nextSibling, 0).normalize().select();\n      }\n\n      afterCommand($editable);\n    };\n\n    /**\n     * remove bogus node and character\n     */\n    this.removeBogus = function ($editable) {\n      var bogusNode = $editable.data(KEY_BOGUS);\n      if (!bogusNode) {\n        return;\n      }\n\n      var textNode = list.find(list.from(bogusNode.childNodes), dom.isText);\n\n      var bogusCharIdx = textNode.nodeValue.indexOf(dom.ZERO_WIDTH_NBSP_CHAR);\n      if (bogusCharIdx !== -1) {\n        textNode.deleteData(bogusCharIdx, 1);\n      }\n\n      if (dom.isEmpty(bogusNode)) {\n        dom.remove(bogusNode);\n      }\n\n      $editable.removeData(KEY_BOGUS);\n    };\n\n    /**\n     * lineHeight\n     * @param {jQuery} $editable\n     * @param {String} value\n     */\n    this.lineHeight = function ($editable, value) {\n      beforeCommand($editable);\n      style.stylePara(range.create(), {\n        lineHeight: value\n      });\n      afterCommand($editable);\n    };\n\n    /**\n     * unlink\n     *\n     * @type command\n     *\n     * @param {jQuery} $editable\n     */\n    this.unlink = function ($editable) {\n      var rng = this.createRange($editable);\n      if (rng.isOnAnchor()) {\n        var anchor = dom.ancestor(rng.sc, dom.isAnchor);\n        rng = range.createFromNode(anchor);\n        rng.select();\n\n        beforeCommand($editable);\n        document.execCommand('unlink');\n        afterCommand($editable);\n      }\n    };\n\n    /**\n     * create link (command)\n     *\n     * @param {jQuery} $editable\n     * @param {Object} linkInfo\n     * @param {Object} options\n     */\n    this.createLink = function ($editable, linkInfo, options) {\n      var linkUrl = linkInfo.url;\n      var linkText = linkInfo.text;\n      var isNewWindow = linkInfo.isNewWindow;\n      var rng = linkInfo.range || this.createRange($editable);\n      var isTextChanged = rng.toString() !== linkText;\n\n      options = options || dom.makeLayoutInfo($editable).editor().data('options');\n\n      beforeCommand($editable);\n\n      if (options.onCreateLink) {\n        linkUrl = options.onCreateLink(linkUrl);\n      }\n\n      var anchors = [];\n      if (isTextChanged) {\n        // Create a new link when text changed.\n        var anchor = rng.insertNode($('<A>' + linkText + '</A>')[0]);\n        anchors.push(anchor);\n      } else {\n        anchors = style.styleNodes(rng, {\n          nodeName: 'A',\n          expandClosestSibling: true,\n          onlyPartialContains: true\n        });\n      }\n\n      $.each(anchors, function (idx, anchor) {\n        $(anchor).attr('href', linkUrl);\n        if (isNewWindow) {\n          $(anchor).attr('target', '_blank');\n        } else {\n          $(anchor).removeAttr('target');\n        }\n      });\n\n      var startRange = range.createFromNodeBefore(list.head(anchors));\n      var startPoint = startRange.getStartPoint();\n      var endRange = range.createFromNodeAfter(list.last(anchors));\n      var endPoint = endRange.getEndPoint();\n\n      range.create(\n        startPoint.node,\n        startPoint.offset,\n        endPoint.node,\n        endPoint.offset\n      ).select();\n\n      afterCommand($editable);\n    };\n\n    /**\n     * returns link info\n     *\n     * @return {Object}\n     * @return {WrappedRange} return.range\n     * @return {String} return.text\n     * @return {Boolean} [return.isNewWindow=true]\n     * @return {String} [return.url=\"\"]\n     */\n    this.getLinkInfo = function ($editable) {\n      this.focus($editable);\n\n      var rng = range.create().expand(dom.isAnchor);\n\n      // Get the first anchor on range(for edit).\n      var $anchor = $(list.head(rng.nodes(dom.isAnchor)));\n\n      return {\n        range: rng,\n        text: rng.toString(),\n        isNewWindow: $anchor.length ? $anchor.attr('target') === '_blank' : false,\n        url: $anchor.length ? $anchor.attr('href') : ''\n      };\n    };\n\n    /**\n     * setting color\n     *\n     * @param {Node} $editable\n     * @param {Object} sObjColor  color code\n     * @param {String} sObjColor.foreColor foreground color\n     * @param {String} sObjColor.backColor background color\n     */\n    this.color = function ($editable, sObjColor) {\n      var oColor = JSON.parse(sObjColor);\n      var foreColor = oColor.foreColor, backColor = oColor.backColor;\n\n      beforeCommand($editable);\n\n      if (foreColor) { document.execCommand('foreColor', false, foreColor); }\n      if (backColor) { document.execCommand('backColor', false, backColor); }\n\n      afterCommand($editable);\n    };\n\n    /**\n     * insert Table\n     *\n     * @param {Node} $editable\n     * @param {String} sDim dimension of table (ex : \"5x5\")\n     */\n    this.insertTable = function ($editable, sDim) {\n      var dimension = sDim.split('x');\n      beforeCommand($editable);\n\n      var rng = range.create().deleteContents();\n      rng.insertNode(table.createTable(dimension[0], dimension[1]));\n      afterCommand($editable);\n    };\n\n    /**\n     * float me\n     *\n     * @param {jQuery} $editable\n     * @param {String} value\n     * @param {jQuery} $target\n     */\n    this.floatMe = function ($editable, value, $target) {\n      beforeCommand($editable);\n      // bootstrap\n      $target.removeClass('pull-left pull-right');\n      if (value && value !== 'none') {\n        $target.addClass('pull-' + value);\n      }\n\n      // fallback for non-bootstrap\n      $target.css('float', value);\n      afterCommand($editable);\n    };\n\n    /**\n     * change image shape\n     *\n     * @param {jQuery} $editable\n     * @param {String} value css class\n     * @param {Node} $target\n     */\n    this.imageShape = function ($editable, value, $target) {\n      beforeCommand($editable);\n\n      $target.removeClass('img-rounded img-circle img-thumbnail');\n\n      if (value) {\n        $target.addClass(value);\n      }\n\n      afterCommand($editable);\n    };\n\n    /**\n     * resize overlay element\n     * @param {jQuery} $editable\n     * @param {String} value\n     * @param {jQuery} $target - target element\n     */\n    this.resize = function ($editable, value, $target) {\n      beforeCommand($editable);\n\n      $target.css({\n        width: value * 100 + '%',\n        height: ''\n      });\n\n      afterCommand($editable);\n    };\n\n    /**\n     * @param {Position} pos\n     * @param {jQuery} $target - target element\n     * @param {Boolean} [bKeepRatio] - keep ratio\n     */\n    this.resizeTo = function (pos, $target, bKeepRatio) {\n      var imageSize;\n      if (bKeepRatio) {\n        var newRatio = pos.y / pos.x;\n        var ratio = $target.data('ratio');\n        imageSize = {\n          width: ratio > newRatio ? pos.x : pos.y / ratio,\n          height: ratio > newRatio ? pos.x * ratio : pos.y\n        };\n      } else {\n        imageSize = {\n          width: pos.x,\n          height: pos.y\n        };\n      }\n\n      $target.css(imageSize);\n    };\n\n    /**\n     * remove media object\n     *\n     * @param {jQuery} $editable\n     * @param {String} value - dummy argument (for keep interface)\n     * @param {jQuery} $target - target element\n     */\n    this.removeMedia = function ($editable, value, $target) {\n      beforeCommand($editable);\n      $target.detach();\n\n      handler.bindCustomEvent(\n        $(), $editable.data('callbacks'), 'media.delete'\n      )($target, $editable);\n\n      afterCommand($editable);\n    };\n\n    /**\n     * set focus\n     *\n     * @param $editable\n     */\n    this.focus = function ($editable) {\n      $editable.focus();\n\n      // [workaround] for firefox bug http://goo.gl/lVfAaI\n      if (agent.isFF && !range.create().isOnEditable()) {\n        range.createFromNode($editable[0])\n             .normalize()\n             .collapse()\n             .select();\n      }\n    };\n\n    /**\n     * returns whether contents is empty or not.\n     *\n     * @param {jQuery} $editable\n     * @return {Boolean}\n     */\n    this.isEmpty = function ($editable) {\n      return dom.isEmpty($editable[0]) || dom.emptyPara === $editable.html();\n    };\n  };\n\n  return Editor;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/module/Fullscreen.js",
    "content": "define(function () {\n  var Fullscreen = function (handler) {\n    var $window = $(window);\n    var $scrollbar = $('html, body');\n\n    /**\n     * toggle fullscreen\n     *\n     * @param {Object} layoutInfo\n     */\n    this.toggle = function (layoutInfo) {\n\n      var $editor = layoutInfo.editor(),\n          $toolbar = layoutInfo.toolbar(),\n          $editable = layoutInfo.editable(),\n          $codable = layoutInfo.codable();\n\n      var resize = function (size) {\n        $editable.css('height', size.h);\n        $codable.css('height', size.h);\n        if ($codable.data('cmeditor')) {\n          $codable.data('cmeditor').setsize(null, size.h);\n        }\n      };\n\n      $editor.toggleClass('fullscreen');\n      var isFullscreen = $editor.hasClass('fullscreen');\n      if (isFullscreen) {\n        $editable.data('orgheight', $editable.css('height'));\n\n        $window.on('resize', function () {\n          resize({\n            h: $window.height() - $toolbar.outerHeight()\n          });\n        }).trigger('resize');\n\n        $scrollbar.css('overflow', 'hidden');\n      } else {\n        $window.off('resize');\n        resize({\n          h: $editable.data('orgheight')\n        });\n        $scrollbar.css('overflow', 'visible');\n      }\n\n      handler.invoke('toolbar.updateFullscreen', $toolbar, isFullscreen);\n    };\n  };\n\n  return Fullscreen;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/module/Handle.js",
    "content": "define([\n  'summernote/core/dom'\n], function (dom) {\n  /**\n   * @class module.Handle\n   *\n   * Handle\n   */\n  var Handle = function (handler) {\n    var $document = $(document);\n\n    /**\n     * `mousedown` event handler on $handle\n     *  - controlSizing: resize image\n     *\n     * @param {MouseEvent} event\n     */\n    var hHandleMousedown = function (event) {\n      if (dom.isControlSizing(event.target)) {\n        event.preventDefault();\n        event.stopPropagation();\n\n        var layoutInfo = dom.makeLayoutInfo(event.target),\n            $handle = layoutInfo.handle(),\n            $popover = layoutInfo.popover(),\n            $editable = layoutInfo.editable(),\n            $editor = layoutInfo.editor();\n\n        var target = $handle.find('.note-control-selection').data('target'),\n            $target = $(target), posStart = $target.offset(),\n            scrollTop = $document.scrollTop();\n\n        var isAirMode = $editor.data('options').airMode;\n\n        $document.on('mousemove', function (event) {\n          handler.invoke('editor.resizeTo', {\n            x: event.clientX - posStart.left,\n            y: event.clientY - (posStart.top - scrollTop)\n          }, $target, !event.shiftKey);\n\n          handler.invoke('handle.update', $handle, {image: target}, isAirMode);\n          handler.invoke('popover.update', $popover, {image: target}, isAirMode);\n        }).one('mouseup', function () {\n          $document.off('mousemove');\n          handler.invoke('editor.afterCommand', $editable);\n        });\n\n        if (!$target.data('ratio')) { // original ratio.\n          $target.data('ratio', $target.height() / $target.width());\n        }\n      }\n    };\n\n    this.attach = function (layoutInfo) {\n      layoutInfo.handle().on('mousedown', hHandleMousedown);\n    };\n\n    /**\n     * update handle\n     * @param {jQuery} $handle\n     * @param {Object} styleInfo\n     * @param {Boolean} isAirMode\n     */\n    this.update = function ($handle, styleInfo, isAirMode) {\n      var $selection = $handle.find('.note-control-selection');\n      if (styleInfo.image) {\n        var $image = $(styleInfo.image);\n        var pos = isAirMode ? $image.offset() : $image.position();\n\n        // include margin\n        var imageSize = {\n          w: $image.outerWidth(true),\n          h: $image.outerHeight(true)\n        };\n\n        $selection.css({\n          display: 'block',\n          left: pos.left,\n          top: pos.top,\n          width: imageSize.w,\n          height: imageSize.h\n        }).data('target', styleInfo.image); // save current image element.\n        var sizingText = imageSize.w + 'x' + imageSize.h;\n        $selection.find('.note-control-selection-info').text(sizingText);\n      } else {\n        $selection.hide();\n      }\n    };\n\n    /**\n     * hide\n     *\n     * @param {jQuery} $handle\n     */\n    this.hide = function ($handle) {\n      $handle.children().hide();\n    };\n  };\n\n  return Handle;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/module/HelpDialog.js",
    "content": "define(function () {\n  var HelpDialog = function (handler) {\n    /**\n     * show help dialog\n     *\n     * @param {jQuery} $editable\n     * @param {jQuery} $dialog\n     * @return {Promise}\n     */\n    this.showHelpDialog = function ($editable, $dialog) {\n      return $.Deferred(function (deferred) {\n        var $helpDialog = $dialog.find('.note-help-dialog');\n\n        $helpDialog.one('hidden.bs.modal', function () {\n          deferred.resolve();\n        }).modal('show');\n      }).promise();\n    };\n\n    /**\n     * @param {Object} layoutInfo\n     */\n    this.show = function (layoutInfo) {\n      var $dialog = layoutInfo.dialog(),\n          $editable = layoutInfo.editable();\n\n      handler.invoke('editor.saveRange', $editable, true);\n      this.showHelpDialog($editable, $dialog).then(function () {\n        handler.invoke('editor.restoreRange', $editable);\n      });\n    };\n  };\n\n  return HelpDialog;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/module/ImageDialog.js",
    "content": "define([\n  'summernote/core/key'\n], function (key) {\n  var ImageDialog = function (handler) {\n    /**\n     * toggle button status\n     *\n     * @private\n     * @param {jQuery} $btn\n     * @param {Boolean} isEnable\n     */\n    var toggleBtn = function ($btn, isEnable) {\n      $btn.toggleClass('disabled', !isEnable);\n      $btn.attr('disabled', !isEnable);\n    };\n\n    /**\n     * bind enter key\n     *\n     * @private\n     * @param {jQuery} $input\n     * @param {jQuery} $btn\n     */\n    var bindEnterKey = function ($input, $btn) {\n      $input.on('keypress', function (event) {\n        if (event.keyCode === key.code.ENTER) {\n          $btn.trigger('click');\n        }\n      });\n    };\n\n    this.show = function (layoutInfo) {\n      var $dialog = layoutInfo.dialog(),\n          $editable = layoutInfo.editable();\n\n      handler.invoke('editor.saveRange', $editable);\n      this.showImageDialog($editable, $dialog).then(function (data) {\n        handler.invoke('editor.restoreRange', $editable);\n\n        if (typeof data === 'string') {\n          // image url\n          handler.invoke('editor.insertImage', $editable, data);\n        } else {\n          // array of files\n          handler.insertImages(layoutInfo, data);\n        }\n      }).fail(function () {\n        handler.invoke('editor.restoreRange', $editable);\n      });\n    };\n\n    /**\n     * show image dialog\n     *\n     * @param {jQuery} $editable\n     * @param {jQuery} $dialog\n     * @return {Promise}\n     */\n    this.showImageDialog = function ($editable, $dialog) {\n      return $.Deferred(function (deferred) {\n        var $imageDialog = $dialog.find('.note-image-dialog');\n\n        var $imageInput = $dialog.find('.note-image-input'),\n            $imageUrl = $dialog.find('.note-image-url'),\n            $imageBtn = $dialog.find('.note-image-btn');\n\n        $imageDialog.one('shown.bs.modal', function () {\n          // Cloning imageInput to clear element.\n          $imageInput.replaceWith($imageInput.clone()\n            .on('change', function () {\n              deferred.resolve(this.files || this.value);\n              $imageDialog.modal('hide');\n            })\n            .val('')\n          );\n\n          $imageBtn.click(function (event) {\n            event.preventDefault();\n\n            deferred.resolve($imageUrl.val());\n            $imageDialog.modal('hide');\n          });\n\n          $imageUrl.on('keyup paste', function (event) {\n            var url;\n            \n            if (event.type === 'paste') {\n              url = event.originalEvent.clipboardData.getData('text');\n            } else {\n              url = $imageUrl.val();\n            }\n            \n            toggleBtn($imageBtn, url);\n          }).val('').trigger('focus');\n          bindEnterKey($imageUrl, $imageBtn);\n        }).one('hidden.bs.modal', function () {\n          $imageInput.off('change');\n          $imageUrl.off('keyup paste keypress');\n          $imageBtn.off('click');\n\n          if (deferred.state() === 'pending') {\n            deferred.reject();\n          }\n        }).modal('show');\n      });\n    };\n  };\n\n  return ImageDialog;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/module/LinkDialog.js",
    "content": "define([\n  'summernote/core/key'\n], function (key) {\n  var LinkDialog = function (handler) {\n\n    /**\n     * toggle button status\n     *\n     * @private\n     * @param {jQuery} $btn\n     * @param {Boolean} isEnable\n     */\n    var toggleBtn = function ($btn, isEnable) {\n      $btn.toggleClass('disabled', !isEnable);\n      $btn.attr('disabled', !isEnable);\n    };\n\n    /**\n     * bind enter key\n     *\n     * @private\n     * @param {jQuery} $input\n     * @param {jQuery} $btn\n     */\n    var bindEnterKey = function ($input, $btn) {\n      $input.on('keypress', function (event) {\n        if (event.keyCode === key.code.ENTER) {\n          $btn.trigger('click');\n        }\n      });\n    };\n\n    /**\n     * Show link dialog and set event handlers on dialog controls.\n     *\n     * @param {jQuery} $editable\n     * @param {jQuery} $dialog\n     * @param {Object} linkInfo\n     * @return {Promise}\n     */\n    this.showLinkDialog = function ($editable, $dialog, linkInfo) {\n      return $.Deferred(function (deferred) {\n        var $linkDialog = $dialog.find('.note-link-dialog');\n\n        var $linkText = $linkDialog.find('.note-link-text'),\n        $linkUrl = $linkDialog.find('.note-link-url'),\n        $linkBtn = $linkDialog.find('.note-link-btn'),\n        $openInNewWindow = $linkDialog.find('input[type=checkbox]');\n\n        $linkDialog.one('shown.bs.modal', function () {\n          $linkText.val(linkInfo.text);\n\n          $linkText.on('input', function () {\n            toggleBtn($linkBtn, $linkText.val() && $linkUrl.val());\n            // if linktext was modified by keyup,\n            // stop cloning text from linkUrl\n            linkInfo.text = $linkText.val();\n          });\n\n          // if no url was given, copy text to url\n          if (!linkInfo.url) {\n            linkInfo.url = linkInfo.text || 'http://';\n            toggleBtn($linkBtn, linkInfo.text);\n          }\n\n          $linkUrl.on('input', function () {\n            toggleBtn($linkBtn, $linkText.val() && $linkUrl.val());\n            // display same link on `Text to display` input\n            // when create a new link\n            if (!linkInfo.text) {\n              $linkText.val($linkUrl.val());\n            }\n          }).val(linkInfo.url).trigger('focus').trigger('select');\n\n          bindEnterKey($linkUrl, $linkBtn);\n          bindEnterKey($linkText, $linkBtn);\n\n          $openInNewWindow.prop('checked', linkInfo.isNewWindow);\n\n          $linkBtn.one('click', function (event) {\n            event.preventDefault();\n\n            deferred.resolve({\n              range: linkInfo.range,\n              url: $linkUrl.val(),\n              text: $linkText.val(),\n              isNewWindow: $openInNewWindow.is(':checked')\n            });\n            $linkDialog.modal('hide');\n          });\n        }).one('hidden.bs.modal', function () {\n          // detach events\n          $linkText.off('input keypress');\n          $linkUrl.off('input keypress');\n          $linkBtn.off('click');\n\n          if (deferred.state() === 'pending') {\n            deferred.reject();\n          }\n        }).modal('show');\n      }).promise();\n    };\n\n    /**\n     * @param {Object} layoutInfo\n     */\n    this.show = function (layoutInfo) {\n      var $editor = layoutInfo.editor(),\n          $dialog = layoutInfo.dialog(),\n          $editable = layoutInfo.editable(),\n          $popover = layoutInfo.popover(),\n          linkInfo = handler.invoke('editor.getLinkInfo', $editable);\n\n      var options = $editor.data('options');\n\n      handler.invoke('editor.saveRange', $editable);\n      this.showLinkDialog($editable, $dialog, linkInfo).then(function (linkInfo) {\n        handler.invoke('editor.restoreRange', $editable);\n        handler.invoke('editor.createLink', $editable, linkInfo, options);\n        // hide popover after creating link\n        handler.invoke('popover.hide', $popover);\n      }).fail(function () {\n        handler.invoke('editor.restoreRange', $editable);\n      });\n    };\n  };\n\n  return LinkDialog;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/module/Popover.js",
    "content": "define([\n  'summernote/core/func',\n  'summernote/core/list',\n  'summernote/module/Button'\n], function (func, list, Button) {\n  /**\n   * @class module.Popover\n   *\n   * Popover (http://getbootstrap.com/javascript/#popovers)\n   *\n   */\n  var Popover = function () {\n    var button = new Button();\n\n    /**\n     * returns position from placeholder\n     *\n     * @private\n     * @param {Node} placeholder\n     * @param {Object} options\n     * @param {Boolean} options.isAirMode\n     * @return {Position}\n     */\n    var posFromPlaceholder = function (placeholder, options) {\n      var isAirMode = options && options.isAirMode;\n      var isLeftTop = options && options.isLeftTop;\n\n      var $placeholder = $(placeholder);\n      var pos = isAirMode ? $placeholder.offset() : $placeholder.position();\n      var height = isLeftTop ? 0 : $placeholder.outerHeight(true); // include margin\n\n      // popover below placeholder.\n      return {\n        left: pos.left,\n        top: pos.top + height\n      };\n    };\n\n    /**\n     * show popover\n     *\n     * @private\n     * @param {jQuery} popover\n     * @param {Position} pos\n     */\n    var showPopover = function ($popover, pos) {\n      $popover.css({\n        display: 'block',\n        left: pos.left,\n        top: pos.top\n      });\n    };\n\n    var PX_POPOVER_ARROW_OFFSET_X = 20;\n\n    /**\n     * update current state\n     * @param {jQuery} $popover - popover container\n     * @param {Object} styleInfo - style object\n     * @param {Boolean} isAirMode\n     */\n    this.update = function ($popover, styleInfo, isAirMode) {\n      button.update($popover, styleInfo);\n\n      var $linkPopover = $popover.find('.note-link-popover');\n      if (styleInfo.anchor) {\n        var $anchor = $linkPopover.find('a');\n        var href = $(styleInfo.anchor).attr('href');\n        var target = $(styleInfo.anchor).attr('target');\n        $anchor.attr('href', href).html(href);\n        if (!target) {\n          $anchor.removeAttr('target');\n        } else {\n          $anchor.attr('target', '_blank');\n        }\n        showPopover($linkPopover, posFromPlaceholder(styleInfo.anchor, {\n          isAirMode: isAirMode\n        }));\n      } else {\n        $linkPopover.hide();\n      }\n\n      var $imagePopover = $popover.find('.note-image-popover');\n      if (styleInfo.image) {\n        showPopover($imagePopover, posFromPlaceholder(styleInfo.image, {\n          isAirMode: isAirMode,\n          isLeftTop: true\n        }));\n      } else {\n        $imagePopover.hide();\n      }\n\n      var $airPopover = $popover.find('.note-air-popover');\n      if (isAirMode && styleInfo.range && !styleInfo.range.isCollapsed()) {\n        var rect = list.last(styleInfo.range.getClientRects());\n        if (rect) {\n          var bnd = func.rect2bnd(rect);\n          showPopover($airPopover, {\n            left: Math.max(bnd.left + bnd.width / 2 - PX_POPOVER_ARROW_OFFSET_X, 0),\n            top: bnd.top + bnd.height\n          });\n        }\n      } else {\n        $airPopover.hide();\n      }\n    };\n\n    /**\n     * @param {Node} button\n     * @param {String} eventName\n     * @param {String} value\n     */\n    this.updateRecentColor = function (button, eventName, value) {\n      button.updateRecentColor(button, eventName, value);\n    };\n\n    /**\n     * hide all popovers\n     * @param {jQuery} $popover - popover container\n     */\n    this.hide = function ($popover) {\n      $popover.children().hide();\n    };\n  };\n\n  return Popover;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/module/Statusbar.js",
    "content": "define([\n  'summernote/core/dom'\n], function (dom) {\n  var EDITABLE_PADDING = 24;\n\n  var Statusbar = function () {\n    var $document = $(document);\n\n    this.attach = function (layoutInfo, options) {\n      if (!options.disableResizeEditor) {\n        layoutInfo.statusbar().on('mousedown', hStatusbarMousedown);\n      }\n    };\n\n    /**\n     * `mousedown` event handler on statusbar\n     *\n     * @param {MouseEvent} event\n     */\n    var hStatusbarMousedown = function (event) {\n      event.preventDefault();\n      event.stopPropagation();\n\n      var $editable = dom.makeLayoutInfo(event.target).editable();\n      var editableTop = $editable.offset().top - $document.scrollTop();\n\n      var layoutInfo = dom.makeLayoutInfo(event.currentTarget || event.target);\n      var options = layoutInfo.editor().data('options');\n\n      $document.on('mousemove', function (event) {\n        var nHeight = event.clientY - (editableTop + EDITABLE_PADDING);\n\n        nHeight = (options.minHeight > 0) ? Math.max(nHeight, options.minHeight) : nHeight;\n        nHeight = (options.maxHeight > 0) ? Math.min(nHeight, options.maxHeight) : nHeight;\n\n        $editable.height(nHeight);\n      }).one('mouseup', function () {\n        $document.off('mousemove');\n      });\n    };\n  };\n\n  return Statusbar;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/module/Toolbar.js",
    "content": "define([\n  'summernote/core/list',\n  'summernote/core/dom',\n  'summernote/module/Button'\n], function (list, dom, Button) {\n  /**\n   * @class module.Toolbar\n   *\n   * Toolbar\n   */\n  var Toolbar = function () {\n    var button = new Button();\n\n    this.update = function ($toolbar, styleInfo) {\n      button.update($toolbar, styleInfo);\n    };\n\n    /**\n     * @param {Node} button\n     * @param {String} eventName\n     * @param {String} value\n     */\n    this.updateRecentColor = function (buttonNode, eventName, value) {\n      button.updateRecentColor(buttonNode, eventName, value);\n    };\n\n    /**\n     * activate buttons exclude codeview\n     * @param {jQuery} $toolbar\n     */\n    this.activate = function ($toolbar) {\n      $toolbar.find('button')\n              .not('button[data-event=\"codeview\"]')\n              .removeClass('disabled');\n    };\n\n    /**\n     * deactivate buttons exclude codeview\n     * @param {jQuery} $toolbar\n     */\n    this.deactivate = function ($toolbar) {\n      $toolbar.find('button')\n              .not('button[data-event=\"codeview\"]')\n              .addClass('disabled');\n    };\n\n    /**\n     * @param {jQuery} $container\n     * @param {Boolean} [bFullscreen=false]\n     */\n    this.updateFullscreen = function ($container, bFullscreen) {\n      var $btn = $container.find('button[data-event=\"fullscreen\"]');\n      $btn.toggleClass('active', bFullscreen);\n    };\n\n    /**\n     * @param {jQuery} $container\n     * @param {Boolean} [isCodeview=false]\n     */\n    this.updateCodeview = function ($container, isCodeview) {\n      var $btn = $container.find('button[data-event=\"codeview\"]');\n      $btn.toggleClass('active', isCodeview);\n\n      if (isCodeview) {\n        this.deactivate($container);\n      } else {\n        this.activate($container);\n      }\n    };\n\n    /**\n     * get button in toolbar \n     *\n     * @param {jQuery} $editable\n     * @param {String} name\n     * @return {jQuery}\n     */\n    this.get = function ($editable, name) {\n      var $toolbar = dom.makeLayoutInfo($editable).toolbar();\n\n      return $toolbar.find('[data-name=' + name + ']');\n    };\n\n    /**\n     * set button state\n     * @param {jQuery} $editable\n     * @param {String} name\n     * @param {Boolean} [isActive=true]\n     */\n    this.setButtonState = function ($editable, name, isActive) {\n      isActive = (isActive === false) ? false : true;\n\n      var $button = this.get($editable, name);\n      $button.toggleClass('active', isActive);\n    };\n  };\n\n  return Toolbar;\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/outro.js",
    "content": "}));\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/js/summernote.js",
    "content": "define([\n  'summernote/core/agent',\n  'summernote/core/list',\n  'summernote/core/dom',\n  'summernote/core/range',\n  'summernote/defaults',\n  'summernote/EventHandler',\n  'summernote/Renderer'\n], function (agent, list, dom, range,\n             defaults, EventHandler, Renderer) {\n\n  // jQuery namespace for summernote\n  /**\n   * @class $.summernote \n   * \n   * summernote attribute  \n   * \n   * @mixin defaults\n   * @singleton  \n   * \n   */\n  $.summernote = $.summernote || {};\n\n  // extends default settings\n  //  - $.summernote.version\n  //  - $.summernote.options\n  //  - $.summernote.lang\n  $.extend($.summernote, defaults);\n\n  var renderer = new Renderer();\n  var eventHandler = new EventHandler();\n\n  $.extend($.summernote, {\n    /** @property {Renderer} */\n    renderer: renderer,\n    /** @property {EventHandler} */\n    eventHandler: eventHandler,\n    /** \n     * @property {Object} core \n     * @property {core.agent} core.agent \n     * @property {core.dom} core.dom\n     * @property {core.range} core.range \n     */\n    core: {\n      agent: agent,\n      list : list,\n      dom: dom,\n      range: range\n    },\n    /** \n     * @property {Object} \n     * pluginEvents event list for plugins\n     * event has name and callback function.\n     * \n     * ``` \n     * $.summernote.addPlugin({\n     *     events : {\n     *          'hello' : function(layoutInfo, value, $target) {\n     *              console.log('event name is hello, value is ' + value );\n     *          }\n     *     }     \n     * })\n     * ```\n     * \n     * * event name is data-event property.\n     * * layoutInfo is a summernote layout information.\n     * * value is data-value property.\n     */\n    pluginEvents: {},\n\n    plugins : []\n  });\n\n  /**\n   * @method addPlugin\n   *\n   * add Plugin in Summernote \n   * \n   * Summernote can make a own plugin.\n   *\n   * ### Define plugin\n   * ```\n   * // get template function  \n   * var tmpl = $.summernote.renderer.getTemplate();\n   * \n   * // add a button   \n   * $.summernote.addPlugin({\n   *     buttons : {\n   *        // \"hello\"  is button's namespace.      \n   *        \"hello\" : function(lang, options) {\n   *            // make icon button by template function          \n   *            return tmpl.iconButton(options.iconPrefix + 'header', {\n   *                // callback function name when button clicked \n   *                event : 'hello',\n   *                // set data-value property                 \n   *                value : 'hello',                \n   *                hide : true\n   *            });           \n   *        }\n   *     \n   *     }, \n   *     \n   *     events : {\n   *        \"hello\" : function(layoutInfo, value) {\n   *            // here is event code \n   *        }\n   *     }     \n   * });\n   * ``` \n   * ### Use a plugin in toolbar\n   * \n   * ``` \n   *    $(\"#editor\").summernote({\n   *    ...\n   *    toolbar : [\n   *        // display hello plugin in toolbar     \n   *        ['group', [ 'hello' ]]\n   *    ]\n   *    ...    \n   *    });\n   * ```\n   *  \n   *  \n   * @param {Object} plugin\n   * @param {Object} [plugin.buttons] define plugin button. for detail, see to Renderer.addButtonInfo\n   * @param {Object} [plugin.dialogs] define plugin dialog. for detail, see to Renderer.addDialogInfo\n   * @param {Object} [plugin.events] add event in $.summernote.pluginEvents \n   * @param {Object} [plugin.langs] update $.summernote.lang\n   * @param {Object} [plugin.options] update $.summernote.options\n   */\n  $.summernote.addPlugin = function (plugin) {\n\n    // save plugin list\n    $.summernote.plugins.push(plugin);\n\n    if (plugin.buttons) {\n      $.each(plugin.buttons, function (name, button) {\n        renderer.addButtonInfo(name, button);\n      });\n    }\n\n    if (plugin.dialogs) {\n      $.each(plugin.dialogs, function (name, dialog) {\n        renderer.addDialogInfo(name, dialog);\n      });\n    }\n\n    if (plugin.events) {\n      $.each(plugin.events, function (name, event) {\n        $.summernote.pluginEvents[name] = event;\n      });\n    }\n\n    if (plugin.langs) {\n      $.each(plugin.langs, function (locale, lang) {\n        if ($.summernote.lang[locale]) {\n          $.extend($.summernote.lang[locale], lang);\n        }\n      });\n    }\n\n    if (plugin.options) {\n      $.extend($.summernote.options, plugin.options);\n    }\n  };\n\n  /*\n   * extend $.fn\n   */\n  $.fn.extend({\n    /**\n     * @method\n     * Initialize summernote\n     *  - create editor layout and attach Mouse and keyboard events.\n     * \n     * ```\n     * $(\"#summernote\").summernote( { options ..} );\n     * ```\n     *   \n     * @member $.fn\n     * @param {Object|String} options reference to $.summernote.options\n     * @return {this}\n     */\n    summernote: function () {\n      // check first argument's type\n      //  - {String}: External API call {{module}}.{{method}}\n      //  - {Object}: init options\n      var type = $.type(list.head(arguments));\n      var isExternalAPICalled = type === 'string';\n      var hasInitOptions = type === 'object';\n\n      // extend default options with custom user options\n      var options = hasInitOptions ? list.head(arguments) : {};\n\n      options = $.extend({}, $.summernote.options, options);\n      options.icons = $.extend({}, $.summernote.options.icons, options.icons);\n\n      // Include langInfo in options for later use, e.g. for image drag-n-drop\n      // Setup language info with en-US as default\n      options.langInfo = $.extend(true, {}, $.summernote.lang['en-US'], $.summernote.lang[options.lang]);\n\n      // override plugin options\n      if (!isExternalAPICalled && hasInitOptions) {\n        for (var i = 0, len = $.summernote.plugins.length; i < len; i++) {\n          var plugin = $.summernote.plugins[i];\n\n          if (options.plugin[plugin.name]) {\n            $.summernote.plugins[i] = $.extend(true, plugin, options.plugin[plugin.name]);\n          }\n        }\n      }\n\n      this.each(function (idx, holder) {\n        var $holder = $(holder);\n\n        // if layout isn't created yet, createLayout and attach events\n        if (!renderer.hasNoteEditor($holder)) {\n          renderer.createLayout($holder, options);\n\n          var layoutInfo = renderer.layoutInfoFromHolder($holder);\n          $holder.data('layoutInfo', layoutInfo);\n\n          eventHandler.attach(layoutInfo, options);\n          eventHandler.attachCustomEvent(layoutInfo, options);\n        }\n      });\n\n      var $first = this.first();\n      if ($first.length) {\n        var layoutInfo = renderer.layoutInfoFromHolder($first);\n\n        // external API\n        if (isExternalAPICalled) {\n          var moduleAndMethod = list.head(list.from(arguments));\n          var args = list.tail(list.from(arguments));\n\n          // TODO now external API only works for editor\n          var params = [moduleAndMethod, layoutInfo.editable()].concat(args);\n          return eventHandler.invoke.apply(eventHandler, params);\n        } else if (options.focus) {\n          // focus on first editable element for initialize editor\n          layoutInfo.editable().focus();\n        }\n      }\n\n      return this;\n    },\n\n    /**\n     * @method \n     * \n     * get the HTML contents of note or set the HTML contents of note.\n     *\n     * * get contents \n     * ```\n     * var content = $(\"#summernote\").code();\n     * ```\n     * * set contents \n     *\n     * ```\n     * $(\"#summernote\").code(html);\n     * ```\n     *\n     * @member $.fn \n     * @param {String} [html] - HTML contents(optional, set)\n     * @return {this|String} - context(set) or HTML contents of note(get).\n     */\n    code: function (html) {\n      // get the HTML contents of note\n      if (html === undefined) {\n        var $holder = this.first();\n        if (!$holder.length) {\n          return;\n        }\n\n        var layoutInfo = renderer.layoutInfoFromHolder($holder);\n        var $editable = layoutInfo && layoutInfo.editable();\n\n        if ($editable && $editable.length) {\n          var isCodeview = eventHandler.invoke('codeview.isActivated', layoutInfo);\n          eventHandler.invoke('codeview.sync', layoutInfo);\n          return isCodeview ? layoutInfo.codable().val() :\n                              layoutInfo.editable().html();\n        }\n        return dom.value($holder);\n      }\n\n      // set the HTML contents of note\n      this.each(function (i, holder) {\n        var layoutInfo = renderer.layoutInfoFromHolder($(holder));\n        var $editable = layoutInfo && layoutInfo.editable();\n        if ($editable) {\n          $editable.html(html);\n        }\n      });\n\n      return this;\n    },\n\n    /**\n     * @method\n     * \n     * destroy Editor Layout and detach Key and Mouse Event\n     *\n     * @member $.fn\n     * @return {this}\n     */\n    destroy: function () {\n      this.each(function (idx, holder) {\n        var $holder = $(holder);\n\n        if (!renderer.hasNoteEditor($holder)) {\n          return;\n        }\n\n        var info = renderer.layoutInfoFromHolder($holder);\n        var options = info.editor().data('options');\n\n        eventHandler.detach(info, options);\n        renderer.removeLayout($holder, info, options);\n      });\n\n      return this;\n    }\n  });\n});\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/less/elements.less",
    "content": "/*---------------------------------------------------\n    LESS Elements 0.9\n  ---------------------------------------------------\n    A set of useful LESS mixins\n    More info at: http://lesselements.com\n  ---------------------------------------------------*/\n\n.gradient(@color: #F5F5F5, @start: #EEE, @stop: #FFF) {\n  background: @color;\n  background: -webkit-gradient(linear,\n                               left bottom,\n                               left top,\n                               color-stop(0, @start),\n                               color-stop(1, @stop));\n  background: -ms-linear-gradient(bottom,\n                                  @start,\n                                  @stop);\n  background: -moz-linear-gradient(center bottom,\n                                   @start 0%,\n                                   @stop 100%);\n  background: -o-linear-gradient(@stop,\n                                 @start);\n  filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",@stop,@start));\n}\n.bw-gradient(@color: #F5F5F5, @start: 0, @stop: 255) {\n  background: @color;\n  background: -webkit-gradient(linear,\n                               left bottom,\n                               left top,\n                               color-stop(0, rgb(@start,@start,@start)),\n                               color-stop(1, rgb(@stop,@stop,@stop)));\n  background: -ms-linear-gradient(bottom,\n                                  rgb(@start,@start,@start) 0%,\n                                  rgb(@stop,@stop,@stop) 100%);\n  background: -moz-linear-gradient(center bottom,\n                                   rgb(@start,@start,@start) 0%,\n                                   rgb(@stop,@stop,@stop) 100%);\n  background: -o-linear-gradient(rgb(@stop,@stop,@stop),\n                                 rgb(@start,@start,@start));\n  filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",rgb(@stop,@stop,@stop),rgb(@start,@start,@start)));\n}\n.bordered(@top-color: #EEE, @right-color: #EEE, @bottom-color: #EEE, @left-color: #EEE) {\n  border-top: solid 1px @top-color;\n  border-left: solid 1px @left-color;\n  border-right: solid 1px @right-color;\n  border-bottom: solid 1px @bottom-color;\n}\n.drop-shadow(@x-axis: 0, @y-axis: 1px, @blur: 2px, @alpha: 0.1) {\n  -webkit-box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha);\n  -moz-box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha);\n  box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha);\n}\n.rounded(@radius: 2px) {\n  -webkit-border-radius: @radius;\n  -moz-border-radius: @radius;\n  border-radius: @radius;\n}\n.border-radius(@topright: 0, @bottomright: 0, @bottomleft: 0, @topleft: 0) {\n  -webkit-border-top-right-radius: @topright;\n  -webkit-border-bottom-right-radius: @bottomright;\n  -webkit-border-bottom-left-radius: @bottomleft;\n  -webkit-border-top-left-radius: @topleft;\n  -moz-border-radius-topright: @topright;\n  -moz-border-radius-bottomright: @bottomright;\n  -moz-border-radius-bottomleft: @bottomleft;\n  -moz-border-radius-topleft: @topleft;\n  border-top-right-radius: @topright;\n  border-bottom-right-radius: @bottomright;\n  border-bottom-left-radius: @bottomleft;\n  border-top-left-radius: @topleft;\n  .background-clip(padding-box);\n}\n.opacity(@opacity: 0.5) {\n  -webkit-opacity: @opacity;\n  -khtml-opacity: @opacity;\n  -moz-opacity: @opacity;\n  opacity: @opacity;\n  @opperc: @opacity * 100;\n  -ms-filter: ~\"progid:DXImageTransform.Microsoft.Alpha(opacity=@{opperc})\";\n  filter: ~\"alpha(opacity=@{opperc})\";\n}\n.transition-duration(@duration: 0.2s) {\n  -moz-transition-duration: @duration;\n  -webkit-transition-duration: @duration;\n  -o-transition-duration: @duration;\n  transition-duration: @duration;\n}\n.transform(...) {\n  -webkit-transform: @arguments;\n  -moz-transform: @arguments;\n  -o-transform: @arguments;\n  -ms-transform: @arguments;\n  transform: @arguments;\n}\n.rotation(@deg:5deg){\n  .transform(rotate(@deg));\n}\n.scale(@ratio:1.5){\n  .transform(scale(@ratio));\n}\n.transition(@duration:0.2s, @ease:ease-out) {\n  -webkit-transition: all @duration @ease;\n  -moz-transition: all @duration @ease;\n  -o-transition: all @duration @ease;\n  transition: all @duration @ease;\n}\n.inner-shadow(@horizontal:0, @vertical:1px, @blur:2px, @alpha: 0.4) {\n  -webkit-box-shadow: inset @horizontal @vertical @blur rgba(0, 0, 0, @alpha);\n  -moz-box-shadow: inset @horizontal @vertical @blur rgba(0, 0, 0, @alpha);\n  box-shadow: inset @horizontal @vertical @blur rgba(0, 0, 0, @alpha);\n}\n.box-shadow(@arguments) {\n  -webkit-box-shadow: @arguments;\n  -moz-box-shadow: @arguments;\n  box-shadow: @arguments;\n}\n.box-sizing(@sizing: border-box) {\n  -ms-box-sizing: @sizing;\n  -moz-box-sizing: @sizing;\n  -webkit-box-sizing: @sizing;\n  box-sizing: @sizing;\n}\n.user-select(@argument: none) {\n  -webkit-user-select: @argument;\n  -moz-user-select: @argument;\n  -ms-user-select: @argument;\n  user-select: @argument;\n}\n.columns(@colwidth: 250px, @colcount: 0, @colgap: 50px, @columnRuleColor: #EEE, @columnRuleStyle: solid, @columnRuleWidth: 1px) {\n  -moz-column-width: @colwidth;\n  -moz-column-count: @colcount;\n  -moz-column-gap: @colgap;\n  -moz-column-rule-color: @columnRuleColor;\n  -moz-column-rule-style: @columnRuleStyle;\n  -moz-column-rule-width: @columnRuleWidth;\n  -webkit-column-width: @colwidth;\n  -webkit-column-count: @colcount;\n  -webkit-column-gap: @colgap;\n  -webkit-column-rule-color: @columnRuleColor;\n  -webkit-column-rule-style: @columnRuleStyle;\n  -webkit-column-rule-width: @columnRuleWidth;\n  column-width: @colwidth;\n  column-count: @colcount;\n  column-gap: @colgap;\n  column-rule-color: @columnRuleColor;\n  column-rule-style: @columnRuleStyle;\n  column-rule-width: @columnRuleWidth;\n}\n.translate(@x:0, @y:0) {\n  .transform(translate(@x, @y));\n}\n.background-clip(@argument: padding-box) {\n  -moz-background-clip: @argument;\n  -webkit-background-clip: @argument;\n  background-clip: @argument;\n}\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/less/summernote.less",
    "content": "@import \"elements.less\";\n\n/* Theme Variables\n ------------------------------------------*/\n@border-color: #a9a9a9;\n@background-color: #f5f5f5;\n\n/* Frame Mode Layout\n ------------------------------------------*/\n.note-editor {\n  border: 1px solid @border-color;\n  position: relative;\n  overflow: hidden;\n\n  /* dropzone */\n  @dropzone-color: lightskyblue;\n  @dropzone-active-color: darken(@dropzone-color, 30);\n  .note-dropzone {\n    position: absolute;\n    display: none;\n    z-index: 100;\n    color: @dropzone-color;\n    background-color: white;\n    opacity: 0.95;\n    pointer-event: none;\n\n    .note-dropzone-message {\n      display: table-cell;\n      vertical-align: middle;\n      text-align: center;\n      font-size: 28px;\n      font-weight: bold;\n    }\n\n    &.hover {\n      color: @dropzone-active-color;\n    }\n  }\n\n  &.dragover .note-dropzone {\n    display: table;\n  }\n\n  /* codeview mode */\n  &.codeview {\n    .note-editing-area {\n      .note-editable {\n        display: none;\n      }\n      .note-codable {\n        display: block;\n      }\n    }\n  }\n\n  /* fullscreen mode */\n  &.fullscreen {\n    position: fixed;\n    top: 0;\n    left: 0;\n    width: 100%;\n    z-index: 1050; /* bs3 modal-backdrop: 1030, bs2: 1040 */\n    .note-editable {\n      background-color: white;\n    }\n    .note-resizebar {\n      display: none;\n    }\n  }\n\n  .note-editing-area {\n    position: relative;\n    overflow: hidden;\n\n    /* editable */\n    .note-editable {\n      background-color: #fff;\n      color: #000;\n      padding: 10px;\n      overflow: auto;\n      outline: none;\n\n      &[contenteditable=true]:empty:not(:focus):before {\n        content:attr(data-placeholder);\n      }\n      &[contenteditable=\"false\"] {\n        background-color: #e5e5e5;\n      }\n    }\n\n    /* codeable */\n    .note-codable {\n      display: none;\n      width: 100%;\n      padding: 10px;\n      border: none;\n      box-shadow: none;\n      font-family: Menlo, Monaco, monospace, sans-serif;\n      font-size: 14px;\n      color: #ccc;\n      background-color: #222;\n      resize: none;\n\n      /* override BS2 default style */\n      .box-sizing(border-box);\n      .rounded(0);\n      margin-bottom: 0;\n    }\n  }\n\n  /* statusbar */\n  .note-statusbar {\n    background-color: @background-color;\n    .note-resizebar {\n      padding-top: 1px;\n      height: 8px;\n      width: 100%;\n      cursor: ns-resize;\n      .note-icon-bar {\n        width: 20px;\n        margin: 1px auto;\n        border-top: 1px solid @border-color;\n      }\n    }\n  }\n}\n\n/* Air Mode Layout\n------------------------------------------*/\n.note-air-editor {\n  outline: none;\n}\n\n/* Popover\n------------------------------------------*/\n.note-popover .popover {\n  max-width: none;\n  .popover-content {\n    a {\n      display: inline-block;\n      max-width: 200px;\n      overflow: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap;    /* for FF */\n      vertical-align: middle; /* for FF */\n    }\n  }\n  & .arrow {\n    left: 20px;\n  }\n}\n\n/* Popover and Toolbar (Button container)\n------------------------------------------*/\n.note-popover .popover .popover-content, .panel-heading.note-toolbar {\n  margin: 0;\n  padding: 0 0 5px 5px;\n\n  &>.btn-group {\n    margin-top: 5px;\n    margin-left: 0;\n    margin-right: 5px;\n  }\n\n  .btn-group {\n    .note-table {\n      min-width: 0;\n      padding: 5px;\n      .note-dimension-picker {\n        font-size: 18px;\n        .note-dimension-picker-mousecatcher {\n          position: absolute !important;\n          z-index: 3;\n          width: 10em;\n          height: 10em;\n          cursor: pointer;\n        }\n        .note-dimension-picker-unhighlighted {\n          position: relative !important;\n          z-index: 1;\n          width: 5em;\n          height: 5em;\n          background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIj4+Pjp6ekKlAqjAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKhmnaJzPAAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC') repeat;\n        }\n        .note-dimension-picker-highlighted {\n          position: absolute !important;\n          z-index: 2;\n          width: 1em;\n          height: 1em;\n          background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIjd6vvD2f9LKLW+AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKwNDEVT0AAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC') repeat;\n        }\n      }\n    }\n  }\n\n  .note-style {\n    h1, h2, h3, h4, h5, h6, blockquote {\n      margin: 0;\n    }\n  }\n\n  .note-color {\n    .dropdown-toggle {\n      width: 20px;\n      padding-left: 5px;\n    }\n    .dropdown-menu {\n      min-width: 340px;\n      .btn-group {\n        margin: 0;\n        &:first-child {\n          margin: 0 5px;\n        }\n\n        .note-palette-title {\n          font-size: 12px;\n          margin: 2px 7px;\n          text-align: center;\n          border-bottom: 1px solid #eee;\n        }\n\n        .note-color-reset {\n          font-size: 11px;\n          margin: 3px;\n          padding: 0 3px;\n          cursor: pointer;\n          .rounded(5px);\n        }\n\n        .note-color-row {\n          height: 20px;\n        }\n\n        .note-color-reset:hover {\n          background: #eee;\n        }\n      }\n    }\n  }\n\n  .note-para {\n    .dropdown-menu {\n      min-width: 216px;\n      padding: 5px;\n      &>div:first-child {\n        margin-right: 5px;\n      }\n    }\n  }\n\n  /* dropdown-menu for toolbar and popover */\n  .dropdown-menu {\n    min-width: 90px;\n\n    /* dropdown-menu right position */\n    /* http://forrst.com/posts/Bootstrap_right_positioned_dropdown-2KB */\n    &.right {\n      right: 0;\n      left: auto;\n      &::before { right: 9px; left: auto !important;  }\n      &::after { right: 10px; left: auto !important;  }\n    }\n    /* dropdown-menu for selectbox */\n    &.note-check {\n      li a i {\n        color: deepskyblue;\n        visibility: hidden;\n      }\n      li a.checked i {\n        visibility: visible;\n      }\n    }\n\n  }\n\n  .note-fontsize-10 {\n    font-size: 10px;\n  }\n\n  /* color palette for toolbar and popover */\n  .note-color-palette {\n    line-height: 1;\n    div {\n      .note-color-btn {\n        width: 20px;\n        height: 20px;\n        padding: 0;\n        margin: 0;\n        border: 1px solid #fff;\n      }\n      .note-color-btn:hover {\n        border: 1px solid #000;\n      }\n    }\n  }\n}\n\n/* Dialog\n------------------------------------------*/\n.note-dialog {\n  &>div {\n    display: none; /* BS2's hide pacth. */\n  }\n  .form-group { /* overwrite BS's form-horizontal minus margins */\n    margin-left: 0;\n    margin-right: 0;\n  }\n  .note-modal-form {\n    margin: 0; /* overwrite BS2's form margin bottom */\n  }\n  .note-image-dialog {\n    .note-dropzone {\n      min-height: 100px;\n      font-size: 30px;\n      line-height: 4; /* vertical-align */\n      color: lightgray;\n      text-align: center;\n      border: 4px dashed lightgray;\n      margin-bottom: 10px;\n    }\n  }\n  .note-help-dialog {\n    @note-shortcut-hl: #dd0;\n    font-size: 12px;\n    color: #ccc;\n    background-color: #222 !important;\n    .opacity(0.9);\n    .modal-content {\n      background: transparent;\n      border: 1px solid white;\n      .box-shadow(none);\n      .rounded(5px);\n    }\n\n    /* BS2's background pacth. */\n    background: transparent;\n    border: none;\n\n    a {\n      font-size: 12px;\n      color: white;\n    }\n\n    .title {\n      color: white;\n      font-size: 14px;\n      font-weight: bold;\n      padding-bottom: 5px;\n      margin-bottom: 10px;\n      border-bottom: white 1px solid;\n    }\n\n    .modal-close {\n      font-size: 14px;\n      color: @note-shortcut-hl;\n      cursor: pointer;\n    }\n\n    .text-center {\n      margin: 10px 0 0;\n    }\n\n    .note-shortcut {\n      padding-top: 8px;\n      padding-bottom: 8px;\n\n      &-row {\n        margin-right: -5px;\n        margin-left: -5px;\n      }\n\n      &-col {\n        padding-right: 5px;\n        padding-left: 5px;\n      }\n\n      &-title {\n        font-size: 13px;\n        font-weight: bold;\n        color: @note-shortcut-hl;\n      }\n\n      &-key {\n        font-family: \"Courier New\";\n        color: @note-shortcut-hl;\n        text-align: right;\n      }\n    }\n  }\n}\n\n/* Handle\n------------------------------------------*/\n.note-handle {\n  /* control selection */\n  .note-control-selection {\n    position: absolute;\n    display: none;\n    border: 1px solid black;\n    &>div { position: absolute; }\n\n    .note-control-selection-bg {\n      width: 100%;\n      height: 100%;\n      background-color: black;\n      .opacity(0.30)\n    }\n\n    .note-control-handle {\n      width: 7px;\n      height: 7px;\n      border: 1px solid black;\n    }\n\n    .note-control-holder {\n      .note-control-handle;\n    }\n\n    .note-control-sizing {\n      .note-control-handle;\n      background-color: white;\n    }\n\n    .note-control-nw {\n      top: -5px;\n      left: -5px;\n      border-right: none;\n      border-bottom: none;\n    }\n\n    .note-control-ne {\n      top: -5px;\n      right: -5px;\n      border-bottom: none;\n      border-left: none;\n    }\n\n    .note-control-sw {\n      bottom: -5px;\n      left: -5px;\n      border-top: none;\n      border-right: none;\n    }\n\n    .note-control-se {\n      right: -5px;\n      bottom: -5px;\n      cursor: se-resize;\n    }\n\n    .note-control-se.note-control-holder {\n      cursor: default;\n      border-top: none;\n      border-left: none;\n    }\n\n    .note-control-selection-info {\n      right: 0;\n      bottom: 0;\n      padding: 5px;\n      margin: 5px;\n      color: white;\n      background-color: black;\n      font-size: 12px;\n      .rounded(5px);\n      .opacity(0.7);\n    }\n  }\n}\n"
  },
  {
    "path": "static/assets/plugins/summernote/src/sass/summernote.scss",
    "content": "/* Theme Mixins\n ------------------------------------------*/\n\n@mixin opacity($opacity) {\n  opacity: $opacity;\n  // IE8 filter\n  $opacity-ie: ($opacity * 100);\n  filter: #{alpha(opacity=$opacity-ie)};\n}\n\n@mixin box-shadow($shadow...) {\n  -webkit-box-shadow: $shadow; // iOS <4.3 & Android <4.1\n          box-shadow: $shadow;\n}\n\n@mixin box-sizing($boxmodel) {\n  -webkit-box-sizing: $boxmodel;\n     -moz-box-sizing: $boxmodel;\n          box-sizing: $boxmodel;\n}\n\n/* Theme Variables\n ------------------------------------------*/\n$border-color: #a9a9a9 !default;\n$background-color: #f5f5f5 !default;\n\n/* Frame Mode Layout\n ------------------------------------------*/\n.note-editor {\n  border: 1px solid $border-color;\n  position: relative;\n\n  /* dropzone */\n  $dropzone-color: lightskyblue;\n  $dropzone-active-color: darken($dropzone-color, 30);\n  .note-dropzone {\n    position: absolute;\n    display: none;\n    z-index: 100;\n    border: 2px dashed $dropzone-color;\n    color: $dropzone-color;\n    background-color: white;\n    @include opacity(.95);\n    pointer-event: none;\n\n    .note-dropzone-message {\n      display: table-cell;\n      vertical-align: middle;\n      text-align: center;\n      font-size: 28px;\n      font-weight: bold;\n    }\n\n    &.hover {\n      border: 2px dashed $dropzone-active-color;\n      color: $dropzone-active-color;\n    }\n  }\n\n  &.dragover .note-dropzone {\n    display: table;\n  }\n\n  .note-toolbar {\n    margin: -5px -10px 0 -10px;\n    padding: 0;\n  }\n\n  /* fullscreen mode */\n  &.fullscreen {\n    position: fixed;\n    top: 0;\n    left: 0;\n    width: 100%;\n    z-index: 1050; /* bs3 modal-backdrop: 1030, bs2: 1040 */\n    .note-editable {\n      background-color: white;\n    }\n    .note-resizebar {\n      display: none;\n    }\n  }\n\n  /* codeview mode */\n  &.codeview {\n    .note-editable {\n      display: none;\n    }\n    .note-codable {\n      display: block;\n    }\n  }\n\n  /* statusbar */\n  .note-statusbar {\n    background-color: $background-color;\n    .note-resizebar {\n      height: 8px;\n      width: 100%;\n      border-top: 1px solid $border-color;\n      cursor: ns-resize;\n      .note-icon-bar {\n        width: 20px;\n        margin: 1px auto;\n        border-top: 1px solid $border-color;\n      }\n    }\n  }\n\n  /* editable */\n  .note-editable[contenteditable=true]:empty:not(:focus):before {\n    content:attr(data-placeholder);\n  }\n\n  .note-editable {\n    background-color: #fff;\n    color: #000;\n    padding: 10px;\n    overflow: auto;\n    outline: none;\n  }\n  .note-editable[contenteditable=\"false\"] {\n    background-color: #e5e5e5;\n  }\n\n  /* codeable */\n  .note-codable {\n    display: none;\n    width: 100%;\n    padding: 10px;\n    border: none;\n    box-shadow: none;\n    font-family: Menlo, Monaco, monospace, sans-serif;\n    font-size: 14px;\n    color: #ccc;\n    background-color: #222;\n    resize: none;\n\n    /* override BS2 default style */\n    @include box-sizing(border-box);\n    border-radius: 0;\n    margin-bottom: 0;\n  }\n}\n\n/* Air Mode Layout\n ------------------------------------------*/\n.note-air-editor {\n  outline: none;\n}\n\n/* Popover\n ------------------------------------------*/\n.note-popover .popover {\n  max-width: none;\n  .popover-content {\n    a {\n      display: inline-block;\n      max-width: 200px;\n      overflow: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap;    /* for FF */\n      vertical-align: middle; /* for FF */\n    }\n  }\n  & .arrow {\n    left: 20px;\n  }\n}\n\n/* Popover and Toolbar (Button container)\n ------------------------------------------*/\n.note-popover .popover .popover-content, .note-toolbar {\n  margin: 0;\n  padding: 0 0 5px 5px;\n\n  &>.btn-group {\n    margin-top: 5px;\n    margin-left: 0;\n    margin-right: 5px;\n  }\n\n  .btn-group {\n    .note-table {\n      min-width: 0;\n      padding: 5px;\n      .note-dimension-picker {\n        font-size: 18px;\n        .note-dimension-picker-mousecatcher {\n          position: absolute !important;\n          z-index: 3;\n          width: 10em;\n          height: 10em;\n          cursor: pointer;\n        }\n        .note-dimension-picker-unhighlighted {\n          position: relative !important;\n          z-index: 1;\n          width: 5em;\n          height: 5em;\n          background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIj4+Pjp6ekKlAqjAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKhmnaJzPAAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC') repeat;\n        }\n        .note-dimension-picker-highlighted {\n          position: absolute !important;\n          z-index: 2;\n          width: 1em;\n          height: 1em;\n          background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIjd6vvD2f9LKLW+AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKwNDEVT0AAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC') repeat;\n        }\n      }\n    }\n  }\n\n  .note-style {\n    h1, h2, h3, h4, h5, h6, blockquote {\n      margin: 0;\n    }\n  }\n\n  .note-color {\n    .dropdown-toggle {\n      width: 20px;\n      padding-left: 5px;\n    }\n    .dropdown-menu {\n      min-width: 340px;\n      .btn-group {\n        margin: 0;\n        &:first-child {\n          margin: 0 5px;\n        }\n\n        .note-palette-title {\n          font-size: 12px;\n          margin: 2px 7px;\n          text-align: center;\n          border-bottom: 1px solid #eee;\n        }\n\n        .note-color-reset {\n          font-size: 11px;\n          margin: 3px;\n          padding: 0 3px;\n          cursor: pointer;\n          border-radius: 5px;\n        }\n\n        .note-color-row {\n          height: 20px;\n        }\n\n        .note-color-reset:hover {\n          background: #eee;\n        }\n      }\n    }\n  }\n\n  .note-para {\n    .dropdown-menu {\n      min-width: 216px;\n      padding: 5px;\n      &>div:first-child {\n        margin-right: 5px;\n      }\n    }\n  }\n\n  /* dropdown-menu for toolbar and popover */\n  .dropdown-menu {\n    min-width: 90px;\n\n    /* dropdown-menu right position */\n    /* http://forrst.com/posts/Bootstrap_right_positioned_dropdown-2KB */\n    &.right {\n      right: 0;\n      left: auto;\n      &::before { right: 9px; left: auto !important;  }\n      &::after { right: 10px; left: auto !important;  }\n    }\n\n    /* dropdown-menu for selectbox */\n    li a i {\n      color: deepskyblue;\n      visibility: hidden;\n    }\n    li a.checked i {\n      visibility: visible;\n    }\n  }\n\n  .note-fontsize-10 {\n    font-size: 10px;\n  }\n\n  /* color palette for toolbar and popover */\n  .note-color-palette {\n    line-height: 1;\n    div {\n      .note-color-btn {\n        width: 20px;\n        height: 20px;\n        padding: 0;\n        margin: 0;\n        border: 1px solid #fff;\n      }\n      .note-color-btn:hover {\n        border: 1px solid #000;\n      }\n    }\n  }\n}\n\n/* Dialog\n ------------------------------------------*/\n.note-dialog {\n  & > div {\n    display: none; /* BS2's hide pacth. */\n  }\n  .form-group { /* overwrite BS's form-horizontal minus margins */\n    margin-left: 0;\n    margin-right: 0;\n  }\n  .note-modal-form {\n    margin: 0; /* overwrite BS2's form margin bottom */\n  }\n  .note-image-dialog {\n    .note-dropzone {\n      min-height: 100px;\n      font-size: 30px;\n      line-height: 4; /* vertical-align */\n      color: lightgray;\n      text-align: center;\n      border: 4px dashed lightgray;\n      margin-bottom: 10px;\n    }\n  }\n  .note-help-dialog {\n    $note-shortcut-hl: #dd0;\n    font-size: 12px;\n    color: #ccc;\n    background-color: #222 !important;\n    @include opacity(.9);\n    .modal-content {\n      background: transparent;\n      border: 1px solid white;\n      @include box-shadow(none);\n      border-radius: 5px;\n    }\n\n    /* BS2's background pacth. */\n    background: transparent;\n    border: none;\n\n    a {\n      font-size: 12px;\n      color: white;\n    }\n\n    .title {\n      color: white;\n      font-size: 14px;\n      font-weight: bold;\n      padding-bottom: 5px;\n      margin-bottom: 10px;\n      border-bottom: white 1px solid;\n    }\n\n    .modal-close {\n      font-size: 14px;\n      color: $note-shortcut-hl;\n      cursor: pointer;\n    }\n\n    .text-center {\n      margin: 10px 0 0;\n    }\n\n    .note-shortcut {\n      padding-top: 8px;\n      padding-bottom: 8px;\n\n      &-row {\n        margin-right: -5px;\n        margin-left: -5px;\n      }\n\n      &-col {\n        padding-right: 5px;\n        padding-left: 5px;\n      }\n\n      &-title {\n        font-size: 13px;\n        font-weight: bold;\n        color: $note-shortcut-hl;\n      }\n\n      &-key {\n        font-family: \"Courier New\";\n        color: $note-shortcut-hl;\n        text-align: right;\n      }\n    }\n  }\n}\n\n/* Handle\n ------------------------------------------*/\n.note-handle {\n  /* control selection */\n  .note-control-selection {\n    position: absolute;\n    display: none;\n    border: 1px solid black;\n    &>div { position: absolute; }\n\n    .note-control-selection-bg {\n      width: 100%;\n      height: 100%;\n      background-color: black;\n      @include opacity(.30);\n    }\n\n    .note-control-handle {\n      width: 7px;\n      height: 7px;\n      border: 1px solid black;\n    }\n\n    .note-control-holder {\n      @extend .note-control-handle;\n    }\n\n    .note-control-sizing {\n      @extend .note-control-handle;\n      background-color: white;\n    }\n\n    .note-control-nw {\n      top: -5px;\n      left: -5px;\n      border-right: none;\n      border-bottom: none;\n    }\n\n    .note-control-ne {\n      top: -5px;\n      right: -5px;\n      border-bottom: none;\n      border-left: none;\n    }\n\n    .note-control-sw {\n      bottom: -5px;\n      left: -5px;\n      border-top: none;\n      border-right: none;\n    }\n\n    .note-control-se {\n      right: -5px;\n      bottom: -5px;\n      cursor: se-resize;\n    }\n\n    .note-control-se.note-control-holder {\n      cursor: default;\n      border-top: none;\n      border-left: none;\n    }\n\n    .note-control-selection-info {\n      right: 0;\n      bottom: 0;\n      padding: 5px;\n      margin: 5px;\n      color: white;\n      background-color: black;\n      font-size: 12px;\n      border-radius: 5px;\n      @include opacity(.7);\n    }\n  }\n}\n"
  },
  {
    "path": "static/assets/plugins/sweetalert/dist/sweetalert-dev.js",
    "content": ";(function(window, document, undefined) {\n  \"use strict\";\n  \n  (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n'use strict';\n\nvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };\n\n// SweetAlert\n// 2014-2015 (c) - Tristan Edwards\n// github.com/t4t5/sweetalert\n\n/*\n * jQuery-like functions for manipulating the DOM\n */\n\nvar _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation = require('./modules/handle-dom');\n\n/*\n * Handy utilities\n */\n\nvar _extend$hexToRgb$isIE8$logStr$colorLuminance = require('./modules/utils');\n\n/*\n *  Handle sweetAlert's DOM elements\n */\n\nvar _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition = require('./modules/handle-swal-dom');\n\n// Handle button events and keyboard events\n\nvar _handleButton$handleConfirm$handleCancel = require('./modules/handle-click');\n\nvar _handleKeyDown = require('./modules/handle-key');\n\nvar _handleKeyDown2 = _interopRequireWildcard(_handleKeyDown);\n\n// Default values\n\nvar _defaultParams = require('./modules/default-params');\n\nvar _defaultParams2 = _interopRequireWildcard(_defaultParams);\n\nvar _setParameters = require('./modules/set-params');\n\nvar _setParameters2 = _interopRequireWildcard(_setParameters);\n\n/*\n * Remember state in cases where opening and handling a modal will fiddle with it.\n * (We also use window.previousActiveElement as a global variable)\n */\nvar previousWindowKeyDown;\nvar lastFocusedButton;\n\n/*\n * Global sweetAlert function\n * (this is what the user calls)\n */\nvar sweetAlert, swal;\n\nsweetAlert = swal = function () {\n  var customizations = arguments[0];\n\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.addClass(document.body, 'stop-scrolling');\n  _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.resetInput();\n\n  /*\n   * Use argument if defined or default value from params object otherwise.\n   * Supports the case where a default value is boolean true and should be\n   * overridden by a corresponding explicit argument which is boolean false.\n   */\n  function argumentOrDefault(key) {\n    var args = customizations;\n    return args[key] === undefined ? _defaultParams2['default'][key] : args[key];\n  }\n\n  if (customizations === undefined) {\n    _extend$hexToRgb$isIE8$logStr$colorLuminance.logStr('SweetAlert expects at least 1 attribute!');\n    return false;\n  }\n\n  var params = _extend$hexToRgb$isIE8$logStr$colorLuminance.extend({}, _defaultParams2['default']);\n\n  switch (typeof customizations) {\n\n    // Ex: swal(\"Hello\", \"Just testing\", \"info\");\n    case 'string':\n      params.title = customizations;\n      params.text = arguments[1] || '';\n      params.type = arguments[2] || '';\n      break;\n\n    // Ex: swal({ title:\"Hello\", text: \"Just testing\", type: \"info\" });\n    case 'object':\n      if (customizations.title === undefined) {\n        _extend$hexToRgb$isIE8$logStr$colorLuminance.logStr('Missing \"title\" argument!');\n        return false;\n      }\n\n      params.title = customizations.title;\n\n      for (var customName in _defaultParams2['default']) {\n        params[customName] = argumentOrDefault(customName);\n      }\n\n      // Show \"Confirm\" instead of \"OK\" if cancel button is visible\n      params.confirmButtonText = params.showCancelButton ? 'Confirm' : _defaultParams2['default'].confirmButtonText;\n      params.confirmButtonText = argumentOrDefault('confirmButtonText');\n\n      // Callback function when clicking on \"OK\"/\"Cancel\"\n      params.doneFunction = arguments[1] || null;\n\n      break;\n\n    default:\n      _extend$hexToRgb$isIE8$logStr$colorLuminance.logStr('Unexpected type of argument! Expected \"string\" or \"object\", got ' + typeof customizations);\n      return false;\n\n  }\n\n  _setParameters2['default'](params);\n  _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.fixVerticalPosition();\n  _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.openModal(arguments[1]);\n\n  // Modal interactions\n  var modal = _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.getModal();\n\n  /*\n   * Make sure all modal buttons respond to all events\n   */\n  var $buttons = modal.querySelectorAll('button');\n  var buttonEvents = ['onclick', 'onmouseover', 'onmouseout', 'onmousedown', 'onmouseup', 'onfocus'];\n  var onButtonEvent = function onButtonEvent(e) {\n    return _handleButton$handleConfirm$handleCancel.handleButton(e, params, modal);\n  };\n\n  for (var btnIndex = 0; btnIndex < $buttons.length; btnIndex++) {\n    for (var evtIndex = 0; evtIndex < buttonEvents.length; evtIndex++) {\n      var btnEvt = buttonEvents[evtIndex];\n      $buttons[btnIndex][btnEvt] = onButtonEvent;\n    }\n  }\n\n  // Clicking outside the modal dismisses it (if allowed by user)\n  _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.getOverlay().onclick = onButtonEvent;\n\n  previousWindowKeyDown = window.onkeydown;\n\n  var onKeyEvent = function onKeyEvent(e) {\n    return _handleKeyDown2['default'](e, params, modal);\n  };\n  window.onkeydown = onKeyEvent;\n\n  window.onfocus = function () {\n    // When the user has focused away and focused back from the whole window.\n    setTimeout(function () {\n      // Put in a timeout to jump out of the event sequence.\n      // Calling focus() in the event sequence confuses things.\n      if (lastFocusedButton !== undefined) {\n        lastFocusedButton.focus();\n        lastFocusedButton = undefined;\n      }\n    }, 0);\n  };\n\n  // Show alert with enabled buttons always\n  swal.enableButtons();\n};\n\n/*\n * Set default params for each popup\n * @param {Object} userParams\n */\nsweetAlert.setDefaults = swal.setDefaults = function (userParams) {\n  if (!userParams) {\n    throw new Error('userParams is required');\n  }\n  if (typeof userParams !== 'object') {\n    throw new Error('userParams has to be a object');\n  }\n\n  _extend$hexToRgb$isIE8$logStr$colorLuminance.extend(_defaultParams2['default'], userParams);\n};\n\n/*\n * Animation when closing modal\n */\nsweetAlert.close = swal.close = function () {\n  var modal = _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.getModal();\n\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.fadeOut(_sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.getOverlay(), 5);\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.fadeOut(modal, 5);\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass(modal, 'showSweetAlert');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.addClass(modal, 'hideSweetAlert');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass(modal, 'visible');\n\n  /*\n   * Reset icon animations\n   */\n  var $successIcon = modal.querySelector('.sa-icon.sa-success');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass($successIcon, 'animate');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass($successIcon.querySelector('.sa-tip'), 'animateSuccessTip');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass($successIcon.querySelector('.sa-long'), 'animateSuccessLong');\n\n  var $errorIcon = modal.querySelector('.sa-icon.sa-error');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass($errorIcon, 'animateErrorIcon');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass($errorIcon.querySelector('.sa-x-mark'), 'animateXMark');\n\n  var $warningIcon = modal.querySelector('.sa-icon.sa-warning');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass($warningIcon, 'pulseWarning');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass($warningIcon.querySelector('.sa-body'), 'pulseWarningIns');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass($warningIcon.querySelector('.sa-dot'), 'pulseWarningIns');\n\n  // Reset custom class (delay so that UI changes aren't visible)\n  setTimeout(function () {\n    var customClass = modal.getAttribute('data-custom-class');\n    _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass(modal, customClass);\n  }, 300);\n\n  // Make page scrollable again\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass(document.body, 'stop-scrolling');\n\n  // Reset the page to its previous state\n  window.onkeydown = previousWindowKeyDown;\n  if (window.previousActiveElement) {\n    window.previousActiveElement.focus();\n  }\n  lastFocusedButton = undefined;\n  clearTimeout(modal.timeout);\n\n  return true;\n};\n\n/*\n * Validation of the input field is done by user\n * If something is wrong => call showInputError with errorMessage\n */\nsweetAlert.showInputError = swal.showInputError = function (errorMessage) {\n  var modal = _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.getModal();\n\n  var $errorIcon = modal.querySelector('.sa-input-error');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.addClass($errorIcon, 'show');\n\n  var $errorContainer = modal.querySelector('.sa-error-container');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.addClass($errorContainer, 'show');\n\n  $errorContainer.querySelector('p').innerHTML = errorMessage;\n\n  setTimeout(function () {\n    sweetAlert.enableButtons();\n  }, 1);\n\n  modal.querySelector('input').focus();\n};\n\n/*\n * Reset input error DOM elements\n */\nsweetAlert.resetInputError = swal.resetInputError = function (event) {\n  // If press enter => ignore\n  if (event && event.keyCode === 13) {\n    return false;\n  }\n\n  var $modal = _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.getModal();\n\n  var $errorIcon = $modal.querySelector('.sa-input-error');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass($errorIcon, 'show');\n\n  var $errorContainer = $modal.querySelector('.sa-error-container');\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide$isDescendant$getTopMargin$fadeIn$fadeOut$fireClick$stopEventPropagation.removeClass($errorContainer, 'show');\n};\n\n/*\n * Disable confirm and cancel buttons\n */\nsweetAlert.disableButtons = swal.disableButtons = function (event) {\n  var modal = _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.getModal();\n  var $confirmButton = modal.querySelector('button.confirm');\n  var $cancelButton = modal.querySelector('button.cancel');\n  $confirmButton.disabled = true;\n  $cancelButton.disabled = true;\n};\n\n/*\n * Enable confirm and cancel buttons\n */\nsweetAlert.enableButtons = swal.enableButtons = function (event) {\n  var modal = _sweetAlertInitialize$getModal$getOverlay$getInput$setFocusStyle$openModal$resetInput$fixVerticalPosition.getModal();\n  var $confirmButton = modal.querySelector('button.confirm');\n  var $cancelButton = modal.querySelector('button.cancel');\n  $confirmButton.disabled = false;\n  $cancelButton.disabled = false;\n};\n\nif (typeof window !== 'undefined') {\n  // The 'handle-click' module requires\n  // that 'sweetAlert' was set as global.\n  window.sweetAlert = window.swal = sweetAlert;\n} else {\n  _extend$hexToRgb$isIE8$logStr$colorLuminance.logStr('SweetAlert is a frontend module!');\n}\n\n},{\"./modules/default-params\":2,\"./modules/handle-click\":3,\"./modules/handle-dom\":4,\"./modules/handle-key\":5,\"./modules/handle-swal-dom\":6,\"./modules/set-params\":8,\"./modules/utils\":9}],2:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\nvar defaultParams = {\n  title: '',\n  text: '',\n  type: null,\n  allowOutsideClick: false,\n  showConfirmButton: true,\n  showCancelButton: false,\n  closeOnConfirm: true,\n  closeOnCancel: true,\n  confirmButtonText: 'OK',\n  confirmButtonColor: '#8CD4F5',\n  cancelButtonText: 'Cancel',\n  imageUrl: null,\n  imageSize: null,\n  timer: null,\n  customClass: '',\n  html: false,\n  animation: true,\n  allowEscapeKey: true,\n  inputType: 'text',\n  inputPlaceholder: '',\n  inputValue: '',\n  showLoaderOnConfirm: false\n};\n\nexports['default'] = defaultParams;\nmodule.exports = exports['default'];\n\n},{}],3:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\n\nvar _colorLuminance = require('./utils');\n\nvar _getModal = require('./handle-swal-dom');\n\nvar _hasClass$isDescendant = require('./handle-dom');\n\n/*\n * User clicked on \"Confirm\"/\"OK\" or \"Cancel\"\n */\nvar handleButton = function handleButton(event, params, modal) {\n  var e = event || window.event;\n  var target = e.target || e.srcElement;\n\n  var targetedConfirm = target.className.indexOf('confirm') !== -1;\n  var targetedOverlay = target.className.indexOf('sweet-overlay') !== -1;\n  var modalIsVisible = _hasClass$isDescendant.hasClass(modal, 'visible');\n  var doneFunctionExists = params.doneFunction && modal.getAttribute('data-has-done-function') === 'true';\n\n  // Since the user can change the background-color of the confirm button programmatically,\n  // we must calculate what the color should be on hover/active\n  var normalColor, hoverColor, activeColor;\n  if (targetedConfirm && params.confirmButtonColor) {\n    normalColor = params.confirmButtonColor;\n    hoverColor = _colorLuminance.colorLuminance(normalColor, -0.04);\n    activeColor = _colorLuminance.colorLuminance(normalColor, -0.14);\n  }\n\n  function shouldSetConfirmButtonColor(color) {\n    if (targetedConfirm && params.confirmButtonColor) {\n      target.style.backgroundColor = color;\n    }\n  }\n\n  switch (e.type) {\n    case 'mouseover':\n      shouldSetConfirmButtonColor(hoverColor);\n      break;\n\n    case 'mouseout':\n      shouldSetConfirmButtonColor(normalColor);\n      break;\n\n    case 'mousedown':\n      shouldSetConfirmButtonColor(activeColor);\n      break;\n\n    case 'mouseup':\n      shouldSetConfirmButtonColor(hoverColor);\n      break;\n\n    case 'focus':\n      var $confirmButton = modal.querySelector('button.confirm');\n      var $cancelButton = modal.querySelector('button.cancel');\n\n      if (targetedConfirm) {\n        $cancelButton.style.boxShadow = 'none';\n      } else {\n        $confirmButton.style.boxShadow = 'none';\n      }\n      break;\n\n    case 'click':\n      var clickedOnModal = modal === target;\n      var clickedOnModalChild = _hasClass$isDescendant.isDescendant(modal, target);\n\n      // Ignore click outside if allowOutsideClick is false\n      if (!clickedOnModal && !clickedOnModalChild && modalIsVisible && !params.allowOutsideClick) {\n        break;\n      }\n\n      if (targetedConfirm && doneFunctionExists && modalIsVisible) {\n        handleConfirm(modal, params);\n      } else if (doneFunctionExists && modalIsVisible || targetedOverlay) {\n        handleCancel(modal, params);\n      } else if (_hasClass$isDescendant.isDescendant(modal, target) && target.tagName === 'BUTTON') {\n        sweetAlert.close();\n      }\n      break;\n  }\n};\n\n/*\n *  User clicked on \"Confirm\"/\"OK\"\n */\nvar handleConfirm = function handleConfirm(modal, params) {\n  var callbackValue = true;\n\n  if (_hasClass$isDescendant.hasClass(modal, 'show-input')) {\n    callbackValue = modal.querySelector('input').value;\n\n    if (!callbackValue) {\n      callbackValue = '';\n    }\n  }\n\n  params.doneFunction(callbackValue);\n\n  if (params.closeOnConfirm) {\n    sweetAlert.close();\n  }\n  // Disable cancel and confirm button if the parameter is true\n  if (params.showLoaderOnConfirm) {\n    sweetAlert.disableButtons();\n  }\n};\n\n/*\n *  User clicked on \"Cancel\"\n */\nvar handleCancel = function handleCancel(modal, params) {\n  // Check if callback function expects a parameter (to track cancel actions)\n  var functionAsStr = String(params.doneFunction).replace(/\\s/g, '');\n  var functionHandlesCancel = functionAsStr.substring(0, 9) === 'function(' && functionAsStr.substring(9, 10) !== ')';\n\n  if (functionHandlesCancel) {\n    params.doneFunction(false);\n  }\n\n  if (params.closeOnCancel) {\n    sweetAlert.close();\n  }\n};\n\nexports['default'] = {\n  handleButton: handleButton,\n  handleConfirm: handleConfirm,\n  handleCancel: handleCancel\n};\nmodule.exports = exports['default'];\n\n},{\"./handle-dom\":4,\"./handle-swal-dom\":6,\"./utils\":9}],4:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\nvar hasClass = function hasClass(elem, className) {\n  return new RegExp(' ' + className + ' ').test(' ' + elem.className + ' ');\n};\n\nvar addClass = function addClass(elem, className) {\n  if (!hasClass(elem, className)) {\n    elem.className += ' ' + className;\n  }\n};\n\nvar removeClass = function removeClass(elem, className) {\n  var newClass = ' ' + elem.className.replace(/[\\t\\r\\n]/g, ' ') + ' ';\n  if (hasClass(elem, className)) {\n    while (newClass.indexOf(' ' + className + ' ') >= 0) {\n      newClass = newClass.replace(' ' + className + ' ', ' ');\n    }\n    elem.className = newClass.replace(/^\\s+|\\s+$/g, '');\n  }\n};\n\nvar escapeHtml = function escapeHtml(str) {\n  var div = document.createElement('div');\n  div.appendChild(document.createTextNode(str));\n  return div.innerHTML;\n};\n\nvar _show = function _show(elem) {\n  elem.style.opacity = '';\n  elem.style.display = 'block';\n};\n\nvar show = function show(elems) {\n  if (elems && !elems.length) {\n    return _show(elems);\n  }\n  for (var i = 0; i < elems.length; ++i) {\n    _show(elems[i]);\n  }\n};\n\nvar _hide = function _hide(elem) {\n  elem.style.opacity = '';\n  elem.style.display = 'none';\n};\n\nvar hide = function hide(elems) {\n  if (elems && !elems.length) {\n    return _hide(elems);\n  }\n  for (var i = 0; i < elems.length; ++i) {\n    _hide(elems[i]);\n  }\n};\n\nvar isDescendant = function isDescendant(parent, child) {\n  var node = child.parentNode;\n  while (node !== null) {\n    if (node === parent) {\n      return true;\n    }\n    node = node.parentNode;\n  }\n  return false;\n};\n\nvar getTopMargin = function getTopMargin(elem) {\n  elem.style.left = '-9999px';\n  elem.style.display = 'block';\n\n  var height = elem.clientHeight,\n      padding;\n  if (typeof getComputedStyle !== 'undefined') {\n    // IE 8\n    padding = parseInt(getComputedStyle(elem).getPropertyValue('padding-top'), 10);\n  } else {\n    padding = parseInt(elem.currentStyle.padding);\n  }\n\n  elem.style.left = '';\n  elem.style.display = 'none';\n  return '-' + parseInt((height + padding) / 2) + 'px';\n};\n\nvar fadeIn = function fadeIn(elem, interval) {\n  if (+elem.style.opacity < 1) {\n    interval = interval || 16;\n    elem.style.opacity = 0;\n    elem.style.display = 'block';\n    var last = +new Date();\n    var tick = (function (_tick) {\n      function tick() {\n        return _tick.apply(this, arguments);\n      }\n\n      tick.toString = function () {\n        return _tick.toString();\n      };\n\n      return tick;\n    })(function () {\n      elem.style.opacity = +elem.style.opacity + (new Date() - last) / 100;\n      last = +new Date();\n\n      if (+elem.style.opacity < 1) {\n        setTimeout(tick, interval);\n      }\n    });\n    tick();\n  }\n  elem.style.display = 'block'; //fallback IE8\n};\n\nvar fadeOut = function fadeOut(elem, interval) {\n  interval = interval || 16;\n  elem.style.opacity = 1;\n  var last = +new Date();\n  var tick = (function (_tick2) {\n    function tick() {\n      return _tick2.apply(this, arguments);\n    }\n\n    tick.toString = function () {\n      return _tick2.toString();\n    };\n\n    return tick;\n  })(function () {\n    elem.style.opacity = +elem.style.opacity - (new Date() - last) / 100;\n    last = +new Date();\n\n    if (+elem.style.opacity > 0) {\n      setTimeout(tick, interval);\n    } else {\n      elem.style.display = 'none';\n    }\n  });\n  tick();\n};\n\nvar fireClick = function fireClick(node) {\n  // Taken from http://www.nonobtrusive.com/2011/11/29/programatically-fire-crossbrowser-click-event-with-javascript/\n  // Then fixed for today's Chrome browser.\n  if (typeof MouseEvent === 'function') {\n    // Up-to-date approach\n    var mevt = new MouseEvent('click', {\n      view: window,\n      bubbles: false,\n      cancelable: true\n    });\n    node.dispatchEvent(mevt);\n  } else if (document.createEvent) {\n    // Fallback\n    var evt = document.createEvent('MouseEvents');\n    evt.initEvent('click', false, false);\n    node.dispatchEvent(evt);\n  } else if (document.createEventObject) {\n    node.fireEvent('onclick');\n  } else if (typeof node.onclick === 'function') {\n    node.onclick();\n  }\n};\n\nvar stopEventPropagation = function stopEventPropagation(e) {\n  // In particular, make sure the space bar doesn't scroll the main window.\n  if (typeof e.stopPropagation === 'function') {\n    e.stopPropagation();\n    e.preventDefault();\n  } else if (window.event && window.event.hasOwnProperty('cancelBubble')) {\n    window.event.cancelBubble = true;\n  }\n};\n\nexports.hasClass = hasClass;\nexports.addClass = addClass;\nexports.removeClass = removeClass;\nexports.escapeHtml = escapeHtml;\nexports._show = _show;\nexports.show = show;\nexports._hide = _hide;\nexports.hide = hide;\nexports.isDescendant = isDescendant;\nexports.getTopMargin = getTopMargin;\nexports.fadeIn = fadeIn;\nexports.fadeOut = fadeOut;\nexports.fireClick = fireClick;\nexports.stopEventPropagation = stopEventPropagation;\n\n},{}],5:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\n\nvar _stopEventPropagation$fireClick = require('./handle-dom');\n\nvar _setFocusStyle = require('./handle-swal-dom');\n\nvar handleKeyDown = function handleKeyDown(event, params, modal) {\n  var e = event || window.event;\n  var keyCode = e.keyCode || e.which;\n\n  var $okButton = modal.querySelector('button.confirm');\n  var $cancelButton = modal.querySelector('button.cancel');\n  var $modalButtons = modal.querySelectorAll('button[tabindex]');\n\n  if ([9, 13, 32, 27].indexOf(keyCode) === -1) {\n    // Don't do work on keys we don't care about.\n    return;\n  }\n\n  var $targetElement = e.target || e.srcElement;\n\n  var btnIndex = -1; // Find the button - note, this is a nodelist, not an array.\n  for (var i = 0; i < $modalButtons.length; i++) {\n    if ($targetElement === $modalButtons[i]) {\n      btnIndex = i;\n      break;\n    }\n  }\n\n  if (keyCode === 9) {\n    // TAB\n    if (btnIndex === -1) {\n      // No button focused. Jump to the confirm button.\n      $targetElement = $okButton;\n    } else {\n      // Cycle to the next button\n      if (btnIndex === $modalButtons.length - 1) {\n        $targetElement = $modalButtons[0];\n      } else {\n        $targetElement = $modalButtons[btnIndex + 1];\n      }\n    }\n\n    _stopEventPropagation$fireClick.stopEventPropagation(e);\n    $targetElement.focus();\n\n    if (params.confirmButtonColor) {\n      _setFocusStyle.setFocusStyle($targetElement, params.confirmButtonColor);\n    }\n  } else {\n    if (keyCode === 13) {\n      if ($targetElement.tagName === 'INPUT') {\n        $targetElement = $okButton;\n        $okButton.focus();\n      }\n\n      if (btnIndex === -1) {\n        // ENTER/SPACE clicked outside of a button.\n        $targetElement = $okButton;\n      } else {\n        // Do nothing - let the browser handle it.\n        $targetElement = undefined;\n      }\n    } else if (keyCode === 27 && params.allowEscapeKey === true) {\n      $targetElement = $cancelButton;\n      _stopEventPropagation$fireClick.fireClick($targetElement, e);\n    } else {\n      // Fallback - let the browser handle it.\n      $targetElement = undefined;\n    }\n  }\n};\n\nexports['default'] = handleKeyDown;\nmodule.exports = exports['default'];\n\n},{\"./handle-dom\":4,\"./handle-swal-dom\":6}],6:[function(require,module,exports){\n'use strict';\n\nvar _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\n\nvar _hexToRgb = require('./utils');\n\nvar _removeClass$getTopMargin$fadeIn$show$addClass = require('./handle-dom');\n\nvar _defaultParams = require('./default-params');\n\nvar _defaultParams2 = _interopRequireWildcard(_defaultParams);\n\n/*\n * Add modal + overlay to DOM\n */\n\nvar _injectedHTML = require('./injected-html');\n\nvar _injectedHTML2 = _interopRequireWildcard(_injectedHTML);\n\nvar modalClass = '.sweet-alert';\nvar overlayClass = '.sweet-overlay';\n\nvar sweetAlertInitialize = function sweetAlertInitialize() {\n  var sweetWrap = document.createElement('div');\n  sweetWrap.innerHTML = _injectedHTML2['default'];\n\n  // Append elements to body\n  while (sweetWrap.firstChild) {\n    document.body.appendChild(sweetWrap.firstChild);\n  }\n};\n\n/*\n * Get DOM element of modal\n */\nvar getModal = (function (_getModal) {\n  function getModal() {\n    return _getModal.apply(this, arguments);\n  }\n\n  getModal.toString = function () {\n    return _getModal.toString();\n  };\n\n  return getModal;\n})(function () {\n  var $modal = document.querySelector(modalClass);\n\n  if (!$modal) {\n    sweetAlertInitialize();\n    $modal = getModal();\n  }\n\n  return $modal;\n});\n\n/*\n * Get DOM element of input (in modal)\n */\nvar getInput = function getInput() {\n  var $modal = getModal();\n  if ($modal) {\n    return $modal.querySelector('input');\n  }\n};\n\n/*\n * Get DOM element of overlay\n */\nvar getOverlay = function getOverlay() {\n  return document.querySelector(overlayClass);\n};\n\n/*\n * Add box-shadow style to button (depending on its chosen bg-color)\n */\nvar setFocusStyle = function setFocusStyle($button, bgColor) {\n  var rgbColor = _hexToRgb.hexToRgb(bgColor);\n  $button.style.boxShadow = '0 0 2px rgba(' + rgbColor + ', 0.8), inset 0 0 0 1px rgba(0, 0, 0, 0.05)';\n};\n\n/*\n * Animation when opening modal\n */\nvar openModal = function openModal(callback) {\n  var $modal = getModal();\n  _removeClass$getTopMargin$fadeIn$show$addClass.fadeIn(getOverlay(), 10);\n  _removeClass$getTopMargin$fadeIn$show$addClass.show($modal);\n  _removeClass$getTopMargin$fadeIn$show$addClass.addClass($modal, 'showSweetAlert');\n  _removeClass$getTopMargin$fadeIn$show$addClass.removeClass($modal, 'hideSweetAlert');\n\n  window.previousActiveElement = document.activeElement;\n  var $okButton = $modal.querySelector('button.confirm');\n  $okButton.focus();\n\n  setTimeout(function () {\n    _removeClass$getTopMargin$fadeIn$show$addClass.addClass($modal, 'visible');\n  }, 500);\n\n  var timer = $modal.getAttribute('data-timer');\n\n  if (timer !== 'null' && timer !== '') {\n    var timerCallback = callback;\n    $modal.timeout = setTimeout(function () {\n      var doneFunctionExists = (timerCallback || null) && $modal.getAttribute('data-has-done-function') === 'true';\n      if (doneFunctionExists) {\n        timerCallback(null);\n      } else {\n        sweetAlert.close();\n      }\n    }, timer);\n  }\n};\n\n/*\n * Reset the styling of the input\n * (for example if errors have been shown)\n */\nvar resetInput = function resetInput() {\n  var $modal = getModal();\n  var $input = getInput();\n\n  _removeClass$getTopMargin$fadeIn$show$addClass.removeClass($modal, 'show-input');\n  $input.value = _defaultParams2['default'].inputValue;\n  $input.setAttribute('type', _defaultParams2['default'].inputType);\n  $input.setAttribute('placeholder', _defaultParams2['default'].inputPlaceholder);\n\n  resetInputError();\n};\n\nvar resetInputError = function resetInputError(event) {\n  // If press enter => ignore\n  if (event && event.keyCode === 13) {\n    return false;\n  }\n\n  var $modal = getModal();\n\n  var $errorIcon = $modal.querySelector('.sa-input-error');\n  _removeClass$getTopMargin$fadeIn$show$addClass.removeClass($errorIcon, 'show');\n\n  var $errorContainer = $modal.querySelector('.sa-error-container');\n  _removeClass$getTopMargin$fadeIn$show$addClass.removeClass($errorContainer, 'show');\n};\n\n/*\n * Set \"margin-top\"-property on modal based on its computed height\n */\nvar fixVerticalPosition = function fixVerticalPosition() {\n  var $modal = getModal();\n  $modal.style.marginTop = _removeClass$getTopMargin$fadeIn$show$addClass.getTopMargin(getModal());\n};\n\nexports.sweetAlertInitialize = sweetAlertInitialize;\nexports.getModal = getModal;\nexports.getOverlay = getOverlay;\nexports.getInput = getInput;\nexports.setFocusStyle = setFocusStyle;\nexports.openModal = openModal;\nexports.resetInput = resetInput;\nexports.resetInputError = resetInputError;\nexports.fixVerticalPosition = fixVerticalPosition;\n\n},{\"./default-params\":2,\"./handle-dom\":4,\"./injected-html\":7,\"./utils\":9}],7:[function(require,module,exports){\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nvar injectedHTML =\n\n// Dark overlay\n\"<div class=\\\"sweet-overlay\\\" tabIndex=\\\"-1\\\"></div>\" +\n\n// Modal\n\"<div class=\\\"sweet-alert\\\">\" +\n\n// Error icon\n\"<div class=\\\"sa-icon sa-error\\\">\\n      <span class=\\\"sa-x-mark\\\">\\n        <span class=\\\"sa-line sa-left\\\"></span>\\n        <span class=\\\"sa-line sa-right\\\"></span>\\n      </span>\\n    </div>\" +\n\n// Warning icon\n\"<div class=\\\"sa-icon sa-warning\\\">\\n      <span class=\\\"sa-body\\\"></span>\\n      <span class=\\\"sa-dot\\\"></span>\\n    </div>\" +\n\n// Info icon\n\"<div class=\\\"sa-icon sa-info\\\"></div>\" +\n\n// Success icon\n\"<div class=\\\"sa-icon sa-success\\\">\\n      <span class=\\\"sa-line sa-tip\\\"></span>\\n      <span class=\\\"sa-line sa-long\\\"></span>\\n\\n      <div class=\\\"sa-placeholder\\\"></div>\\n      <div class=\\\"sa-fix\\\"></div>\\n    </div>\" + \"<div class=\\\"sa-icon sa-custom\\\"></div>\" +\n\n// Title, text and input\n\"<h2>Title</h2>\\n    <p>Text</p>\\n    <fieldset>\\n      <input type=\\\"text\\\" tabIndex=\\\"3\\\" />\\n      <div class=\\\"sa-input-error\\\"></div>\\n    </fieldset>\" +\n\n// Input errors\n\"<div class=\\\"sa-error-container\\\">\\n      <div class=\\\"icon\\\">!</div>\\n      <p>Not valid!</p>\\n    </div>\" +\n\n// Cancel and confirm buttons\n\"<div class=\\\"sa-button-container\\\">\\n      <button class=\\\"cancel\\\" tabIndex=\\\"2\\\">Cancel</button>\\n      <div class=\\\"sa-confirm-button-container\\\">\\n        <button class=\\\"confirm\\\" tabIndex=\\\"1\\\">OK</button>\" +\n\n// Loading animation\n\"<div class=\\\"la-ball-fall\\\">\\n          <div></div>\\n          <div></div>\\n          <div></div>\\n        </div>\\n      </div>\\n    </div>\" +\n\n// End of modal\n\"</div>\";\n\nexports[\"default\"] = injectedHTML;\nmodule.exports = exports[\"default\"];\n\n},{}],8:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\n\nvar _isIE8 = require('./utils');\n\nvar _getModal$getInput$setFocusStyle = require('./handle-swal-dom');\n\nvar _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide = require('./handle-dom');\n\nvar alertTypes = ['error', 'warning', 'info', 'success', 'input', 'prompt'];\n\n/*\n * Set type, text and actions on modal\n */\nvar setParameters = function setParameters(params) {\n  var modal = _getModal$getInput$setFocusStyle.getModal();\n\n  var $title = modal.querySelector('h2');\n  var $text = modal.querySelector('p');\n  var $cancelBtn = modal.querySelector('button.cancel');\n  var $confirmBtn = modal.querySelector('button.confirm');\n\n  /*\n   * Title\n   */\n  $title.innerHTML = params.html ? params.title : _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.escapeHtml(params.title).split('\\n').join('<br>');\n\n  /*\n   * Text\n   */\n  $text.innerHTML = params.html ? params.text : _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.escapeHtml(params.text || '').split('\\n').join('<br>');\n  if (params.text) _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.show($text);\n\n  /*\n   * Custom class\n   */\n  if (params.customClass) {\n    _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass(modal, params.customClass);\n    modal.setAttribute('data-custom-class', params.customClass);\n  } else {\n    // Find previously set classes and remove them\n    var customClass = modal.getAttribute('data-custom-class');\n    _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.removeClass(modal, customClass);\n    modal.setAttribute('data-custom-class', '');\n  }\n\n  /*\n   * Icon\n   */\n  _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.hide(modal.querySelectorAll('.sa-icon'));\n\n  if (params.type && !_isIE8.isIE8()) {\n    var _ret = (function () {\n\n      var validType = false;\n\n      for (var i = 0; i < alertTypes.length; i++) {\n        if (params.type === alertTypes[i]) {\n          validType = true;\n          break;\n        }\n      }\n\n      if (!validType) {\n        logStr('Unknown alert type: ' + params.type);\n        return {\n          v: false\n        };\n      }\n\n      var typesWithIcons = ['success', 'error', 'warning', 'info'];\n      var $icon = undefined;\n\n      if (typesWithIcons.indexOf(params.type) !== -1) {\n        $icon = modal.querySelector('.sa-icon.' + 'sa-' + params.type);\n        _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.show($icon);\n      }\n\n      var $input = _getModal$getInput$setFocusStyle.getInput();\n\n      // Animate icon\n      switch (params.type) {\n\n        case 'success':\n          _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon, 'animate');\n          _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon.querySelector('.sa-tip'), 'animateSuccessTip');\n          _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon.querySelector('.sa-long'), 'animateSuccessLong');\n          break;\n\n        case 'error':\n          _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon, 'animateErrorIcon');\n          _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon.querySelector('.sa-x-mark'), 'animateXMark');\n          break;\n\n        case 'warning':\n          _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon, 'pulseWarning');\n          _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon.querySelector('.sa-body'), 'pulseWarningIns');\n          _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass($icon.querySelector('.sa-dot'), 'pulseWarningIns');\n          break;\n\n        case 'input':\n        case 'prompt':\n          $input.setAttribute('type', params.inputType);\n          $input.value = params.inputValue;\n          $input.setAttribute('placeholder', params.inputPlaceholder);\n          _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.addClass(modal, 'show-input');\n          setTimeout(function () {\n            $input.focus();\n            $input.addEventListener('keyup', swal.resetInputError);\n          }, 400);\n          break;\n      }\n    })();\n\n    if (typeof _ret === 'object') {\n      return _ret.v;\n    }\n  }\n\n  /*\n   * Custom image\n   */\n  if (params.imageUrl) {\n    var $customIcon = modal.querySelector('.sa-icon.sa-custom');\n\n    $customIcon.style.backgroundImage = 'url(' + params.imageUrl + ')';\n    _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.show($customIcon);\n\n    var _imgWidth = 80;\n    var _imgHeight = 80;\n\n    if (params.imageSize) {\n      var dimensions = params.imageSize.toString().split('x');\n      var imgWidth = dimensions[0];\n      var imgHeight = dimensions[1];\n\n      if (!imgWidth || !imgHeight) {\n        logStr('Parameter imageSize expects value with format WIDTHxHEIGHT, got ' + params.imageSize);\n      } else {\n        _imgWidth = imgWidth;\n        _imgHeight = imgHeight;\n      }\n    }\n\n    $customIcon.setAttribute('style', $customIcon.getAttribute('style') + 'width:' + _imgWidth + 'px; height:' + _imgHeight + 'px');\n  }\n\n  /*\n   * Show cancel button?\n   */\n  modal.setAttribute('data-has-cancel-button', params.showCancelButton);\n  if (params.showCancelButton) {\n    $cancelBtn.style.display = 'inline-block';\n  } else {\n    _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.hide($cancelBtn);\n  }\n\n  /*\n   * Show confirm button?\n   */\n  modal.setAttribute('data-has-confirm-button', params.showConfirmButton);\n  if (params.showConfirmButton) {\n    $confirmBtn.style.display = 'inline-block';\n  } else {\n    _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.hide($confirmBtn);\n  }\n\n  /*\n   * Custom text on cancel/confirm buttons\n   */\n  if (params.cancelButtonText) {\n    $cancelBtn.innerHTML = _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.escapeHtml(params.cancelButtonText);\n  }\n  if (params.confirmButtonText) {\n    $confirmBtn.innerHTML = _hasClass$addClass$removeClass$escapeHtml$_show$show$_hide$hide.escapeHtml(params.confirmButtonText);\n  }\n\n  /*\n   * Custom color on confirm button\n   */\n  if (params.confirmButtonColor) {\n    // Set confirm button to selected background color\n    $confirmBtn.style.backgroundColor = params.confirmButtonColor;\n\n    // Set the confirm button color to the loading ring\n    $confirmBtn.style.borderLeftColor = params.confirmLoadingButtonColor;\n    $confirmBtn.style.borderRightColor = params.confirmLoadingButtonColor;\n\n    // Set box-shadow to default focused button\n    _getModal$getInput$setFocusStyle.setFocusStyle($confirmBtn, params.confirmButtonColor);\n  }\n\n  /*\n   * Allow outside click\n   */\n  modal.setAttribute('data-allow-outside-click', params.allowOutsideClick);\n\n  /*\n   * Callback function\n   */\n  var hasDoneFunction = params.doneFunction ? true : false;\n  modal.setAttribute('data-has-done-function', hasDoneFunction);\n\n  /*\n   * Animation\n   */\n  if (!params.animation) {\n    modal.setAttribute('data-animation', 'none');\n  } else if (typeof params.animation === 'string') {\n    modal.setAttribute('data-animation', params.animation); // Custom animation\n  } else {\n    modal.setAttribute('data-animation', 'pop');\n  }\n\n  /*\n   * Timer\n   */\n  modal.setAttribute('data-timer', params.timer);\n};\n\nexports['default'] = setParameters;\nmodule.exports = exports['default'];\n\n},{\"./handle-dom\":4,\"./handle-swal-dom\":6,\"./utils\":9}],9:[function(require,module,exports){\n'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n  value: true\n});\n/*\n * Allow user to pass their own params\n */\nvar extend = function extend(a, b) {\n  for (var key in b) {\n    if (b.hasOwnProperty(key)) {\n      a[key] = b[key];\n    }\n  }\n  return a;\n};\n\n/*\n * Convert HEX codes to RGB values (#000000 -> rgb(0,0,0))\n */\nvar hexToRgb = function hexToRgb(hex) {\n  var result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n  return result ? parseInt(result[1], 16) + ', ' + parseInt(result[2], 16) + ', ' + parseInt(result[3], 16) : null;\n};\n\n/*\n * Check if the user is using Internet Explorer 8 (for fallbacks)\n */\nvar isIE8 = function isIE8() {\n  return window.attachEvent && !window.addEventListener;\n};\n\n/*\n * IE compatible logging for developers\n */\nvar logStr = function logStr(string) {\n  if (window.console) {\n    // IE...\n    window.console.log('SweetAlert: ' + string);\n  }\n};\n\n/*\n * Set hover, active and focus-states for buttons \n * (source: http://www.sitepoint.com/javascript-generate-lighter-darker-color)\n */\nvar colorLuminance = function colorLuminance(hex, lum) {\n  // Validate hex string\n  hex = String(hex).replace(/[^0-9a-f]/gi, '');\n  if (hex.length < 6) {\n    hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];\n  }\n  lum = lum || 0;\n\n  // Convert to decimal and change luminosity\n  var rgb = '#';\n  var c;\n  var i;\n\n  for (i = 0; i < 3; i++) {\n    c = parseInt(hex.substr(i * 2, 2), 16);\n    c = Math.round(Math.min(Math.max(0, c + c * lum), 255)).toString(16);\n    rgb += ('00' + c).substr(c.length);\n  }\n\n  return rgb;\n};\n\nexports.extend = extend;\nexports.hexToRgb = hexToRgb;\nexports.isIE8 = isIE8;\nexports.logStr = logStr;\nexports.colorLuminance = colorLuminance;\n\n},{}]},{},[1])\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvVHJpc3Rhbi9kZXYvU3dlZXRBbGVydC9kZXYvc3dlZXRhbGVydC5lczYuanMiLCIvVXNlcnMvVHJpc3Rhbi9kZXYvU3dlZXRBbGVydC9kZXYvbW9kdWxlcy9kZWZhdWx0LXBhcmFtcy5qcyIsIi9Vc2Vycy9UcmlzdGFuL2Rldi9Td2VldEFsZXJ0L2Rldi9tb2R1bGVzL2hhbmRsZS1jbGljay5qcyIsIi9Vc2Vycy9UcmlzdGFuL2Rldi9Td2VldEFsZXJ0L2Rldi9tb2R1bGVzL2hhbmRsZS1kb20uanMiLCIvVXNlcnMvVHJpc3Rhbi9kZXYvU3dlZXRBbGVydC9kZXYvbW9kdWxlcy9oYW5kbGUta2V5LmpzIiwiL1VzZXJzL1RyaXN0YW4vZGV2L1N3ZWV0QWxlcnQvZGV2L21vZHVsZXMvaGFuZGxlLXN3YWwtZG9tLmpzIiwiL1VzZXJzL1RyaXN0YW4vZGV2L1N3ZWV0QWxlcnQvZGV2L21vZHVsZXMvaW5qZWN0ZWQtaHRtbC5qcyIsIi9Vc2Vycy9UcmlzdGFuL2Rldi9Td2VldEFsZXJ0L2Rldi9tb2R1bGVzL3NldC1wYXJhbXMuanMiLCIvVXNlcnMvVHJpc3Rhbi9kZXYvU3dlZXRBbGVydC9kZXYvbW9kdWxlcy91dGlscy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7OztzSkNnQk8sc0JBQXNCOzs7Ozs7MkRBV3RCLGlCQUFpQjs7Ozs7O3dIQWNqQiwyQkFBMkI7Ozs7dURBSXdCLHdCQUF3Qjs7NkJBQ3hELHNCQUFzQjs7Ozs7OzZCQUl0QiwwQkFBMEI7Ozs7NkJBQzFCLHNCQUFzQjs7Ozs7Ozs7QUFNaEQsSUFBSSxxQkFBcUIsQ0FBQztBQUMxQixJQUFJLGlCQUFpQixDQUFDOzs7Ozs7QUFPdEIsSUFBSSxVQUFVLEVBQUUsSUFBSSxDQUFDOztBQUVyQixVQUFVLEdBQUcsSUFBSSxHQUFHLFlBQVc7QUFDN0IsTUFBSSxjQUFjLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDOztBQUVsQywwSUE5RFUsUUFBUSxDQThEVCxRQUFRLENBQUMsSUFBSSxFQUFFLGdCQUFnQixDQUFDLENBQUM7QUFDMUMsNEdBaENBLFVBQVUsRUFnQ0UsQ0FBQzs7Ozs7OztBQU9iLFdBQVMsaUJBQWlCLENBQUMsR0FBRyxFQUFFO0FBQzlCLFFBQUksSUFBSSxHQUFHLGNBQWMsQ0FBQztBQUMxQixXQUFPLEFBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLFNBQVMsR0FBSywyQkFBYyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7R0FDcEU7O0FBRUQsTUFBSSxjQUFjLEtBQUssU0FBUyxFQUFFO0FBQ2hDLGlEQTNERixNQUFNLENBMkRHLDBDQUEwQyxDQUFDLENBQUM7QUFDbkQsV0FBTyxLQUFLLENBQUM7R0FDZDs7QUFFRCxNQUFJLE1BQU0sR0FBRyw2Q0FsRWIsTUFBTSxDQWtFYyxFQUFFLDZCQUFnQixDQUFDOztBQUV2QyxVQUFRLE9BQU8sY0FBYzs7O0FBRzNCLFNBQUssUUFBUTtBQUNYLFlBQU0sQ0FBQyxLQUFLLEdBQUcsY0FBYyxDQUFDO0FBQzlCLFlBQU0sQ0FBQyxJQUFJLEdBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNsQyxZQUFNLENBQUMsSUFBSSxHQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDbEMsWUFBTTs7QUFBQTtBQUdSLFNBQUssUUFBUTtBQUNYLFVBQUksY0FBYyxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQUU7QUFDdEMscURBN0VOLE1BQU0sQ0E2RU8sMkJBQTJCLENBQUMsQ0FBQztBQUNwQyxlQUFPLEtBQUssQ0FBQztPQUNkOztBQUVELFlBQU0sQ0FBQyxLQUFLLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQzs7QUFFcEMsV0FBSyxJQUFJLFVBQVUsZ0NBQW1CO0FBQ3BDLGNBQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztPQUNwRDs7O0FBR0QsWUFBTSxDQUFDLGlCQUFpQixHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsR0FBRyxTQUFTLEdBQUcsMkJBQWMsaUJBQWlCLENBQUM7QUFDakcsWUFBTSxDQUFDLGlCQUFpQixHQUFHLGlCQUFpQixDQUFDLG1CQUFtQixDQUFDLENBQUM7OztBQUdsRSxZQUFNLENBQUMsWUFBWSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUM7O0FBRTNDLFlBQU07O0FBQUEsQUFFUjtBQUNFLG1EQWpHSixNQUFNLENBaUdLLGtFQUFrRSxHQUFHLE9BQU8sY0FBYyxDQUFDLENBQUM7QUFDbkcsYUFBTyxLQUFLLENBQUM7O0FBQUEsR0FFaEI7O0FBRUQsNkJBQWMsTUFBTSxDQUFDLENBQUM7QUFDdEIsNEdBeEZBLG1CQUFtQixFQXdGRSxDQUFDO0FBQ3RCLDRHQTNGQSxTQUFTLENBMkZDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDOzs7QUFHeEIsTUFBSSxLQUFLLEdBQUcsMEdBbEdaLFFBQVEsRUFrR2MsQ0FBQzs7Ozs7QUFNdkIsTUFBSSxRQUFRLEdBQUcsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ2hELE1BQUksWUFBWSxHQUFHLENBQUMsU0FBUyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLFdBQVcsRUFBRSxTQUFTLENBQUMsQ0FBQztBQUNuRyxNQUFJLGFBQWEsR0FBRyx1QkFBQyxDQUFDO1dBQUsseUNBL0ZwQixZQUFZLENBK0ZxQixDQUFDLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQztHQUFBLENBQUM7O0FBRTFELE9BQUssSUFBSSxRQUFRLEdBQUcsQ0FBQyxFQUFFLFFBQVEsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxFQUFFO0FBQzdELFNBQUssSUFBSSxRQUFRLEdBQUcsQ0FBQyxFQUFFLFFBQVEsR0FBRyxZQUFZLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxFQUFFO0FBQ2pFLFVBQUksTUFBTSxHQUFHLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNwQyxjQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsYUFBYSxDQUFDO0tBQzVDO0dBQ0Y7OztBQUdELDRHQW5IQSxVQUFVLEVBbUhFLENBQUMsT0FBTyxHQUFHLGFBQWEsQ0FBQzs7QUFFckMsdUJBQXFCLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQzs7QUFFekMsTUFBSSxVQUFVLEdBQUcsb0JBQUMsQ0FBQztXQUFLLDJCQUFjLENBQUMsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDO0dBQUEsQ0FBQztBQUN4RCxRQUFNLENBQUMsU0FBUyxHQUFHLFVBQVUsQ0FBQzs7QUFFOUIsUUFBTSxDQUFDLE9BQU8sR0FBRyxZQUFZOztBQUUzQixjQUFVLENBQUMsWUFBWTs7O0FBR3JCLFVBQUksaUJBQWlCLEtBQUssU0FBUyxFQUFFO0FBQ25DLHlCQUFpQixDQUFDLEtBQUssRUFBRSxDQUFDO0FBQzFCLHlCQUFpQixHQUFHLFNBQVMsQ0FBQztPQUMvQjtLQUNGLEVBQUUsQ0FBQyxDQUFDLENBQUM7R0FDUCxDQUFDOzs7QUFHRixNQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7Q0FDdEIsQ0FBQzs7Ozs7O0FBUUYsVUFBVSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVMsVUFBVSxFQUFFO0FBQy9ELE1BQUksQ0FBQyxVQUFVLEVBQUU7QUFDZixVQUFNLElBQUksS0FBSyxDQUFDLHdCQUF3QixDQUFDLENBQUM7R0FDM0M7QUFDRCxNQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsRUFBRTtBQUNsQyxVQUFNLElBQUksS0FBSyxDQUFDLCtCQUErQixDQUFDLENBQUM7R0FDbEQ7O0FBRUQsK0NBcktBLE1BQU0sNkJBcUtnQixVQUFVLENBQUMsQ0FBQztDQUNuQyxDQUFDOzs7OztBQU1GLFVBQVUsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRyxZQUFXO0FBQ3pDLE1BQUksS0FBSyxHQUFHLDBHQWpLWixRQUFRLEVBaUtjLENBQUM7O0FBRXZCLDBJQXhMUSxPQUFPLENBd0xQLDBHQWxLUixVQUFVLEVBa0tVLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDekIsMElBekxRLE9BQU8sQ0F5TFAsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLDBJQS9Mb0IsV0FBVyxDQStMbkIsS0FBSyxFQUFFLGdCQUFnQixDQUFDLENBQUM7QUFDckMsMElBaE1VLFFBQVEsQ0FnTVQsS0FBSyxFQUFFLGdCQUFnQixDQUFDLENBQUM7QUFDbEMsMElBak1vQixXQUFXLENBaU1uQixLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7Ozs7O0FBSzlCLE1BQUksWUFBWSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMscUJBQXFCLENBQUMsQ0FBQztBQUM5RCwwSUF2TW9CLFdBQVcsQ0F1TW5CLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztBQUNyQywwSUF4TW9CLFdBQVcsQ0F3TW5CLFlBQVksQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztBQUN4RSwwSUF6TW9CLFdBQVcsQ0F5TW5CLFlBQVksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLEVBQUUsb0JBQW9CLENBQUMsQ0FBQzs7QUFFMUUsTUFBSSxVQUFVLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0FBQzFELDBJQTVNb0IsV0FBVyxDQTRNbkIsVUFBVSxFQUFFLGtCQUFrQixDQUFDLENBQUM7QUFDNUMsMElBN01vQixXQUFXLENBNk1uQixVQUFVLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDOztBQUVwRSxNQUFJLFlBQVksR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLHFCQUFxQixDQUFDLENBQUM7QUFDOUQsMElBaE5vQixXQUFXLENBZ05uQixZQUFZLEVBQUUsY0FBYyxDQUFDLENBQUM7QUFDMUMsMElBak5vQixXQUFXLENBaU5uQixZQUFZLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUM7QUFDdkUsMElBbE5vQixXQUFXLENBa05uQixZQUFZLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUM7OztBQUd0RSxZQUFVLENBQUMsWUFBVztBQUNwQixRQUFJLFdBQVcsR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLG1CQUFtQixDQUFDLENBQUM7QUFDMUQsNElBdk5rQixXQUFXLENBdU5qQixLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7R0FDakMsRUFBRSxHQUFHLENBQUMsQ0FBQzs7O0FBR1IsMElBM05vQixXQUFXLENBMk5uQixRQUFRLENBQUMsSUFBSSxFQUFFLGdCQUFnQixDQUFDLENBQUM7OztBQUc3QyxRQUFNLENBQUMsU0FBUyxHQUFHLHFCQUFxQixDQUFDO0FBQ3pDLE1BQUksTUFBTSxDQUFDLHFCQUFxQixFQUFFO0FBQ2hDLFVBQU0sQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztHQUN0QztBQUNELG1CQUFpQixHQUFHLFNBQVMsQ0FBQztBQUM5QixjQUFZLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDOztBQUU1QixTQUFPLElBQUksQ0FBQztDQUNiLENBQUM7Ozs7OztBQU9GLFVBQVUsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGNBQWMsR0FBRyxVQUFTLFlBQVksRUFBRTtBQUN2RSxNQUFJLEtBQUssR0FBRywwR0FwTlosUUFBUSxFQW9OYyxDQUFDOztBQUV2QixNQUFJLFVBQVUsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFDeEQsMElBalBVLFFBQVEsQ0FpUFQsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDOztBQUU3QixNQUFJLGVBQWUsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLHFCQUFxQixDQUFDLENBQUM7QUFDakUsMElBcFBVLFFBQVEsQ0FvUFQsZUFBZSxFQUFFLE1BQU0sQ0FBQyxDQUFDOztBQUVsQyxpQkFBZSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLEdBQUcsWUFBWSxDQUFDOztBQUU1RCxZQUFVLENBQUMsWUFBVztBQUNwQixjQUFVLENBQUMsYUFBYSxFQUFFLENBQUM7R0FDNUIsRUFBRSxDQUFDLENBQUMsQ0FBQzs7QUFFTixPQUFLLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO0NBQ3RDLENBQUM7Ozs7O0FBTUYsVUFBVSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsZUFBZSxHQUFHLFVBQVMsS0FBSyxFQUFFOztBQUVsRSxNQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsT0FBTyxLQUFLLEVBQUUsRUFBRTtBQUNqQyxXQUFPLEtBQUssQ0FBQztHQUNkOztBQUVELE1BQUksTUFBTSxHQUFHLDBHQS9PYixRQUFRLEVBK09lLENBQUM7O0FBRXhCLE1BQUksVUFBVSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQUN6RCwwSUE1UW9CLFdBQVcsQ0E0UW5CLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQzs7QUFFaEMsTUFBSSxlQUFlLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0FBQ2xFLDBJQS9Rb0IsV0FBVyxDQStRbkIsZUFBZSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0NBQ3RDLENBQUM7Ozs7O0FBS0YsVUFBVSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsY0FBYyxHQUFHLFVBQVMsS0FBSyxFQUFFO0FBQ2hFLE1BQUksS0FBSyxHQUFHLDBHQTVQWixRQUFRLEVBNFBjLENBQUM7QUFDdkIsTUFBSSxjQUFjLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBQzNELE1BQUksYUFBYSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDekQsZ0JBQWMsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQy9CLGVBQWEsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO0NBQy9CLENBQUM7Ozs7O0FBS0YsVUFBVSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxHQUFHLFVBQVMsS0FBSyxFQUFFO0FBQzlELE1BQUksS0FBSyxHQUFHLDBHQXZRWixRQUFRLEVBdVFjLENBQUM7QUFDdkIsTUFBSSxjQUFjLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBQzNELE1BQUksYUFBYSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDekQsZ0JBQWMsQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO0FBQ2hDLGVBQWEsQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO0NBQ2hDLENBQUM7O0FBRUYsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUU7OztBQUdqQyxRQUFNLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxJQUFJLEdBQUcsVUFBVSxDQUFDO0NBQzlDLE1BQU07QUFDTCwrQ0E1UkEsTUFBTSxDQTRSQyxrQ0FBa0MsQ0FBQyxDQUFDO0NBQzVDOzs7Ozs7OztBQ3RURCxJQUFJLGFBQWEsR0FBRztBQUNsQixPQUFLLEVBQUUsRUFBRTtBQUNULE1BQUksRUFBRSxFQUFFO0FBQ1IsTUFBSSxFQUFFLElBQUk7QUFDVixtQkFBaUIsRUFBRSxLQUFLO0FBQ3hCLG1CQUFpQixFQUFFLElBQUk7QUFDdkIsa0JBQWdCLEVBQUUsS0FBSztBQUN2QixnQkFBYyxFQUFFLElBQUk7QUFDcEIsZUFBYSxFQUFFLElBQUk7QUFDbkIsbUJBQWlCLEVBQUUsSUFBSTtBQUN2QixvQkFBa0IsRUFBRSxTQUFTO0FBQzdCLGtCQUFnQixFQUFFLFFBQVE7QUFDMUIsVUFBUSxFQUFFLElBQUk7QUFDZCxXQUFTLEVBQUUsSUFBSTtBQUNmLE9BQUssRUFBRSxJQUFJO0FBQ1gsYUFBVyxFQUFFLEVBQUU7QUFDZixNQUFJLEVBQUUsS0FBSztBQUNYLFdBQVMsRUFBRSxJQUFJO0FBQ2YsZ0JBQWMsRUFBRSxJQUFJO0FBQ3BCLFdBQVMsRUFBRSxNQUFNO0FBQ2pCLGtCQUFnQixFQUFFLEVBQUU7QUFDcEIsWUFBVSxFQUFFLEVBQUU7QUFDZCxxQkFBbUIsRUFBRSxLQUFLO0NBQzNCLENBQUM7O3FCQUVhLGFBQWE7Ozs7Ozs7Ozs7OEJDekJHLFNBQVM7O3dCQUNmLG1CQUFtQjs7cUNBQ0wsY0FBYzs7Ozs7QUFNckQsSUFBSSxZQUFZLEdBQUcsc0JBQVMsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7QUFDaEQsTUFBSSxDQUFDLEdBQUcsS0FBSyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUM7QUFDOUIsTUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDOztBQUV0QyxNQUFJLGVBQWUsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNqRSxNQUFJLGVBQWUsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUN2RSxNQUFJLGNBQWMsR0FBSSx1QkFaZixRQUFRLENBWWdCLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztBQUNqRCxNQUFJLGtCQUFrQixHQUFJLE1BQU0sQ0FBQyxZQUFZLElBQUksS0FBSyxDQUFDLFlBQVksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLE1BQU0sQUFBQyxDQUFDOzs7O0FBSTFHLE1BQUksV0FBVyxFQUFFLFVBQVUsRUFBRSxXQUFXLENBQUM7QUFDekMsTUFBSSxlQUFlLElBQUksTUFBTSxDQUFDLGtCQUFrQixFQUFFO0FBQ2hELGVBQVcsR0FBSSxNQUFNLENBQUMsa0JBQWtCLENBQUM7QUFDekMsY0FBVSxHQUFLLGdCQXRCVixjQUFjLENBc0JXLFdBQVcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2xELGVBQVcsR0FBSSxnQkF2QlYsY0FBYyxDQXVCVyxXQUFXLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztHQUNuRDs7QUFFRCxXQUFTLDJCQUEyQixDQUFDLEtBQUssRUFBRTtBQUMxQyxRQUFJLGVBQWUsSUFBSSxNQUFNLENBQUMsa0JBQWtCLEVBQUU7QUFDaEQsWUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO0tBQ3RDO0dBQ0Y7O0FBRUQsVUFBUSxDQUFDLENBQUMsSUFBSTtBQUNaLFNBQUssV0FBVztBQUNkLGlDQUEyQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3hDLFlBQU07O0FBQUEsQUFFUixTQUFLLFVBQVU7QUFDYixpQ0FBMkIsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUN6QyxZQUFNOztBQUFBLEFBRVIsU0FBSyxXQUFXO0FBQ2QsaUNBQTJCLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekMsWUFBTTs7QUFBQSxBQUVSLFNBQUssU0FBUztBQUNaLGlDQUEyQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3hDLFlBQU07O0FBQUEsQUFFUixTQUFLLE9BQU87QUFDVixVQUFJLGNBQWMsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFDM0QsVUFBSSxhQUFhLEdBQUksS0FBSyxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsQ0FBQzs7QUFFMUQsVUFBSSxlQUFlLEVBQUU7QUFDbkIscUJBQWEsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQztPQUN4QyxNQUFNO0FBQ0wsc0JBQWMsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQztPQUN6QztBQUNELFlBQU07O0FBQUEsQUFFUixTQUFLLE9BQU87QUFDVixVQUFJLGNBQWMsR0FBSSxLQUFLLEtBQUssTUFBTSxBQUFDLENBQUM7QUFDeEMsVUFBSSxtQkFBbUIsR0FBRyx1QkE1RGIsWUFBWSxDQTREYyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7OztBQUd0RCxVQUFJLENBQUMsY0FBYyxJQUFJLENBQUMsbUJBQW1CLElBQUksY0FBYyxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixFQUFFO0FBQzFGLGNBQU07T0FDUDs7QUFFRCxVQUFJLGVBQWUsSUFBSSxrQkFBa0IsSUFBSSxjQUFjLEVBQUU7QUFDM0QscUJBQWEsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7T0FDOUIsTUFBTSxJQUFJLGtCQUFrQixJQUFJLGNBQWMsSUFBSSxlQUFlLEVBQUU7QUFDbEUsb0JBQVksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7T0FDN0IsTUFBTSxJQUFJLHVCQXZFRSxZQUFZLENBdUVELEtBQUssRUFBRSxNQUFNLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxLQUFLLFFBQVEsRUFBRTtBQUNyRSxrQkFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO09BQ3BCO0FBQ0QsWUFBTTtBQUFBLEdBQ1Q7Q0FDRixDQUFDOzs7OztBQUtGLElBQUksYUFBYSxHQUFHLHVCQUFTLEtBQUssRUFBRSxNQUFNLEVBQUU7QUFDMUMsTUFBSSxhQUFhLEdBQUcsSUFBSSxDQUFDOztBQUV6QixNQUFJLHVCQXBGRyxRQUFRLENBb0ZGLEtBQUssRUFBRSxZQUFZLENBQUMsRUFBRTtBQUNqQyxpQkFBYSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDOztBQUVuRCxRQUFJLENBQUMsYUFBYSxFQUFFO0FBQ2xCLG1CQUFhLEdBQUcsRUFBRSxDQUFDO0tBQ3BCO0dBQ0Y7O0FBRUQsUUFBTSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQzs7QUFFbkMsTUFBSSxNQUFNLENBQUMsY0FBYyxFQUFFO0FBQ3pCLGNBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztHQUNwQjs7QUFFRCxNQUFJLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRTtBQUM5QixjQUFVLENBQUMsY0FBYyxFQUFFLENBQUM7R0FDN0I7Q0FDRixDQUFDOzs7OztBQUtGLElBQUksWUFBWSxHQUFHLHNCQUFTLEtBQUssRUFBRSxNQUFNLEVBQUU7O0FBRXpDLE1BQUksYUFBYSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNuRSxNQUFJLHFCQUFxQixHQUFHLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLFdBQVcsSUFBSSxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsS0FBSyxHQUFHLENBQUM7O0FBRXBILE1BQUkscUJBQXFCLEVBQUU7QUFDekIsVUFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztHQUM1Qjs7QUFFRCxNQUFJLE1BQU0sQ0FBQyxhQUFhLEVBQUU7QUFDeEIsY0FBVSxDQUFDLEtBQUssRUFBRSxDQUFDO0dBQ3BCO0NBQ0YsQ0FBQzs7cUJBR2E7QUFDYixjQUFZLEVBQVosWUFBWTtBQUNaLGVBQWEsRUFBYixhQUFhO0FBQ2IsY0FBWSxFQUFaLFlBQVk7Q0FDYjs7Ozs7Ozs7O0FDL0hELElBQUksUUFBUSxHQUFHLGtCQUFTLElBQUksRUFBRSxTQUFTLEVBQUU7QUFDdkMsU0FBTyxJQUFJLE1BQU0sQ0FBQyxHQUFHLEdBQUcsU0FBUyxHQUFHLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxHQUFHLENBQUMsQ0FBQztDQUMzRSxDQUFDOztBQUVGLElBQUksUUFBUSxHQUFHLGtCQUFTLElBQUksRUFBRSxTQUFTLEVBQUU7QUFDdkMsTUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLEVBQUU7QUFDOUIsUUFBSSxDQUFDLFNBQVMsSUFBSSxHQUFHLEdBQUcsU0FBUyxDQUFDO0dBQ25DO0NBQ0YsQ0FBQzs7QUFFRixJQUFJLFdBQVcsR0FBRyxxQkFBUyxJQUFJLEVBQUUsU0FBUyxFQUFFO0FBQzFDLE1BQUksUUFBUSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ3BFLE1BQUksUUFBUSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsRUFBRTtBQUM3QixXQUFPLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxHQUFHLFNBQVMsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7QUFDbkQsY0FBUSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxHQUFHLFNBQVMsR0FBRyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7S0FDekQ7QUFDRCxRQUFJLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0dBQ3JEO0NBQ0YsQ0FBQzs7QUFFRixJQUFJLFVBQVUsR0FBRyxvQkFBUyxHQUFHLEVBQUU7QUFDN0IsTUFBSSxHQUFHLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN4QyxLQUFHLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUM5QyxTQUFPLEdBQUcsQ0FBQyxTQUFTLENBQUM7Q0FDdEIsQ0FBQzs7QUFFRixJQUFJLEtBQUssR0FBRyxlQUFTLElBQUksRUFBRTtBQUN6QixNQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7QUFDeEIsTUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0NBQzlCLENBQUM7O0FBRUYsSUFBSSxJQUFJLEdBQUcsY0FBUyxLQUFLLEVBQUU7QUFDekIsTUFBSSxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFO0FBQzFCLFdBQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0dBQ3JCO0FBQ0QsT0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUU7QUFDckMsU0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0dBQ2pCO0NBQ0YsQ0FBQzs7QUFFRixJQUFJLEtBQUssR0FBRyxlQUFTLElBQUksRUFBRTtBQUN6QixNQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7QUFDeEIsTUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO0NBQzdCLENBQUM7O0FBRUYsSUFBSSxJQUFJLEdBQUcsY0FBUyxLQUFLLEVBQUU7QUFDekIsTUFBSSxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFO0FBQzFCLFdBQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0dBQ3JCO0FBQ0QsT0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUU7QUFDckMsU0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0dBQ2pCO0NBQ0YsQ0FBQzs7QUFFRixJQUFJLFlBQVksR0FBRyxzQkFBUyxNQUFNLEVBQUUsS0FBSyxFQUFFO0FBQ3pDLE1BQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUM7QUFDNUIsU0FBTyxJQUFJLEtBQUssSUFBSSxFQUFFO0FBQ3BCLFFBQUksSUFBSSxLQUFLLE1BQU0sRUFBRTtBQUNuQixhQUFPLElBQUksQ0FBQztLQUNiO0FBQ0QsUUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7R0FDeEI7QUFDRCxTQUFPLEtBQUssQ0FBQztDQUNkLENBQUM7O0FBRUYsSUFBSSxZQUFZLEdBQUcsc0JBQVMsSUFBSSxFQUFFO0FBQ2hDLE1BQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLFNBQVMsQ0FBQztBQUM1QixNQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7O0FBRTdCLE1BQUksTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZO01BQzFCLE9BQU8sQ0FBQztBQUNaLE1BQUksT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLEVBQUU7O0FBQzNDLFdBQU8sR0FBRyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7R0FDaEYsTUFBTTtBQUNMLFdBQU8sR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztHQUMvQzs7QUFFRCxNQUFJLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxFQUFFLENBQUM7QUFDckIsTUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO0FBQzVCLFNBQVEsR0FBRyxHQUFHLFFBQVEsQ0FBQyxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUEsR0FBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUU7Q0FDeEQsQ0FBQzs7QUFFRixJQUFJLE1BQU0sR0FBRyxnQkFBUyxJQUFJLEVBQUUsUUFBUSxFQUFFO0FBQ3BDLE1BQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxDQUFDLEVBQUU7QUFDM0IsWUFBUSxHQUFHLFFBQVEsSUFBSSxFQUFFLENBQUM7QUFDMUIsUUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZCLFFBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztBQUM3QixRQUFJLElBQUksR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7QUFDdkIsUUFBSSxJQUFJOzs7Ozs7Ozs7O09BQUcsWUFBVztBQUNwQixVQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUEsR0FBSSxHQUFHLENBQUM7QUFDckUsVUFBSSxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQzs7QUFFbkIsVUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLENBQUMsRUFBRTtBQUMzQixrQkFBVSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztPQUM1QjtLQUNGLENBQUEsQ0FBQztBQUNGLFFBQUksRUFBRSxDQUFDO0dBQ1I7QUFDRCxNQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7Q0FDOUIsQ0FBQzs7QUFFRixJQUFJLE9BQU8sR0FBRyxpQkFBUyxJQUFJLEVBQUUsUUFBUSxFQUFFO0FBQ3JDLFVBQVEsR0FBRyxRQUFRLElBQUksRUFBRSxDQUFDO0FBQzFCLE1BQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztBQUN2QixNQUFJLElBQUksR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7QUFDdkIsTUFBSSxJQUFJOzs7Ozs7Ozs7O0tBQUcsWUFBVztBQUNwQixRQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUEsR0FBSSxHQUFHLENBQUM7QUFDckUsUUFBSSxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQzs7QUFFbkIsUUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLENBQUMsRUFBRTtBQUMzQixnQkFBVSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztLQUM1QixNQUFNO0FBQ0wsVUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO0tBQzdCO0dBQ0YsQ0FBQSxDQUFDO0FBQ0YsTUFBSSxFQUFFLENBQUM7Q0FDUixDQUFDOztBQUVGLElBQUksU0FBUyxHQUFHLG1CQUFTLElBQUksRUFBRTs7O0FBRzdCLE1BQUksT0FBTyxVQUFVLEtBQUssVUFBVSxFQUFFOztBQUVwQyxRQUFJLElBQUksR0FBRyxJQUFJLFVBQVUsQ0FBQyxPQUFPLEVBQUU7QUFDakMsVUFBSSxFQUFFLE1BQU07QUFDWixhQUFPLEVBQUUsS0FBSztBQUNkLGdCQUFVLEVBQUUsSUFBSTtLQUNqQixDQUFDLENBQUM7QUFDSCxRQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO0dBQzFCLE1BQU0sSUFBSyxRQUFRLENBQUMsV0FBVyxFQUFHOztBQUVqQyxRQUFJLEdBQUcsR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQzlDLE9BQUcsQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNyQyxRQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0dBQ3pCLE1BQU0sSUFBSSxRQUFRLENBQUMsaUJBQWlCLEVBQUU7QUFDckMsUUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBRTtHQUM1QixNQUFNLElBQUksT0FBTyxJQUFJLENBQUMsT0FBTyxLQUFLLFVBQVUsRUFBRztBQUM5QyxRQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7R0FDaEI7Q0FDRixDQUFDOztBQUVGLElBQUksb0JBQW9CLEdBQUcsOEJBQVMsQ0FBQyxFQUFFOztBQUVyQyxNQUFJLE9BQU8sQ0FBQyxDQUFDLGVBQWUsS0FBSyxVQUFVLEVBQUU7QUFDM0MsS0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO0FBQ3BCLEtBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztHQUNwQixNQUFNLElBQUksTUFBTSxDQUFDLEtBQUssSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsRUFBRTtBQUN0RSxVQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7R0FDbEM7Q0FDRixDQUFDOztRQUdBLFFBQVEsR0FBUixRQUFRO1FBQUUsUUFBUSxHQUFSLFFBQVE7UUFBRSxXQUFXLEdBQVgsV0FBVztRQUMvQixVQUFVLEdBQVYsVUFBVTtRQUNWLEtBQUssR0FBTCxLQUFLO1FBQUUsSUFBSSxHQUFKLElBQUk7UUFBRSxLQUFLLEdBQUwsS0FBSztRQUFFLElBQUksR0FBSixJQUFJO1FBQ3hCLFlBQVksR0FBWixZQUFZO1FBQ1osWUFBWSxHQUFaLFlBQVk7UUFDWixNQUFNLEdBQU4sTUFBTTtRQUFFLE9BQU8sR0FBUCxPQUFPO1FBQ2YsU0FBUyxHQUFULFNBQVM7UUFDVCxvQkFBb0IsR0FBcEIsb0JBQW9COzs7Ozs7Ozs7OENDL0owQixjQUFjOzs2QkFDaEMsbUJBQW1COztBQUdqRCxJQUFJLGFBQWEsR0FBRyx1QkFBUyxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtBQUNqRCxNQUFJLENBQUMsR0FBRyxLQUFLLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQztBQUM5QixNQUFJLE9BQU8sR0FBRyxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUM7O0FBRW5DLE1BQUksU0FBUyxHQUFPLEtBQUssQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztBQUMxRCxNQUFJLGFBQWEsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBQ3pELE1BQUksYUFBYSxHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDOztBQUcvRCxNQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFOztBQUUzQyxXQUFPO0dBQ1I7O0FBRUQsTUFBSSxjQUFjLEdBQUcsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDOztBQUU5QyxNQUFJLFFBQVEsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNsQixPQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUM3QyxRQUFJLGNBQWMsS0FBSyxhQUFhLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDdkMsY0FBUSxHQUFHLENBQUMsQ0FBQztBQUNiLFlBQU07S0FDUDtHQUNGOztBQUVELE1BQUksT0FBTyxLQUFLLENBQUMsRUFBRTs7QUFFakIsUUFBSSxRQUFRLEtBQUssQ0FBQyxDQUFDLEVBQUU7O0FBRW5CLG9CQUFjLEdBQUcsU0FBUyxDQUFDO0tBQzVCLE1BQU07O0FBRUwsVUFBSSxRQUFRLEtBQUssYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7QUFDekMsc0JBQWMsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7T0FDbkMsTUFBTTtBQUNMLHNCQUFjLEdBQUcsYUFBYSxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUMsQ0FBQztPQUM5QztLQUNGOztBQUVELG9DQTFDSyxvQkFBb0IsQ0EwQ0osQ0FBQyxDQUFDLENBQUM7QUFDeEIsa0JBQWMsQ0FBQyxLQUFLLEVBQUUsQ0FBQzs7QUFFdkIsUUFBSSxNQUFNLENBQUMsa0JBQWtCLEVBQUU7QUFDN0IscUJBN0NHLGFBQWEsQ0E2Q0YsY0FBYyxFQUFFLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0tBQzFEO0dBQ0YsTUFBTTtBQUNMLFFBQUksT0FBTyxLQUFLLEVBQUUsRUFBRTtBQUNsQixVQUFJLGNBQWMsQ0FBQyxPQUFPLEtBQUssT0FBTyxFQUFFO0FBQ3RDLHNCQUFjLEdBQUcsU0FBUyxDQUFDO0FBQzNCLGlCQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7T0FDbkI7O0FBRUQsVUFBSSxRQUFRLEtBQUssQ0FBQyxDQUFDLEVBQUU7O0FBRW5CLHNCQUFjLEdBQUcsU0FBUyxDQUFDO09BQzVCLE1BQU07O0FBRUwsc0JBQWMsR0FBRyxTQUFTLENBQUM7T0FDNUI7S0FDRixNQUFNLElBQUksT0FBTyxLQUFLLEVBQUUsSUFBSSxNQUFNLENBQUMsY0FBYyxLQUFLLElBQUksRUFBRTtBQUMzRCxvQkFBYyxHQUFHLGFBQWEsQ0FBQztBQUMvQixzQ0FoRXlCLFNBQVMsQ0FnRXhCLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQztLQUM5QixNQUFNOztBQUVMLG9CQUFjLEdBQUcsU0FBUyxDQUFDO0tBQzVCO0dBQ0Y7Q0FDRixDQUFDOztxQkFFYSxhQUFhOzs7Ozs7Ozs7Ozs7d0JDeEVILFNBQVM7OzZEQUNnQyxjQUFjOzs2QkFDdEQsa0JBQWtCOzs7Ozs7Ozs0QkFRbkIsaUJBQWlCOzs7O0FBTjFDLElBQUksVUFBVSxHQUFLLGNBQWMsQ0FBQztBQUNsQyxJQUFJLFlBQVksR0FBRyxnQkFBZ0IsQ0FBQzs7QUFPcEMsSUFBSSxvQkFBb0IsR0FBRyxnQ0FBVztBQUNwQyxNQUFJLFNBQVMsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzlDLFdBQVMsQ0FBQyxTQUFTLDRCQUFlLENBQUM7OztBQUduQyxTQUFPLFNBQVMsQ0FBQyxVQUFVLEVBQUU7QUFDM0IsWUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0dBQ2pEO0NBQ0YsQ0FBQzs7Ozs7QUFLRixJQUFJLFFBQVE7Ozs7Ozs7Ozs7R0FBRyxZQUFXO0FBQ3hCLE1BQUksTUFBTSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7O0FBRWhELE1BQUksQ0FBQyxNQUFNLEVBQUU7QUFDWCx3QkFBb0IsRUFBRSxDQUFDO0FBQ3ZCLFVBQU0sR0FBRyxRQUFRLEVBQUUsQ0FBQztHQUNyQjs7QUFFRCxTQUFPLE1BQU0sQ0FBQztDQUNmLENBQUEsQ0FBQzs7Ozs7QUFLRixJQUFJLFFBQVEsR0FBRyxvQkFBVztBQUN4QixNQUFJLE1BQU0sR0FBRyxRQUFRLEVBQUUsQ0FBQztBQUN4QixNQUFJLE1BQU0sRUFBRTtBQUNWLFdBQU8sTUFBTSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztHQUN0QztDQUNGLENBQUM7Ozs7O0FBS0YsSUFBSSxVQUFVLEdBQUcsc0JBQVc7QUFDMUIsU0FBTyxRQUFRLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDO0NBQzdDLENBQUM7Ozs7O0FBS0YsSUFBSSxhQUFhLEdBQUcsdUJBQVMsT0FBTyxFQUFFLE9BQU8sRUFBRTtBQUM3QyxNQUFJLFFBQVEsR0FBRyxVQXpEUixRQUFRLENBeURTLE9BQU8sQ0FBQyxDQUFDO0FBQ2pDLFNBQU8sQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLGVBQWUsR0FBRyxRQUFRLEdBQUcsNkNBQTZDLENBQUM7Q0FDdEcsQ0FBQzs7Ozs7QUFLRixJQUFJLFNBQVMsR0FBRyxtQkFBUyxRQUFRLEVBQUU7QUFDakMsTUFBSSxNQUFNLEdBQUcsUUFBUSxFQUFFLENBQUM7QUFDeEIsaURBakVrQyxNQUFNLENBaUVqQyxVQUFVLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUN6QixpREFsRTBDLElBQUksQ0FrRXpDLE1BQU0sQ0FBQyxDQUFDO0FBQ2IsaURBbkVnRCxRQUFRLENBbUUvQyxNQUFNLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztBQUNuQyxpREFwRU8sV0FBVyxDQW9FTixNQUFNLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQzs7QUFFdEMsUUFBTSxDQUFDLHFCQUFxQixHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUM7QUFDdEQsTUFBSSxTQUFTLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBQ3ZELFdBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQzs7QUFFbEIsWUFBVSxDQUFDLFlBQVk7QUFDckIsbURBM0U4QyxRQUFRLENBMkU3QyxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7R0FDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQzs7QUFFUixNQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDOztBQUU5QyxNQUFJLEtBQUssS0FBSyxNQUFNLElBQUksS0FBSyxLQUFLLEVBQUUsRUFBRTtBQUNwQyxRQUFJLGFBQWEsR0FBRyxRQUFRLENBQUM7QUFDN0IsVUFBTSxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUMsWUFBVztBQUNyQyxVQUFJLGtCQUFrQixHQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQSxJQUFLLE1BQU0sQ0FBQyxZQUFZLENBQUMsd0JBQXdCLENBQUMsS0FBSyxNQUFNLEFBQUMsQ0FBQztBQUMvRyxVQUFJLGtCQUFrQixFQUFFO0FBQ3RCLHFCQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7T0FDckIsTUFDSTtBQUNILGtCQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7T0FDcEI7S0FDRixFQUFFLEtBQUssQ0FBQyxDQUFDO0dBQ1g7Q0FDRixDQUFDOzs7Ozs7QUFNRixJQUFJLFVBQVUsR0FBRyxzQkFBVztBQUMxQixNQUFJLE1BQU0sR0FBRyxRQUFRLEVBQUUsQ0FBQztBQUN4QixNQUFJLE1BQU0sR0FBRyxRQUFRLEVBQUUsQ0FBQzs7QUFFeEIsaURBdEdPLFdBQVcsQ0FzR04sTUFBTSxFQUFFLFlBQVksQ0FBQyxDQUFDO0FBQ2xDLFFBQU0sQ0FBQyxLQUFLLEdBQUcsMkJBQWMsVUFBVSxDQUFDO0FBQ3hDLFFBQU0sQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLDJCQUFjLFNBQVMsQ0FBQyxDQUFDO0FBQ3JELFFBQU0sQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLDJCQUFjLGdCQUFnQixDQUFDLENBQUM7O0FBRW5FLGlCQUFlLEVBQUUsQ0FBQztDQUNuQixDQUFDOztBQUdGLElBQUksZUFBZSxHQUFHLHlCQUFTLEtBQUssRUFBRTs7QUFFcEMsTUFBSSxLQUFLLElBQUksS0FBSyxDQUFDLE9BQU8sS0FBSyxFQUFFLEVBQUU7QUFDakMsV0FBTyxLQUFLLENBQUM7R0FDZDs7QUFFRCxNQUFJLE1BQU0sR0FBRyxRQUFRLEVBQUUsQ0FBQzs7QUFFeEIsTUFBSSxVQUFVLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBQ3pELGlEQXhITyxXQUFXLENBd0hOLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQzs7QUFFaEMsTUFBSSxlQUFlLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0FBQ2xFLGlEQTNITyxXQUFXLENBMkhOLGVBQWUsRUFBRSxNQUFNLENBQUMsQ0FBQztDQUN0QyxDQUFDOzs7OztBQU1GLElBQUksbUJBQW1CLEdBQUcsK0JBQVc7QUFDbkMsTUFBSSxNQUFNLEdBQUcsUUFBUSxFQUFFLENBQUM7QUFDeEIsUUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsK0NBcElMLFlBQVksQ0FvSU0sUUFBUSxFQUFFLENBQUMsQ0FBQztDQUNuRCxDQUFDOztRQUlBLG9CQUFvQixHQUFwQixvQkFBb0I7UUFDcEIsUUFBUSxHQUFSLFFBQVE7UUFDUixVQUFVLEdBQVYsVUFBVTtRQUNWLFFBQVEsR0FBUixRQUFRO1FBQ1IsYUFBYSxHQUFiLGFBQWE7UUFDYixTQUFTLEdBQVQsU0FBUztRQUNULFVBQVUsR0FBVixVQUFVO1FBQ1YsZUFBZSxHQUFmLGVBQWU7UUFDZixtQkFBbUIsR0FBbkIsbUJBQW1COzs7Ozs7OztBQ2xKckIsSUFBSSxZQUFZOzs7QUFHZDs7OzZCQUcyQjs7O2tNQVFsQjs7OzZIQU1BOzs7dUNBRzhCOzs7K05BUzlCLDRDQUVnQzs7OzRKQVEzQjs7OzRHQU1MOzs7cU5BTThDOzs7NklBUzlDOzs7UUFHRCxDQUFDOztxQkFFSSxZQUFZOzs7Ozs7Ozs7O3FCQ2hFcEIsU0FBUzs7K0NBTVQsbUJBQW1COzs4RUFNbkIsY0FBYzs7QUFoQnJCLElBQUksVUFBVSxHQUFHLENBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQzs7Ozs7QUFzQjVFLElBQUksYUFBYSxHQUFHLHVCQUFTLE1BQU0sRUFBRTtBQUNuQyxNQUFJLEtBQUssR0FBRyxpQ0FoQlosUUFBUSxFQWdCYyxDQUFDOztBQUV2QixNQUFJLE1BQU0sR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3ZDLE1BQUksS0FBSyxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDckMsTUFBSSxVQUFVLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUN0RCxNQUFJLFdBQVcsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLENBQUM7Ozs7O0FBS3hELFFBQU0sQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsS0FBSyxHQUFHLGdFQW5CaEQsVUFBVSxDQW1CaUQsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7Ozs7O0FBS2xHLE9BQUssQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxHQUFHLGdFQXhCOUMsVUFBVSxDQXdCK0MsTUFBTSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3JHLE1BQUksTUFBTSxDQUFDLElBQUksRUFBRSxnRUF4QlYsSUFBSSxDQXdCVyxLQUFLLENBQUMsQ0FBQzs7Ozs7QUFLN0IsTUFBSSxNQUFNLENBQUMsV0FBVyxFQUFFO0FBQ3RCLG9FQWhDUSxRQUFRLENBZ0NQLEtBQUssRUFBRSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDcEMsU0FBSyxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsRUFBRSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7R0FDN0QsTUFBTTs7QUFFTCxRQUFJLFdBQVcsR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLG1CQUFtQixDQUFDLENBQUM7QUFDMUQsb0VBckNrQixXQUFXLENBcUNqQixLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFDaEMsU0FBSyxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLENBQUMsQ0FBQztHQUM3Qzs7Ozs7QUFLRCxrRUExQ29CLElBQUksQ0EwQ25CLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDOztBQUV6QyxNQUFJLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxPQXhEcEIsS0FBSyxFQXdEc0IsRUFBRTs7O0FBRTNCLFVBQUksU0FBUyxHQUFHLEtBQUssQ0FBQzs7QUFFdEIsV0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDMUMsWUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUNqQyxtQkFBUyxHQUFHLElBQUksQ0FBQztBQUNqQixnQkFBTTtTQUNQO09BQ0Y7O0FBRUQsVUFBSSxDQUFDLFNBQVMsRUFBRTtBQUNkLGNBQU0sQ0FBQyxzQkFBc0IsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDN0M7YUFBTyxLQUFLO1VBQUM7T0FDZDs7QUFFRCxVQUFJLGNBQWMsR0FBRyxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQzdELFVBQUksS0FBSyxZQUFBLENBQUM7O0FBRVYsVUFBSSxjQUFjLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRTtBQUM5QyxhQUFLLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxXQUFXLEdBQUcsS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMvRCx3RUFqRUcsSUFBSSxDQWlFRixLQUFLLENBQUMsQ0FBQztPQUNiOztBQUVELFVBQUksTUFBTSxHQUFHLGlDQTNFZixRQUFRLEVBMkVpQixDQUFDOzs7QUFHeEIsY0FBUSxNQUFNLENBQUMsSUFBSTs7QUFFakIsYUFBSyxTQUFTO0FBQ1osMEVBNUVJLFFBQVEsQ0E0RUgsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQzNCLDBFQTdFSSxRQUFRLENBNkVILEtBQUssQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztBQUM5RCwwRUE5RUksUUFBUSxDQThFSCxLQUFLLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxFQUFFLG9CQUFvQixDQUFDLENBQUM7QUFDaEUsZ0JBQU07O0FBQUEsQUFFUixhQUFLLE9BQU87QUFDViwwRUFsRkksUUFBUSxDQWtGSCxLQUFLLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztBQUNwQywwRUFuRkksUUFBUSxDQW1GSCxLQUFLLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0FBQzVELGdCQUFNOztBQUFBLEFBRVIsYUFBSyxTQUFTO0FBQ1osMEVBdkZJLFFBQVEsQ0F1RkgsS0FBSyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0FBQ2hDLDBFQXhGSSxRQUFRLENBd0ZILEtBQUssQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztBQUM3RCwwRUF6RkksUUFBUSxDQXlGSCxLQUFLLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUM7QUFDNUQsZ0JBQU07O0FBQUEsQUFFUixhQUFLLE9BQU8sQ0FBQztBQUNiLGFBQUssUUFBUTtBQUNYLGdCQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDOUMsZ0JBQU0sQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQztBQUNqQyxnQkFBTSxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFDNUQsMEVBakdJLFFBQVEsQ0FpR0gsS0FBSyxFQUFFLFlBQVksQ0FBQyxDQUFDO0FBQzlCLG9CQUFVLENBQUMsWUFBWTtBQUNyQixrQkFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ2Ysa0JBQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1dBQ3hELEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDUixnQkFBTTtBQUFBLE9BQ1Q7Ozs7OztHQUNGOzs7OztBQUtELE1BQUksTUFBTSxDQUFDLFFBQVEsRUFBRTtBQUNuQixRQUFJLFdBQVcsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLG9CQUFvQixDQUFDLENBQUM7O0FBRTVELGVBQVcsQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLE1BQU0sR0FBRyxNQUFNLENBQUMsUUFBUSxHQUFHLEdBQUcsQ0FBQztBQUNuRSxvRUEvR0ssSUFBSSxDQStHSixXQUFXLENBQUMsQ0FBQzs7QUFFbEIsUUFBSSxTQUFTLEdBQUcsRUFBRSxDQUFDO0FBQ25CLFFBQUksVUFBVSxHQUFHLEVBQUUsQ0FBQzs7QUFFcEIsUUFBSSxNQUFNLENBQUMsU0FBUyxFQUFFO0FBQ3BCLFVBQUksVUFBVSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hELFVBQUksUUFBUSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixVQUFJLFNBQVMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7O0FBRTlCLFVBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxTQUFTLEVBQUU7QUFDM0IsY0FBTSxDQUFDLGtFQUFrRSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztPQUMvRixNQUFNO0FBQ0wsaUJBQVMsR0FBRyxRQUFRLENBQUM7QUFDckIsa0JBQVUsR0FBRyxTQUFTLENBQUM7T0FDeEI7S0FDRjs7QUFFRCxlQUFXLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxXQUFXLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxHQUFHLFFBQVEsR0FBRyxTQUFTLEdBQUcsYUFBYSxHQUFHLFVBQVUsR0FBRyxJQUFJLENBQUMsQ0FBQztHQUNqSTs7Ozs7QUFLRCxPQUFLLENBQUMsWUFBWSxDQUFDLHdCQUF3QixFQUFFLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBQ3RFLE1BQUksTUFBTSxDQUFDLGdCQUFnQixFQUFFO0FBQzNCLGNBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLGNBQWMsQ0FBQztHQUMzQyxNQUFNO0FBQ0wsb0VBM0lrQixJQUFJLENBMklqQixVQUFVLENBQUMsQ0FBQztHQUNsQjs7Ozs7QUFLRCxPQUFLLENBQUMsWUFBWSxDQUFDLHlCQUF5QixFQUFFLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBQ3hFLE1BQUksTUFBTSxDQUFDLGlCQUFpQixFQUFFO0FBQzVCLGVBQVcsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLGNBQWMsQ0FBQztHQUM1QyxNQUFNO0FBQ0wsb0VBckprQixJQUFJLENBcUpqQixXQUFXLENBQUMsQ0FBQztHQUNuQjs7Ozs7QUFLRCxNQUFJLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRTtBQUMzQixjQUFVLENBQUMsU0FBUyxHQUFHLGdFQTdKekIsVUFBVSxDQTZKMEIsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7R0FDNUQ7QUFDRCxNQUFJLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRTtBQUM1QixlQUFXLENBQUMsU0FBUyxHQUFHLGdFQWhLMUIsVUFBVSxDQWdLMkIsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7R0FDOUQ7Ozs7O0FBS0QsTUFBSSxNQUFNLENBQUMsa0JBQWtCLEVBQUU7O0FBRTdCLGVBQVcsQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQzs7O0FBRzlELGVBQVcsQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLE1BQU0sQ0FBQyx5QkFBeUIsQ0FBQztBQUNyRSxlQUFXLENBQUMsS0FBSyxDQUFDLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyx5QkFBeUIsQ0FBQzs7O0FBR3RFLHFDQXBMRixhQUFhLENBb0xHLFdBQVcsRUFBRSxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztHQUN2RDs7Ozs7QUFLRCxPQUFLLENBQUMsWUFBWSxDQUFDLDBCQUEwQixFQUFFLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDOzs7OztBQUt6RSxNQUFJLGVBQWUsR0FBRyxNQUFNLENBQUMsWUFBWSxHQUFHLElBQUksR0FBRyxLQUFLLENBQUM7QUFDekQsT0FBSyxDQUFDLFlBQVksQ0FBQyx3QkFBd0IsRUFBRSxlQUFlLENBQUMsQ0FBQzs7Ozs7QUFLOUQsTUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUU7QUFDckIsU0FBSyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsQ0FBQztHQUM5QyxNQUFNLElBQUksT0FBTyxNQUFNLENBQUMsU0FBUyxLQUFLLFFBQVEsRUFBRTtBQUMvQyxTQUFLLENBQUMsWUFBWSxDQUFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztHQUN4RCxNQUFNO0FBQ0wsU0FBSyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsQ0FBQztHQUM3Qzs7Ozs7QUFLRCxPQUFLLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7Q0FDaEQsQ0FBQzs7cUJBRWEsYUFBYTs7Ozs7Ozs7Ozs7O0FDek41QixJQUFJLE1BQU0sR0FBRyxnQkFBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQzFCLE9BQUssSUFBSSxHQUFHLElBQUksQ0FBQyxFQUFFO0FBQ2pCLFFBQUksQ0FBQyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRTtBQUN6QixPQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0tBQ2pCO0dBQ0Y7QUFDRCxTQUFPLENBQUMsQ0FBQztDQUNWLENBQUM7Ozs7O0FBS0YsSUFBSSxRQUFRLEdBQUcsa0JBQVMsR0FBRyxFQUFFO0FBQzNCLE1BQUksTUFBTSxHQUFHLDJDQUEyQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNuRSxTQUFPLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLElBQUksR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLElBQUksR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQztDQUNsSCxDQUFDOzs7OztBQUtGLElBQUksS0FBSyxHQUFHLGlCQUFXO0FBQ3JCLFNBQVEsTUFBTSxDQUFDLFdBQVcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBRTtDQUN6RCxDQUFDOzs7OztBQUtGLElBQUksTUFBTSxHQUFHLGdCQUFTLE1BQU0sRUFBRTtBQUM1QixNQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUU7O0FBRWxCLFVBQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsR0FBRyxNQUFNLENBQUMsQ0FBQztHQUM3QztDQUNGLENBQUM7Ozs7OztBQU1GLElBQUksY0FBYyxHQUFHLHdCQUFTLEdBQUcsRUFBRSxHQUFHLEVBQUU7O0FBRXRDLEtBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUM3QyxNQUFJLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO0FBQ2xCLE9BQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztHQUMzRDtBQUNELEtBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDOzs7QUFHZixNQUFJLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDZCxNQUFJLENBQUMsQ0FBQztBQUNOLE1BQUksQ0FBQyxDQUFDOztBQUVOLE9BQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQ3RCLEtBQUMsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZDLEtBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNyRSxPQUFHLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFBLENBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztHQUNwQzs7QUFFRCxTQUFPLEdBQUcsQ0FBQztDQUNaLENBQUM7O1FBSUEsTUFBTSxHQUFOLE1BQU07UUFDTixRQUFRLEdBQVIsUUFBUTtRQUNSLEtBQUssR0FBTCxLQUFLO1FBQ0wsTUFBTSxHQUFOLE1BQU07UUFDTixjQUFjLEdBQWQsY0FBYyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIvLyBTd2VldEFsZXJ0XG4vLyAyMDE0LTIwMTUgKGMpIC0gVHJpc3RhbiBFZHdhcmRzXG4vLyBnaXRodWIuY29tL3Q0dDUvc3dlZXRhbGVydFxuXG4vKlxuICogalF1ZXJ5LWxpa2UgZnVuY3Rpb25zIGZvciBtYW5pcHVsYXRpbmcgdGhlIERPTVxuICovXG5pbXBvcnQge1xuICBoYXNDbGFzcywgYWRkQ2xhc3MsIHJlbW92ZUNsYXNzLFxuICBlc2NhcGVIdG1sLFxuICBfc2hvdywgc2hvdywgX2hpZGUsIGhpZGUsXG4gIGlzRGVzY2VuZGFudCxcbiAgZ2V0VG9wTWFyZ2luLFxuICBmYWRlSW4sIGZhZGVPdXQsXG4gIGZpcmVDbGljayxcbiAgc3RvcEV2ZW50UHJvcGFnYXRpb25cbn0gZnJvbSAnLi9tb2R1bGVzL2hhbmRsZS1kb20nO1xuXG4vKlxuICogSGFuZHkgdXRpbGl0aWVzXG4gKi9cbmltcG9ydCB7XG4gIGV4dGVuZCxcbiAgaGV4VG9SZ2IsXG4gIGlzSUU4LFxuICBsb2dTdHIsXG4gIGNvbG9yTHVtaW5hbmNlXG59IGZyb20gJy4vbW9kdWxlcy91dGlscyc7XG5cbi8qXG4gKiAgSGFuZGxlIHN3ZWV0QWxlcnQncyBET00gZWxlbWVudHNcbiAqL1xuaW1wb3J0IHtcbiAgc3dlZXRBbGVydEluaXRpYWxpemUsXG4gIGdldE1vZGFsLFxuICBnZXRPdmVybGF5LFxuICBnZXRJbnB1dCxcbiAgc2V0Rm9jdXNTdHlsZSxcbiAgb3Blbk1vZGFsLFxuICByZXNldElucHV0LFxuICBmaXhWZXJ0aWNhbFBvc2l0aW9uXG59IGZyb20gJy4vbW9kdWxlcy9oYW5kbGUtc3dhbC1kb20nO1xuXG5cbi8vIEhhbmRsZSBidXR0b24gZXZlbnRzIGFuZCBrZXlib2FyZCBldmVudHNcbmltcG9ydCB7IGhhbmRsZUJ1dHRvbiwgaGFuZGxlQ29uZmlybSwgaGFuZGxlQ2FuY2VsIH0gZnJvbSAnLi9tb2R1bGVzL2hhbmRsZS1jbGljayc7XG5pbXBvcnQgaGFuZGxlS2V5RG93biBmcm9tICcuL21vZHVsZXMvaGFuZGxlLWtleSc7XG5cblxuLy8gRGVmYXVsdCB2YWx1ZXNcbmltcG9ydCBkZWZhdWx0UGFyYW1zIGZyb20gJy4vbW9kdWxlcy9kZWZhdWx0LXBhcmFtcyc7XG5pbXBvcnQgc2V0UGFyYW1ldGVycyBmcm9tICcuL21vZHVsZXMvc2V0LXBhcmFtcyc7XG5cbi8qXG4gKiBSZW1lbWJlciBzdGF0ZSBpbiBjYXNlcyB3aGVyZSBvcGVuaW5nIGFuZCBoYW5kbGluZyBhIG1vZGFsIHdpbGwgZmlkZGxlIHdpdGggaXQuXG4gKiAoV2UgYWxzbyB1c2Ugd2luZG93LnByZXZpb3VzQWN0aXZlRWxlbWVudCBhcyBhIGdsb2JhbCB2YXJpYWJsZSlcbiAqL1xudmFyIHByZXZpb3VzV2luZG93S2V5RG93bjtcbnZhciBsYXN0Rm9jdXNlZEJ1dHRvbjtcblxuXG4vKlxuICogR2xvYmFsIHN3ZWV0QWxlcnQgZnVuY3Rpb25cbiAqICh0aGlzIGlzIHdoYXQgdGhlIHVzZXIgY2FsbHMpXG4gKi9cbnZhciBzd2VldEFsZXJ0LCBzd2FsO1xuXG5zd2VldEFsZXJ0ID0gc3dhbCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY3VzdG9taXphdGlvbnMgPSBhcmd1bWVudHNbMF07XG5cbiAgYWRkQ2xhc3MoZG9jdW1lbnQuYm9keSwgJ3N0b3Atc2Nyb2xsaW5nJyk7XG4gIHJlc2V0SW5wdXQoKTtcblxuICAvKlxuICAgKiBVc2UgYXJndW1lbnQgaWYgZGVmaW5lZCBvciBkZWZhdWx0IHZhbHVlIGZyb20gcGFyYW1zIG9iamVjdCBvdGhlcndpc2UuXG4gICAqIFN1cHBvcnRzIHRoZSBjYXNlIHdoZXJlIGEgZGVmYXVsdCB2YWx1ZSBpcyBib29sZWFuIHRydWUgYW5kIHNob3VsZCBiZVxuICAgKiBvdmVycmlkZGVuIGJ5IGEgY29ycmVzcG9uZGluZyBleHBsaWNpdCBhcmd1bWVudCB3aGljaCBpcyBib29sZWFuIGZhbHNlLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJndW1lbnRPckRlZmF1bHQoa2V5KSB7XG4gICAgdmFyIGFyZ3MgPSBjdXN0b21pemF0aW9ucztcbiAgICByZXR1cm4gKGFyZ3Nba2V5XSA9PT0gdW5kZWZpbmVkKSA/ICBkZWZhdWx0UGFyYW1zW2tleV0gOiBhcmdzW2tleV07XG4gIH1cblxuICBpZiAoY3VzdG9taXphdGlvbnMgPT09IHVuZGVmaW5lZCkge1xuICAgIGxvZ1N0cignU3dlZXRBbGVydCBleHBlY3RzIGF0IGxlYXN0IDEgYXR0cmlidXRlIScpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBwYXJhbXMgPSBleHRlbmQoe30sIGRlZmF1bHRQYXJhbXMpO1xuXG4gIHN3aXRjaCAodHlwZW9mIGN1c3RvbWl6YXRpb25zKSB7XG5cbiAgICAvLyBFeDogc3dhbChcIkhlbGxvXCIsIFwiSnVzdCB0ZXN0aW5nXCIsIFwiaW5mb1wiKTtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgcGFyYW1zLnRpdGxlID0gY3VzdG9taXphdGlvbnM7XG4gICAgICBwYXJhbXMudGV4dCAgPSBhcmd1bWVudHNbMV0gfHwgJyc7XG4gICAgICBwYXJhbXMudHlwZSAgPSBhcmd1bWVudHNbMl0gfHwgJyc7XG4gICAgICBicmVhaztcblxuICAgIC8vIEV4OiBzd2FsKHsgdGl0bGU6XCJIZWxsb1wiLCB0ZXh0OiBcIkp1c3QgdGVzdGluZ1wiLCB0eXBlOiBcImluZm9cIiB9KTtcbiAgICBjYXNlICdvYmplY3QnOlxuICAgICAgaWYgKGN1c3RvbWl6YXRpb25zLnRpdGxlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbG9nU3RyKCdNaXNzaW5nIFwidGl0bGVcIiBhcmd1bWVudCEnKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBwYXJhbXMudGl0bGUgPSBjdXN0b21pemF0aW9ucy50aXRsZTtcblxuICAgICAgZm9yIChsZXQgY3VzdG9tTmFtZSBpbiBkZWZhdWx0UGFyYW1zKSB7XG4gICAgICAgIHBhcmFtc1tjdXN0b21OYW1lXSA9IGFyZ3VtZW50T3JEZWZhdWx0KGN1c3RvbU5hbWUpO1xuICAgICAgfVxuXG4gICAgICAvLyBTaG93IFwiQ29uZmlybVwiIGluc3RlYWQgb2YgXCJPS1wiIGlmIGNhbmNlbCBidXR0b24gaXMgdmlzaWJsZVxuICAgICAgcGFyYW1zLmNvbmZpcm1CdXR0b25UZXh0ID0gcGFyYW1zLnNob3dDYW5jZWxCdXR0b24gPyAnQ29uZmlybScgOiBkZWZhdWx0UGFyYW1zLmNvbmZpcm1CdXR0b25UZXh0O1xuICAgICAgcGFyYW1zLmNvbmZpcm1CdXR0b25UZXh0ID0gYXJndW1lbnRPckRlZmF1bHQoJ2NvbmZpcm1CdXR0b25UZXh0Jyk7XG5cbiAgICAgIC8vIENhbGxiYWNrIGZ1bmN0aW9uIHdoZW4gY2xpY2tpbmcgb24gXCJPS1wiL1wiQ2FuY2VsXCJcbiAgICAgIHBhcmFtcy5kb25lRnVuY3Rpb24gPSBhcmd1bWVudHNbMV0gfHwgbnVsbDtcblxuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgbG9nU3RyKCdVbmV4cGVjdGVkIHR5cGUgb2YgYXJndW1lbnQhIEV4cGVjdGVkIFwic3RyaW5nXCIgb3IgXCJvYmplY3RcIiwgZ290ICcgKyB0eXBlb2YgY3VzdG9taXphdGlvbnMpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gIH1cblxuICBzZXRQYXJhbWV0ZXJzKHBhcmFtcyk7XG4gIGZpeFZlcnRpY2FsUG9zaXRpb24oKTtcbiAgb3Blbk1vZGFsKGFyZ3VtZW50c1sxXSk7XG5cbiAgLy8gTW9kYWwgaW50ZXJhY3Rpb25zXG4gIHZhciBtb2RhbCA9IGdldE1vZGFsKCk7XG5cblxuICAvKlxuICAgKiBNYWtlIHN1cmUgYWxsIG1vZGFsIGJ1dHRvbnMgcmVzcG9uZCB0byBhbGwgZXZlbnRzXG4gICAqL1xuICB2YXIgJGJ1dHRvbnMgPSBtb2RhbC5xdWVyeVNlbGVjdG9yQWxsKCdidXR0b24nKTtcbiAgdmFyIGJ1dHRvbkV2ZW50cyA9IFsnb25jbGljaycsICdvbm1vdXNlb3ZlcicsICdvbm1vdXNlb3V0JywgJ29ubW91c2Vkb3duJywgJ29ubW91c2V1cCcsICdvbmZvY3VzJ107XG4gIHZhciBvbkJ1dHRvbkV2ZW50ID0gKGUpID0+IGhhbmRsZUJ1dHRvbihlLCBwYXJhbXMsIG1vZGFsKTtcblxuICBmb3IgKGxldCBidG5JbmRleCA9IDA7IGJ0bkluZGV4IDwgJGJ1dHRvbnMubGVuZ3RoOyBidG5JbmRleCsrKSB7XG4gICAgZm9yIChsZXQgZXZ0SW5kZXggPSAwOyBldnRJbmRleCA8IGJ1dHRvbkV2ZW50cy5sZW5ndGg7IGV2dEluZGV4KyspIHtcbiAgICAgIGxldCBidG5FdnQgPSBidXR0b25FdmVudHNbZXZ0SW5kZXhdO1xuICAgICAgJGJ1dHRvbnNbYnRuSW5kZXhdW2J0bkV2dF0gPSBvbkJ1dHRvbkV2ZW50O1xuICAgIH1cbiAgfVxuXG4gIC8vIENsaWNraW5nIG91dHNpZGUgdGhlIG1vZGFsIGRpc21pc3NlcyBpdCAoaWYgYWxsb3dlZCBieSB1c2VyKVxuICBnZXRPdmVybGF5KCkub25jbGljayA9IG9uQnV0dG9uRXZlbnQ7XG5cbiAgcHJldmlvdXNXaW5kb3dLZXlEb3duID0gd2luZG93Lm9ua2V5ZG93bjtcblxuICB2YXIgb25LZXlFdmVudCA9IChlKSA9PiBoYW5kbGVLZXlEb3duKGUsIHBhcmFtcywgbW9kYWwpO1xuICB3aW5kb3cub25rZXlkb3duID0gb25LZXlFdmVudDtcblxuICB3aW5kb3cub25mb2N1cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBXaGVuIHRoZSB1c2VyIGhhcyBmb2N1c2VkIGF3YXkgYW5kIGZvY3VzZWQgYmFjayBmcm9tIHRoZSB3aG9sZSB3aW5kb3cuXG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBQdXQgaW4gYSB0aW1lb3V0IHRvIGp1bXAgb3V0IG9mIHRoZSBldmVudCBzZXF1ZW5jZS5cbiAgICAgIC8vIENhbGxpbmcgZm9jdXMoKSBpbiB0aGUgZXZlbnQgc2VxdWVuY2UgY29uZnVzZXMgdGhpbmdzLlxuICAgICAgaWYgKGxhc3RGb2N1c2VkQnV0dG9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbGFzdEZvY3VzZWRCdXR0b24uZm9jdXMoKTtcbiAgICAgICAgbGFzdEZvY3VzZWRCdXR0b24gPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfSwgMCk7XG4gIH07XG4gIFxuICAvLyBTaG93IGFsZXJ0IHdpdGggZW5hYmxlZCBidXR0b25zIGFsd2F5c1xuICBzd2FsLmVuYWJsZUJ1dHRvbnMoKTtcbn07XG5cblxuXG4vKlxuICogU2V0IGRlZmF1bHQgcGFyYW1zIGZvciBlYWNoIHBvcHVwXG4gKiBAcGFyYW0ge09iamVjdH0gdXNlclBhcmFtc1xuICovXG5zd2VldEFsZXJ0LnNldERlZmF1bHRzID0gc3dhbC5zZXREZWZhdWx0cyA9IGZ1bmN0aW9uKHVzZXJQYXJhbXMpIHtcbiAgaWYgKCF1c2VyUGFyYW1zKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1c2VyUGFyYW1zIGlzIHJlcXVpcmVkJyk7XG4gIH1cbiAgaWYgKHR5cGVvZiB1c2VyUGFyYW1zICE9PSAnb2JqZWN0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcigndXNlclBhcmFtcyBoYXMgdG8gYmUgYSBvYmplY3QnKTtcbiAgfVxuXG4gIGV4dGVuZChkZWZhdWx0UGFyYW1zLCB1c2VyUGFyYW1zKTtcbn07XG5cblxuLypcbiAqIEFuaW1hdGlvbiB3aGVuIGNsb3NpbmcgbW9kYWxcbiAqL1xuc3dlZXRBbGVydC5jbG9zZSA9IHN3YWwuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgdmFyIG1vZGFsID0gZ2V0TW9kYWwoKTtcblxuICBmYWRlT3V0KGdldE92ZXJsYXkoKSwgNSk7XG4gIGZhZGVPdXQobW9kYWwsIDUpO1xuICByZW1vdmVDbGFzcyhtb2RhbCwgJ3Nob3dTd2VldEFsZXJ0Jyk7XG4gIGFkZENsYXNzKG1vZGFsLCAnaGlkZVN3ZWV0QWxlcnQnKTtcbiAgcmVtb3ZlQ2xhc3MobW9kYWwsICd2aXNpYmxlJyk7XG5cbiAgLypcbiAgICogUmVzZXQgaWNvbiBhbmltYXRpb25zXG4gICAqL1xuICB2YXIgJHN1Y2Nlc3NJY29uID0gbW9kYWwucXVlcnlTZWxlY3RvcignLnNhLWljb24uc2Etc3VjY2VzcycpO1xuICByZW1vdmVDbGFzcygkc3VjY2Vzc0ljb24sICdhbmltYXRlJyk7XG4gIHJlbW92ZUNsYXNzKCRzdWNjZXNzSWNvbi5xdWVyeVNlbGVjdG9yKCcuc2EtdGlwJyksICdhbmltYXRlU3VjY2Vzc1RpcCcpO1xuICByZW1vdmVDbGFzcygkc3VjY2Vzc0ljb24ucXVlcnlTZWxlY3RvcignLnNhLWxvbmcnKSwgJ2FuaW1hdGVTdWNjZXNzTG9uZycpO1xuXG4gIHZhciAkZXJyb3JJY29uID0gbW9kYWwucXVlcnlTZWxlY3RvcignLnNhLWljb24uc2EtZXJyb3InKTtcbiAgcmVtb3ZlQ2xhc3MoJGVycm9ySWNvbiwgJ2FuaW1hdGVFcnJvckljb24nKTtcbiAgcmVtb3ZlQ2xhc3MoJGVycm9ySWNvbi5xdWVyeVNlbGVjdG9yKCcuc2EteC1tYXJrJyksICdhbmltYXRlWE1hcmsnKTtcblxuICB2YXIgJHdhcm5pbmdJY29uID0gbW9kYWwucXVlcnlTZWxlY3RvcignLnNhLWljb24uc2Etd2FybmluZycpO1xuICByZW1vdmVDbGFzcygkd2FybmluZ0ljb24sICdwdWxzZVdhcm5pbmcnKTtcbiAgcmVtb3ZlQ2xhc3MoJHdhcm5pbmdJY29uLnF1ZXJ5U2VsZWN0b3IoJy5zYS1ib2R5JyksICdwdWxzZVdhcm5pbmdJbnMnKTtcbiAgcmVtb3ZlQ2xhc3MoJHdhcm5pbmdJY29uLnF1ZXJ5U2VsZWN0b3IoJy5zYS1kb3QnKSwgJ3B1bHNlV2FybmluZ0lucycpO1xuXG4gIC8vIFJlc2V0IGN1c3RvbSBjbGFzcyAoZGVsYXkgc28gdGhhdCBVSSBjaGFuZ2VzIGFyZW4ndCB2aXNpYmxlKVxuICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgIHZhciBjdXN0b21DbGFzcyA9IG1vZGFsLmdldEF0dHJpYnV0ZSgnZGF0YS1jdXN0b20tY2xhc3MnKTtcbiAgICByZW1vdmVDbGFzcyhtb2RhbCwgY3VzdG9tQ2xhc3MpO1xuICB9LCAzMDApO1xuXG4gIC8vIE1ha2UgcGFnZSBzY3JvbGxhYmxlIGFnYWluXG4gIHJlbW92ZUNsYXNzKGRvY3VtZW50LmJvZHksICdzdG9wLXNjcm9sbGluZycpO1xuXG4gIC8vIFJlc2V0IHRoZSBwYWdlIHRvIGl0cyBwcmV2aW91cyBzdGF0ZVxuICB3aW5kb3cub25rZXlkb3duID0gcHJldmlvdXNXaW5kb3dLZXlEb3duO1xuICBpZiAod2luZG93LnByZXZpb3VzQWN0aXZlRWxlbWVudCkge1xuICAgIHdpbmRvdy5wcmV2aW91c0FjdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgfVxuICBsYXN0Rm9jdXNlZEJ1dHRvbiA9IHVuZGVmaW5lZDtcbiAgY2xlYXJUaW1lb3V0KG1vZGFsLnRpbWVvdXQpO1xuXG4gIHJldHVybiB0cnVlO1xufTtcblxuXG4vKlxuICogVmFsaWRhdGlvbiBvZiB0aGUgaW5wdXQgZmllbGQgaXMgZG9uZSBieSB1c2VyXG4gKiBJZiBzb21ldGhpbmcgaXMgd3JvbmcgPT4gY2FsbCBzaG93SW5wdXRFcnJvciB3aXRoIGVycm9yTWVzc2FnZVxuICovXG5zd2VldEFsZXJ0LnNob3dJbnB1dEVycm9yID0gc3dhbC5zaG93SW5wdXRFcnJvciA9IGZ1bmN0aW9uKGVycm9yTWVzc2FnZSkge1xuICB2YXIgbW9kYWwgPSBnZXRNb2RhbCgpO1xuXG4gIHZhciAkZXJyb3JJY29uID0gbW9kYWwucXVlcnlTZWxlY3RvcignLnNhLWlucHV0LWVycm9yJyk7XG4gIGFkZENsYXNzKCRlcnJvckljb24sICdzaG93Jyk7XG5cbiAgdmFyICRlcnJvckNvbnRhaW5lciA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJy5zYS1lcnJvci1jb250YWluZXInKTtcbiAgYWRkQ2xhc3MoJGVycm9yQ29udGFpbmVyLCAnc2hvdycpO1xuXG4gICRlcnJvckNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCdwJykuaW5uZXJIVE1MID0gZXJyb3JNZXNzYWdlO1xuXG4gIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgc3dlZXRBbGVydC5lbmFibGVCdXR0b25zKCk7XG4gIH0sIDEpO1xuXG4gIG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ2lucHV0JykuZm9jdXMoKTtcbn07XG5cblxuLypcbiAqIFJlc2V0IGlucHV0IGVycm9yIERPTSBlbGVtZW50c1xuICovXG5zd2VldEFsZXJ0LnJlc2V0SW5wdXRFcnJvciA9IHN3YWwucmVzZXRJbnB1dEVycm9yID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgLy8gSWYgcHJlc3MgZW50ZXIgPT4gaWdub3JlXG4gIGlmIChldmVudCAmJiBldmVudC5rZXlDb2RlID09PSAxMykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciAkbW9kYWwgPSBnZXRNb2RhbCgpO1xuXG4gIHZhciAkZXJyb3JJY29uID0gJG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJy5zYS1pbnB1dC1lcnJvcicpO1xuICByZW1vdmVDbGFzcygkZXJyb3JJY29uLCAnc2hvdycpO1xuXG4gIHZhciAkZXJyb3JDb250YWluZXIgPSAkbW9kYWwucXVlcnlTZWxlY3RvcignLnNhLWVycm9yLWNvbnRhaW5lcicpO1xuICByZW1vdmVDbGFzcygkZXJyb3JDb250YWluZXIsICdzaG93Jyk7XG59O1xuXG4vKlxuICogRGlzYWJsZSBjb25maXJtIGFuZCBjYW5jZWwgYnV0dG9uc1xuICovXG5zd2VldEFsZXJ0LmRpc2FibGVCdXR0b25zID0gc3dhbC5kaXNhYmxlQnV0dG9ucyA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIHZhciBtb2RhbCA9IGdldE1vZGFsKCk7XG4gIHZhciAkY29uZmlybUJ1dHRvbiA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ2J1dHRvbi5jb25maXJtJyk7XG4gIHZhciAkY2FuY2VsQnV0dG9uID0gbW9kYWwucXVlcnlTZWxlY3RvcignYnV0dG9uLmNhbmNlbCcpO1xuICAkY29uZmlybUJ1dHRvbi5kaXNhYmxlZCA9IHRydWU7XG4gICRjYW5jZWxCdXR0b24uZGlzYWJsZWQgPSB0cnVlO1xufTtcblxuLypcbiAqIEVuYWJsZSBjb25maXJtIGFuZCBjYW5jZWwgYnV0dG9uc1xuICovXG5zd2VldEFsZXJ0LmVuYWJsZUJ1dHRvbnMgPSBzd2FsLmVuYWJsZUJ1dHRvbnMgPSBmdW5jdGlvbihldmVudCkge1xuICB2YXIgbW9kYWwgPSBnZXRNb2RhbCgpO1xuICB2YXIgJGNvbmZpcm1CdXR0b24gPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCdidXR0b24uY29uZmlybScpO1xuICB2YXIgJGNhbmNlbEJ1dHRvbiA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ2J1dHRvbi5jYW5jZWwnKTtcbiAgJGNvbmZpcm1CdXR0b24uZGlzYWJsZWQgPSBmYWxzZTtcbiAgJGNhbmNlbEJ1dHRvbi5kaXNhYmxlZCA9IGZhbHNlO1xufTtcblxuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gIC8vIFRoZSAnaGFuZGxlLWNsaWNrJyBtb2R1bGUgcmVxdWlyZXNcbiAgLy8gdGhhdCAnc3dlZXRBbGVydCcgd2FzIHNldCBhcyBnbG9iYWwuXG4gIHdpbmRvdy5zd2VldEFsZXJ0ID0gd2luZG93LnN3YWwgPSBzd2VldEFsZXJ0O1xufSBlbHNlIHtcbiAgbG9nU3RyKCdTd2VldEFsZXJ0IGlzIGEgZnJvbnRlbmQgbW9kdWxlIScpO1xufVxuIiwidmFyIGRlZmF1bHRQYXJhbXMgPSB7XG4gIHRpdGxlOiAnJyxcbiAgdGV4dDogJycsXG4gIHR5cGU6IG51bGwsXG4gIGFsbG93T3V0c2lkZUNsaWNrOiBmYWxzZSxcbiAgc2hvd0NvbmZpcm1CdXR0b246IHRydWUsXG4gIHNob3dDYW5jZWxCdXR0b246IGZhbHNlLFxuICBjbG9zZU9uQ29uZmlybTogdHJ1ZSxcbiAgY2xvc2VPbkNhbmNlbDogdHJ1ZSxcbiAgY29uZmlybUJ1dHRvblRleHQ6ICdPSycsXG4gIGNvbmZpcm1CdXR0b25Db2xvcjogJyM4Q0Q0RjUnLFxuICBjYW5jZWxCdXR0b25UZXh0OiAnQ2FuY2VsJyxcbiAgaW1hZ2VVcmw6IG51bGwsXG4gIGltYWdlU2l6ZTogbnVsbCxcbiAgdGltZXI6IG51bGwsXG4gIGN1c3RvbUNsYXNzOiAnJyxcbiAgaHRtbDogZmFsc2UsXG4gIGFuaW1hdGlvbjogdHJ1ZSxcbiAgYWxsb3dFc2NhcGVLZXk6IHRydWUsXG4gIGlucHV0VHlwZTogJ3RleHQnLFxuICBpbnB1dFBsYWNlaG9sZGVyOiAnJyxcbiAgaW5wdXRWYWx1ZTogJycsXG4gIHNob3dMb2FkZXJPbkNvbmZpcm06IGZhbHNlXG59O1xuXG5leHBvcnQgZGVmYXVsdCBkZWZhdWx0UGFyYW1zO1xuIiwiaW1wb3J0IHsgY29sb3JMdW1pbmFuY2UgfSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IGdldE1vZGFsIH0gZnJvbSAnLi9oYW5kbGUtc3dhbC1kb20nO1xuaW1wb3J0IHsgaGFzQ2xhc3MsIGlzRGVzY2VuZGFudCB9IGZyb20gJy4vaGFuZGxlLWRvbSc7XG5cblxuLypcbiAqIFVzZXIgY2xpY2tlZCBvbiBcIkNvbmZpcm1cIi9cIk9LXCIgb3IgXCJDYW5jZWxcIlxuICovXG52YXIgaGFuZGxlQnV0dG9uID0gZnVuY3Rpb24oZXZlbnQsIHBhcmFtcywgbW9kYWwpIHtcbiAgdmFyIGUgPSBldmVudCB8fCB3aW5kb3cuZXZlbnQ7XG4gIHZhciB0YXJnZXQgPSBlLnRhcmdldCB8fCBlLnNyY0VsZW1lbnQ7XG5cbiAgdmFyIHRhcmdldGVkQ29uZmlybSA9IHRhcmdldC5jbGFzc05hbWUuaW5kZXhPZignY29uZmlybScpICE9PSAtMTtcbiAgdmFyIHRhcmdldGVkT3ZlcmxheSA9IHRhcmdldC5jbGFzc05hbWUuaW5kZXhPZignc3dlZXQtb3ZlcmxheScpICE9PSAtMTtcbiAgdmFyIG1vZGFsSXNWaXNpYmxlICA9IGhhc0NsYXNzKG1vZGFsLCAndmlzaWJsZScpO1xuICB2YXIgZG9uZUZ1bmN0aW9uRXhpc3RzID0gKHBhcmFtcy5kb25lRnVuY3Rpb24gJiYgbW9kYWwuZ2V0QXR0cmlidXRlKCdkYXRhLWhhcy1kb25lLWZ1bmN0aW9uJykgPT09ICd0cnVlJyk7XG5cbiAgLy8gU2luY2UgdGhlIHVzZXIgY2FuIGNoYW5nZSB0aGUgYmFja2dyb3VuZC1jb2xvciBvZiB0aGUgY29uZmlybSBidXR0b24gcHJvZ3JhbW1hdGljYWxseSxcbiAgLy8gd2UgbXVzdCBjYWxjdWxhdGUgd2hhdCB0aGUgY29sb3Igc2hvdWxkIGJlIG9uIGhvdmVyL2FjdGl2ZVxuICB2YXIgbm9ybWFsQ29sb3IsIGhvdmVyQ29sb3IsIGFjdGl2ZUNvbG9yO1xuICBpZiAodGFyZ2V0ZWRDb25maXJtICYmIHBhcmFtcy5jb25maXJtQnV0dG9uQ29sb3IpIHtcbiAgICBub3JtYWxDb2xvciAgPSBwYXJhbXMuY29uZmlybUJ1dHRvbkNvbG9yO1xuICAgIGhvdmVyQ29sb3IgICA9IGNvbG9yTHVtaW5hbmNlKG5vcm1hbENvbG9yLCAtMC4wNCk7XG4gICAgYWN0aXZlQ29sb3IgID0gY29sb3JMdW1pbmFuY2Uobm9ybWFsQ29sb3IsIC0wLjE0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNob3VsZFNldENvbmZpcm1CdXR0b25Db2xvcihjb2xvcikge1xuICAgIGlmICh0YXJnZXRlZENvbmZpcm0gJiYgcGFyYW1zLmNvbmZpcm1CdXR0b25Db2xvcikge1xuICAgICAgdGFyZ2V0LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGNvbG9yO1xuICAgIH1cbiAgfVxuXG4gIHN3aXRjaCAoZS50eXBlKSB7XG4gICAgY2FzZSAnbW91c2VvdmVyJzpcbiAgICAgIHNob3VsZFNldENvbmZpcm1CdXR0b25Db2xvcihob3ZlckNvbG9yKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnbW91c2VvdXQnOlxuICAgICAgc2hvdWxkU2V0Q29uZmlybUJ1dHRvbkNvbG9yKG5vcm1hbENvbG9yKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnbW91c2Vkb3duJzpcbiAgICAgIHNob3VsZFNldENvbmZpcm1CdXR0b25Db2xvcihhY3RpdmVDb2xvcik7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ21vdXNldXAnOlxuICAgICAgc2hvdWxkU2V0Q29uZmlybUJ1dHRvbkNvbG9yKGhvdmVyQ29sb3IpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdmb2N1cyc6XG4gICAgICBsZXQgJGNvbmZpcm1CdXR0b24gPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCdidXR0b24uY29uZmlybScpO1xuICAgICAgbGV0ICRjYW5jZWxCdXR0b24gID0gbW9kYWwucXVlcnlTZWxlY3RvcignYnV0dG9uLmNhbmNlbCcpO1xuXG4gICAgICBpZiAodGFyZ2V0ZWRDb25maXJtKSB7XG4gICAgICAgICRjYW5jZWxCdXR0b24uc3R5bGUuYm94U2hhZG93ID0gJ25vbmUnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgJGNvbmZpcm1CdXR0b24uc3R5bGUuYm94U2hhZG93ID0gJ25vbmUnO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdjbGljayc6XG4gICAgICBsZXQgY2xpY2tlZE9uTW9kYWwgPSAobW9kYWwgPT09IHRhcmdldCk7XG4gICAgICBsZXQgY2xpY2tlZE9uTW9kYWxDaGlsZCA9IGlzRGVzY2VuZGFudChtb2RhbCwgdGFyZ2V0KTtcblxuICAgICAgLy8gSWdub3JlIGNsaWNrIG91dHNpZGUgaWYgYWxsb3dPdXRzaWRlQ2xpY2sgaXMgZmFsc2VcbiAgICAgIGlmICghY2xpY2tlZE9uTW9kYWwgJiYgIWNsaWNrZWRPbk1vZGFsQ2hpbGQgJiYgbW9kYWxJc1Zpc2libGUgJiYgIXBhcmFtcy5hbGxvd091dHNpZGVDbGljaykge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgaWYgKHRhcmdldGVkQ29uZmlybSAmJiBkb25lRnVuY3Rpb25FeGlzdHMgJiYgbW9kYWxJc1Zpc2libGUpIHtcbiAgICAgICAgaGFuZGxlQ29uZmlybShtb2RhbCwgcGFyYW1zKTtcbiAgICAgIH0gZWxzZSBpZiAoZG9uZUZ1bmN0aW9uRXhpc3RzICYmIG1vZGFsSXNWaXNpYmxlIHx8IHRhcmdldGVkT3ZlcmxheSkge1xuICAgICAgICBoYW5kbGVDYW5jZWwobW9kYWwsIHBhcmFtcyk7XG4gICAgICB9IGVsc2UgaWYgKGlzRGVzY2VuZGFudChtb2RhbCwgdGFyZ2V0KSAmJiB0YXJnZXQudGFnTmFtZSA9PT0gJ0JVVFRPTicpIHtcbiAgICAgICAgc3dlZXRBbGVydC5jbG9zZSgpO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gIH1cbn07XG5cbi8qXG4gKiAgVXNlciBjbGlja2VkIG9uIFwiQ29uZmlybVwiL1wiT0tcIlxuICovXG52YXIgaGFuZGxlQ29uZmlybSA9IGZ1bmN0aW9uKG1vZGFsLCBwYXJhbXMpIHtcbiAgdmFyIGNhbGxiYWNrVmFsdWUgPSB0cnVlO1xuXG4gIGlmIChoYXNDbGFzcyhtb2RhbCwgJ3Nob3ctaW5wdXQnKSkge1xuICAgIGNhbGxiYWNrVmFsdWUgPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCdpbnB1dCcpLnZhbHVlO1xuXG4gICAgaWYgKCFjYWxsYmFja1ZhbHVlKSB7XG4gICAgICBjYWxsYmFja1ZhbHVlID0gJyc7XG4gICAgfVxuICB9XG5cbiAgcGFyYW1zLmRvbmVGdW5jdGlvbihjYWxsYmFja1ZhbHVlKTtcblxuICBpZiAocGFyYW1zLmNsb3NlT25Db25maXJtKSB7XG4gICAgc3dlZXRBbGVydC5jbG9zZSgpO1xuICB9XG4gIC8vIERpc2FibGUgY2FuY2VsIGFuZCBjb25maXJtIGJ1dHRvbiBpZiB0aGUgcGFyYW1ldGVyIGlzIHRydWVcbiAgaWYgKHBhcmFtcy5zaG93TG9hZGVyT25Db25maXJtKSB7XG4gICAgc3dlZXRBbGVydC5kaXNhYmxlQnV0dG9ucygpO1xuICB9XG59O1xuXG4vKlxuICogIFVzZXIgY2xpY2tlZCBvbiBcIkNhbmNlbFwiXG4gKi9cbnZhciBoYW5kbGVDYW5jZWwgPSBmdW5jdGlvbihtb2RhbCwgcGFyYW1zKSB7XG4gIC8vIENoZWNrIGlmIGNhbGxiYWNrIGZ1bmN0aW9uIGV4cGVjdHMgYSBwYXJhbWV0ZXIgKHRvIHRyYWNrIGNhbmNlbCBhY3Rpb25zKVxuICB2YXIgZnVuY3Rpb25Bc1N0ciA9IFN0cmluZyhwYXJhbXMuZG9uZUZ1bmN0aW9uKS5yZXBsYWNlKC9cXHMvZywgJycpO1xuICB2YXIgZnVuY3Rpb25IYW5kbGVzQ2FuY2VsID0gZnVuY3Rpb25Bc1N0ci5zdWJzdHJpbmcoMCwgOSkgPT09ICdmdW5jdGlvbignICYmIGZ1bmN0aW9uQXNTdHIuc3Vic3RyaW5nKDksIDEwKSAhPT0gJyknO1xuXG4gIGlmIChmdW5jdGlvbkhhbmRsZXNDYW5jZWwpIHtcbiAgICBwYXJhbXMuZG9uZUZ1bmN0aW9uKGZhbHNlKTtcbiAgfVxuXG4gIGlmIChwYXJhbXMuY2xvc2VPbkNhbmNlbCkge1xuICAgIHN3ZWV0QWxlcnQuY2xvc2UoKTtcbiAgfVxufTtcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIGhhbmRsZUJ1dHRvbixcbiAgaGFuZGxlQ29uZmlybSxcbiAgaGFuZGxlQ2FuY2VsXG59O1xuIiwidmFyIGhhc0NsYXNzID0gZnVuY3Rpb24oZWxlbSwgY2xhc3NOYW1lKSB7XG4gIHJldHVybiBuZXcgUmVnRXhwKCcgJyArIGNsYXNzTmFtZSArICcgJykudGVzdCgnICcgKyBlbGVtLmNsYXNzTmFtZSArICcgJyk7XG59O1xuXG52YXIgYWRkQ2xhc3MgPSBmdW5jdGlvbihlbGVtLCBjbGFzc05hbWUpIHtcbiAgaWYgKCFoYXNDbGFzcyhlbGVtLCBjbGFzc05hbWUpKSB7XG4gICAgZWxlbS5jbGFzc05hbWUgKz0gJyAnICsgY2xhc3NOYW1lO1xuICB9XG59O1xuXG52YXIgcmVtb3ZlQ2xhc3MgPSBmdW5jdGlvbihlbGVtLCBjbGFzc05hbWUpIHtcbiAgdmFyIG5ld0NsYXNzID0gJyAnICsgZWxlbS5jbGFzc05hbWUucmVwbGFjZSgvW1xcdFxcclxcbl0vZywgJyAnKSArICcgJztcbiAgaWYgKGhhc0NsYXNzKGVsZW0sIGNsYXNzTmFtZSkpIHtcbiAgICB3aGlsZSAobmV3Q2xhc3MuaW5kZXhPZignICcgKyBjbGFzc05hbWUgKyAnICcpID49IDApIHtcbiAgICAgIG5ld0NsYXNzID0gbmV3Q2xhc3MucmVwbGFjZSgnICcgKyBjbGFzc05hbWUgKyAnICcsICcgJyk7XG4gICAgfVxuICAgIGVsZW0uY2xhc3NOYW1lID0gbmV3Q2xhc3MucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpO1xuICB9XG59O1xuXG52YXIgZXNjYXBlSHRtbCA9IGZ1bmN0aW9uKHN0cikge1xuICB2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIGRpdi5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzdHIpKTtcbiAgcmV0dXJuIGRpdi5pbm5lckhUTUw7XG59O1xuXG52YXIgX3Nob3cgPSBmdW5jdGlvbihlbGVtKSB7XG4gIGVsZW0uc3R5bGUub3BhY2l0eSA9ICcnO1xuICBlbGVtLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xufTtcblxudmFyIHNob3cgPSBmdW5jdGlvbihlbGVtcykge1xuICBpZiAoZWxlbXMgJiYgIWVsZW1zLmxlbmd0aCkge1xuICAgIHJldHVybiBfc2hvdyhlbGVtcyk7XG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtcy5sZW5ndGg7ICsraSkge1xuICAgIF9zaG93KGVsZW1zW2ldKTtcbiAgfVxufTtcblxudmFyIF9oaWRlID0gZnVuY3Rpb24oZWxlbSkge1xuICBlbGVtLnN0eWxlLm9wYWNpdHkgPSAnJztcbiAgZWxlbS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xufTtcblxudmFyIGhpZGUgPSBmdW5jdGlvbihlbGVtcykge1xuICBpZiAoZWxlbXMgJiYgIWVsZW1zLmxlbmd0aCkge1xuICAgIHJldHVybiBfaGlkZShlbGVtcyk7XG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtcy5sZW5ndGg7ICsraSkge1xuICAgIF9oaWRlKGVsZW1zW2ldKTtcbiAgfVxufTtcblxudmFyIGlzRGVzY2VuZGFudCA9IGZ1bmN0aW9uKHBhcmVudCwgY2hpbGQpIHtcbiAgdmFyIG5vZGUgPSBjaGlsZC5wYXJlbnROb2RlO1xuICB3aGlsZSAobm9kZSAhPT0gbnVsbCkge1xuICAgIGlmIChub2RlID09PSBwYXJlbnQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbnZhciBnZXRUb3BNYXJnaW4gPSBmdW5jdGlvbihlbGVtKSB7XG4gIGVsZW0uc3R5bGUubGVmdCA9ICctOTk5OXB4JztcbiAgZWxlbS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblxuICB2YXIgaGVpZ2h0ID0gZWxlbS5jbGllbnRIZWlnaHQsXG4gICAgICBwYWRkaW5nO1xuICBpZiAodHlwZW9mIGdldENvbXB1dGVkU3R5bGUgIT09IFwidW5kZWZpbmVkXCIpIHsgLy8gSUUgOFxuICAgIHBhZGRpbmcgPSBwYXJzZUludChnZXRDb21wdXRlZFN0eWxlKGVsZW0pLmdldFByb3BlcnR5VmFsdWUoJ3BhZGRpbmctdG9wJyksIDEwKTtcbiAgfSBlbHNlIHtcbiAgICBwYWRkaW5nID0gcGFyc2VJbnQoZWxlbS5jdXJyZW50U3R5bGUucGFkZGluZyk7XG4gIH1cblxuICBlbGVtLnN0eWxlLmxlZnQgPSAnJztcbiAgZWxlbS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICByZXR1cm4gKCctJyArIHBhcnNlSW50KChoZWlnaHQgKyBwYWRkaW5nKSAvIDIpICsgJ3B4Jyk7XG59O1xuXG52YXIgZmFkZUluID0gZnVuY3Rpb24oZWxlbSwgaW50ZXJ2YWwpIHtcbiAgaWYgKCtlbGVtLnN0eWxlLm9wYWNpdHkgPCAxKSB7XG4gICAgaW50ZXJ2YWwgPSBpbnRlcnZhbCB8fCAxNjtcbiAgICBlbGVtLnN0eWxlLm9wYWNpdHkgPSAwO1xuICAgIGVsZW0uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgdmFyIGxhc3QgPSArbmV3IERhdGUoKTtcbiAgICB2YXIgdGljayA9IGZ1bmN0aW9uKCkge1xuICAgICAgZWxlbS5zdHlsZS5vcGFjaXR5ID0gK2VsZW0uc3R5bGUub3BhY2l0eSArIChuZXcgRGF0ZSgpIC0gbGFzdCkgLyAxMDA7XG4gICAgICBsYXN0ID0gK25ldyBEYXRlKCk7XG5cbiAgICAgIGlmICgrZWxlbS5zdHlsZS5vcGFjaXR5IDwgMSkge1xuICAgICAgICBzZXRUaW1lb3V0KHRpY2ssIGludGVydmFsKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHRpY2soKTtcbiAgfVxuICBlbGVtLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOyAvL2ZhbGxiYWNrIElFOFxufTtcblxudmFyIGZhZGVPdXQgPSBmdW5jdGlvbihlbGVtLCBpbnRlcnZhbCkge1xuICBpbnRlcnZhbCA9IGludGVydmFsIHx8IDE2O1xuICBlbGVtLnN0eWxlLm9wYWNpdHkgPSAxO1xuICB2YXIgbGFzdCA9ICtuZXcgRGF0ZSgpO1xuICB2YXIgdGljayA9IGZ1bmN0aW9uKCkge1xuICAgIGVsZW0uc3R5bGUub3BhY2l0eSA9ICtlbGVtLnN0eWxlLm9wYWNpdHkgLSAobmV3IERhdGUoKSAtIGxhc3QpIC8gMTAwO1xuICAgIGxhc3QgPSArbmV3IERhdGUoKTtcblxuICAgIGlmICgrZWxlbS5zdHlsZS5vcGFjaXR5ID4gMCkge1xuICAgICAgc2V0VGltZW91dCh0aWNrLCBpbnRlcnZhbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW0uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB9XG4gIH07XG4gIHRpY2soKTtcbn07XG5cbnZhciBmaXJlQ2xpY2sgPSBmdW5jdGlvbihub2RlKSB7XG4gIC8vIFRha2VuIGZyb20gaHR0cDovL3d3dy5ub25vYnRydXNpdmUuY29tLzIwMTEvMTEvMjkvcHJvZ3JhbWF0aWNhbGx5LWZpcmUtY3Jvc3Nicm93c2VyLWNsaWNrLWV2ZW50LXdpdGgtamF2YXNjcmlwdC9cbiAgLy8gVGhlbiBmaXhlZCBmb3IgdG9kYXkncyBDaHJvbWUgYnJvd3Nlci5cbiAgaWYgKHR5cGVvZiBNb3VzZUV2ZW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgLy8gVXAtdG8tZGF0ZSBhcHByb2FjaFxuICAgIHZhciBtZXZ0ID0gbmV3IE1vdXNlRXZlbnQoJ2NsaWNrJywge1xuICAgICAgdmlldzogd2luZG93LFxuICAgICAgYnViYmxlczogZmFsc2UsXG4gICAgICBjYW5jZWxhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgbm9kZS5kaXNwYXRjaEV2ZW50KG1ldnQpO1xuICB9IGVsc2UgaWYgKCBkb2N1bWVudC5jcmVhdGVFdmVudCApIHtcbiAgICAvLyBGYWxsYmFja1xuICAgIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnTW91c2VFdmVudHMnKTtcbiAgICBldnQuaW5pdEV2ZW50KCdjbGljaycsIGZhbHNlLCBmYWxzZSk7XG4gICAgbm9kZS5kaXNwYXRjaEV2ZW50KGV2dCk7XG4gIH0gZWxzZSBpZiAoZG9jdW1lbnQuY3JlYXRlRXZlbnRPYmplY3QpIHtcbiAgICBub2RlLmZpcmVFdmVudCgnb25jbGljaycpIDtcbiAgfSBlbHNlIGlmICh0eXBlb2Ygbm9kZS5vbmNsaWNrID09PSAnZnVuY3Rpb24nICkge1xuICAgIG5vZGUub25jbGljaygpO1xuICB9XG59O1xuXG52YXIgc3RvcEV2ZW50UHJvcGFnYXRpb24gPSBmdW5jdGlvbihlKSB7XG4gIC8vIEluIHBhcnRpY3VsYXIsIG1ha2Ugc3VyZSB0aGUgc3BhY2UgYmFyIGRvZXNuJ3Qgc2Nyb2xsIHRoZSBtYWluIHdpbmRvdy5cbiAgaWYgKHR5cGVvZiBlLnN0b3BQcm9wYWdhdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICB9IGVsc2UgaWYgKHdpbmRvdy5ldmVudCAmJiB3aW5kb3cuZXZlbnQuaGFzT3duUHJvcGVydHkoJ2NhbmNlbEJ1YmJsZScpKSB7XG4gICAgd2luZG93LmV2ZW50LmNhbmNlbEJ1YmJsZSA9IHRydWU7XG4gIH1cbn07XG5cbmV4cG9ydCB7IFxuICBoYXNDbGFzcywgYWRkQ2xhc3MsIHJlbW92ZUNsYXNzLCBcbiAgZXNjYXBlSHRtbCwgXG4gIF9zaG93LCBzaG93LCBfaGlkZSwgaGlkZSwgXG4gIGlzRGVzY2VuZGFudCwgXG4gIGdldFRvcE1hcmdpbixcbiAgZmFkZUluLCBmYWRlT3V0LFxuICBmaXJlQ2xpY2ssXG4gIHN0b3BFdmVudFByb3BhZ2F0aW9uXG59O1xuIiwiaW1wb3J0IHsgc3RvcEV2ZW50UHJvcGFnYXRpb24sIGZpcmVDbGljayB9IGZyb20gJy4vaGFuZGxlLWRvbSc7XG5pbXBvcnQgeyBzZXRGb2N1c1N0eWxlIH0gZnJvbSAnLi9oYW5kbGUtc3dhbC1kb20nO1xuXG5cbnZhciBoYW5kbGVLZXlEb3duID0gZnVuY3Rpb24oZXZlbnQsIHBhcmFtcywgbW9kYWwpIHtcbiAgdmFyIGUgPSBldmVudCB8fCB3aW5kb3cuZXZlbnQ7XG4gIHZhciBrZXlDb2RlID0gZS5rZXlDb2RlIHx8IGUud2hpY2g7XG5cbiAgdmFyICRva0J1dHRvbiAgICAgPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCdidXR0b24uY29uZmlybScpO1xuICB2YXIgJGNhbmNlbEJ1dHRvbiA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJ2J1dHRvbi5jYW5jZWwnKTtcbiAgdmFyICRtb2RhbEJ1dHRvbnMgPSBtb2RhbC5xdWVyeVNlbGVjdG9yQWxsKCdidXR0b25bdGFiaW5kZXhdJyk7XG5cblxuICBpZiAoWzksIDEzLCAzMiwgMjddLmluZGV4T2Yoa2V5Q29kZSkgPT09IC0xKSB7XG4gICAgLy8gRG9uJ3QgZG8gd29yayBvbiBrZXlzIHdlIGRvbid0IGNhcmUgYWJvdXQuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyICR0YXJnZXRFbGVtZW50ID0gZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50O1xuXG4gIHZhciBidG5JbmRleCA9IC0xOyAvLyBGaW5kIHRoZSBidXR0b24gLSBub3RlLCB0aGlzIGlzIGEgbm9kZWxpc3QsIG5vdCBhbiBhcnJheS5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAkbW9kYWxCdXR0b25zLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCR0YXJnZXRFbGVtZW50ID09PSAkbW9kYWxCdXR0b25zW2ldKSB7XG4gICAgICBidG5JbmRleCA9IGk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoa2V5Q29kZSA9PT0gOSkge1xuICAgIC8vIFRBQlxuICAgIGlmIChidG5JbmRleCA9PT0gLTEpIHtcbiAgICAgIC8vIE5vIGJ1dHRvbiBmb2N1c2VkLiBKdW1wIHRvIHRoZSBjb25maXJtIGJ1dHRvbi5cbiAgICAgICR0YXJnZXRFbGVtZW50ID0gJG9rQnV0dG9uO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBDeWNsZSB0byB0aGUgbmV4dCBidXR0b25cbiAgICAgIGlmIChidG5JbmRleCA9PT0gJG1vZGFsQnV0dG9ucy5sZW5ndGggLSAxKSB7XG4gICAgICAgICR0YXJnZXRFbGVtZW50ID0gJG1vZGFsQnV0dG9uc1swXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICR0YXJnZXRFbGVtZW50ID0gJG1vZGFsQnV0dG9uc1tidG5JbmRleCArIDFdO1xuICAgICAgfVxuICAgIH1cblxuICAgIHN0b3BFdmVudFByb3BhZ2F0aW9uKGUpO1xuICAgICR0YXJnZXRFbGVtZW50LmZvY3VzKCk7XG5cbiAgICBpZiAocGFyYW1zLmNvbmZpcm1CdXR0b25Db2xvcikge1xuICAgICAgc2V0Rm9jdXNTdHlsZSgkdGFyZ2V0RWxlbWVudCwgcGFyYW1zLmNvbmZpcm1CdXR0b25Db2xvcik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChrZXlDb2RlID09PSAxMykge1xuICAgICAgaWYgKCR0YXJnZXRFbGVtZW50LnRhZ05hbWUgPT09ICdJTlBVVCcpIHtcbiAgICAgICAgJHRhcmdldEVsZW1lbnQgPSAkb2tCdXR0b247XG4gICAgICAgICRva0J1dHRvbi5mb2N1cygpO1xuICAgICAgfVxuXG4gICAgICBpZiAoYnRuSW5kZXggPT09IC0xKSB7XG4gICAgICAgIC8vIEVOVEVSL1NQQUNFIGNsaWNrZWQgb3V0c2lkZSBvZiBhIGJ1dHRvbi5cbiAgICAgICAgJHRhcmdldEVsZW1lbnQgPSAkb2tCdXR0b247XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBEbyBub3RoaW5nIC0gbGV0IHRoZSBicm93c2VyIGhhbmRsZSBpdC5cbiAgICAgICAgJHRhcmdldEVsZW1lbnQgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChrZXlDb2RlID09PSAyNyAmJiBwYXJhbXMuYWxsb3dFc2NhcGVLZXkgPT09IHRydWUpIHtcbiAgICAgICR0YXJnZXRFbGVtZW50ID0gJGNhbmNlbEJ1dHRvbjtcbiAgICAgIGZpcmVDbGljaygkdGFyZ2V0RWxlbWVudCwgZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZhbGxiYWNrIC0gbGV0IHRoZSBicm93c2VyIGhhbmRsZSBpdC5cbiAgICAgICR0YXJnZXRFbGVtZW50ID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgaGFuZGxlS2V5RG93bjtcbiIsImltcG9ydCB7IGhleFRvUmdiIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyByZW1vdmVDbGFzcywgZ2V0VG9wTWFyZ2luLCBmYWRlSW4sIHNob3csIGFkZENsYXNzIH0gZnJvbSAnLi9oYW5kbGUtZG9tJztcbmltcG9ydCBkZWZhdWx0UGFyYW1zIGZyb20gJy4vZGVmYXVsdC1wYXJhbXMnO1xuXG52YXIgbW9kYWxDbGFzcyAgID0gJy5zd2VldC1hbGVydCc7XG52YXIgb3ZlcmxheUNsYXNzID0gJy5zd2VldC1vdmVybGF5JztcblxuLypcbiAqIEFkZCBtb2RhbCArIG92ZXJsYXkgdG8gRE9NXG4gKi9cbmltcG9ydCBpbmplY3RlZEhUTUwgZnJvbSAnLi9pbmplY3RlZC1odG1sJztcblxudmFyIHN3ZWV0QWxlcnRJbml0aWFsaXplID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzd2VldFdyYXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgc3dlZXRXcmFwLmlubmVySFRNTCA9IGluamVjdGVkSFRNTDtcblxuICAvLyBBcHBlbmQgZWxlbWVudHMgdG8gYm9keVxuICB3aGlsZSAoc3dlZXRXcmFwLmZpcnN0Q2hpbGQpIHtcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHN3ZWV0V3JhcC5maXJzdENoaWxkKTtcbiAgfVxufTtcblxuLypcbiAqIEdldCBET00gZWxlbWVudCBvZiBtb2RhbFxuICovXG52YXIgZ2V0TW9kYWwgPSBmdW5jdGlvbigpIHtcbiAgdmFyICRtb2RhbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IobW9kYWxDbGFzcyk7XG5cbiAgaWYgKCEkbW9kYWwpIHtcbiAgICBzd2VldEFsZXJ0SW5pdGlhbGl6ZSgpO1xuICAgICRtb2RhbCA9IGdldE1vZGFsKCk7XG4gIH1cblxuICByZXR1cm4gJG1vZGFsO1xufTtcblxuLypcbiAqIEdldCBET00gZWxlbWVudCBvZiBpbnB1dCAoaW4gbW9kYWwpXG4gKi9cbnZhciBnZXRJbnB1dCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgJG1vZGFsID0gZ2V0TW9kYWwoKTtcbiAgaWYgKCRtb2RhbCkge1xuICAgIHJldHVybiAkbW9kYWwucXVlcnlTZWxlY3RvcignaW5wdXQnKTtcbiAgfVxufTtcblxuLypcbiAqIEdldCBET00gZWxlbWVudCBvZiBvdmVybGF5XG4gKi9cbnZhciBnZXRPdmVybGF5ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKG92ZXJsYXlDbGFzcyk7XG59O1xuXG4vKlxuICogQWRkIGJveC1zaGFkb3cgc3R5bGUgdG8gYnV0dG9uIChkZXBlbmRpbmcgb24gaXRzIGNob3NlbiBiZy1jb2xvcilcbiAqL1xudmFyIHNldEZvY3VzU3R5bGUgPSBmdW5jdGlvbigkYnV0dG9uLCBiZ0NvbG9yKSB7XG4gIHZhciByZ2JDb2xvciA9IGhleFRvUmdiKGJnQ29sb3IpO1xuICAkYnV0dG9uLnN0eWxlLmJveFNoYWRvdyA9ICcwIDAgMnB4IHJnYmEoJyArIHJnYkNvbG9yICsgJywgMC44KSwgaW5zZXQgMCAwIDAgMXB4IHJnYmEoMCwgMCwgMCwgMC4wNSknO1xufTtcblxuLypcbiAqIEFuaW1hdGlvbiB3aGVuIG9wZW5pbmcgbW9kYWxcbiAqL1xudmFyIG9wZW5Nb2RhbCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gIHZhciAkbW9kYWwgPSBnZXRNb2RhbCgpO1xuICBmYWRlSW4oZ2V0T3ZlcmxheSgpLCAxMCk7XG4gIHNob3coJG1vZGFsKTtcbiAgYWRkQ2xhc3MoJG1vZGFsLCAnc2hvd1N3ZWV0QWxlcnQnKTtcbiAgcmVtb3ZlQ2xhc3MoJG1vZGFsLCAnaGlkZVN3ZWV0QWxlcnQnKTtcblxuICB3aW5kb3cucHJldmlvdXNBY3RpdmVFbGVtZW50ID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcbiAgdmFyICRva0J1dHRvbiA9ICRtb2RhbC5xdWVyeVNlbGVjdG9yKCdidXR0b24uY29uZmlybScpO1xuICAkb2tCdXR0b24uZm9jdXMoKTtcblxuICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBhZGRDbGFzcygkbW9kYWwsICd2aXNpYmxlJyk7XG4gIH0sIDUwMCk7XG5cbiAgdmFyIHRpbWVyID0gJG1vZGFsLmdldEF0dHJpYnV0ZSgnZGF0YS10aW1lcicpO1xuXG4gIGlmICh0aW1lciAhPT0gJ251bGwnICYmIHRpbWVyICE9PSAnJykge1xuICAgIHZhciB0aW1lckNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgJG1vZGFsLnRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGRvbmVGdW5jdGlvbkV4aXN0cyA9ICgodGltZXJDYWxsYmFjayB8fCBudWxsKSAmJiAkbW9kYWwuZ2V0QXR0cmlidXRlKCdkYXRhLWhhcy1kb25lLWZ1bmN0aW9uJykgPT09ICd0cnVlJyk7XG4gICAgICBpZiAoZG9uZUZ1bmN0aW9uRXhpc3RzKSB7IFxuICAgICAgICB0aW1lckNhbGxiYWNrKG51bGwpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHN3ZWV0QWxlcnQuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9LCB0aW1lcik7XG4gIH1cbn07XG5cbi8qXG4gKiBSZXNldCB0aGUgc3R5bGluZyBvZiB0aGUgaW5wdXRcbiAqIChmb3IgZXhhbXBsZSBpZiBlcnJvcnMgaGF2ZSBiZWVuIHNob3duKVxuICovXG52YXIgcmVzZXRJbnB1dCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgJG1vZGFsID0gZ2V0TW9kYWwoKTtcbiAgdmFyICRpbnB1dCA9IGdldElucHV0KCk7XG5cbiAgcmVtb3ZlQ2xhc3MoJG1vZGFsLCAnc2hvdy1pbnB1dCcpO1xuICAkaW5wdXQudmFsdWUgPSBkZWZhdWx0UGFyYW1zLmlucHV0VmFsdWU7XG4gICRpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCBkZWZhdWx0UGFyYW1zLmlucHV0VHlwZSk7XG4gICRpbnB1dC5zZXRBdHRyaWJ1dGUoJ3BsYWNlaG9sZGVyJywgZGVmYXVsdFBhcmFtcy5pbnB1dFBsYWNlaG9sZGVyKTtcblxuICByZXNldElucHV0RXJyb3IoKTtcbn07XG5cblxudmFyIHJlc2V0SW5wdXRFcnJvciA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIC8vIElmIHByZXNzIGVudGVyID0+IGlnbm9yZVxuICBpZiAoZXZlbnQgJiYgZXZlbnQua2V5Q29kZSA9PT0gMTMpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgJG1vZGFsID0gZ2V0TW9kYWwoKTtcblxuICB2YXIgJGVycm9ySWNvbiA9ICRtb2RhbC5xdWVyeVNlbGVjdG9yKCcuc2EtaW5wdXQtZXJyb3InKTtcbiAgcmVtb3ZlQ2xhc3MoJGVycm9ySWNvbiwgJ3Nob3cnKTtcblxuICB2YXIgJGVycm9yQ29udGFpbmVyID0gJG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJy5zYS1lcnJvci1jb250YWluZXInKTtcbiAgcmVtb3ZlQ2xhc3MoJGVycm9yQ29udGFpbmVyLCAnc2hvdycpO1xufTtcblxuXG4vKlxuICogU2V0IFwibWFyZ2luLXRvcFwiLXByb3BlcnR5IG9uIG1vZGFsIGJhc2VkIG9uIGl0cyBjb21wdXRlZCBoZWlnaHRcbiAqL1xudmFyIGZpeFZlcnRpY2FsUG9zaXRpb24gPSBmdW5jdGlvbigpIHtcbiAgdmFyICRtb2RhbCA9IGdldE1vZGFsKCk7XG4gICRtb2RhbC5zdHlsZS5tYXJnaW5Ub3AgPSBnZXRUb3BNYXJnaW4oZ2V0TW9kYWwoKSk7XG59O1xuXG5cbmV4cG9ydCB7IFxuICBzd2VldEFsZXJ0SW5pdGlhbGl6ZSxcbiAgZ2V0TW9kYWwsXG4gIGdldE92ZXJsYXksXG4gIGdldElucHV0LFxuICBzZXRGb2N1c1N0eWxlLFxuICBvcGVuTW9kYWwsXG4gIHJlc2V0SW5wdXQsXG4gIHJlc2V0SW5wdXRFcnJvcixcbiAgZml4VmVydGljYWxQb3NpdGlvblxufTtcbiIsInZhciBpbmplY3RlZEhUTUwgPSBcblxuICAvLyBEYXJrIG92ZXJsYXlcbiAgYDxkaXYgY2xhc3M9XCJzd2VldC1vdmVybGF5XCIgdGFiSW5kZXg9XCItMVwiPjwvZGl2PmAgK1xuXG4gIC8vIE1vZGFsXG4gIGA8ZGl2IGNsYXNzPVwic3dlZXQtYWxlcnRcIj5gICtcblxuICAgIC8vIEVycm9yIGljb25cbiAgICBgPGRpdiBjbGFzcz1cInNhLWljb24gc2EtZXJyb3JcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2EteC1tYXJrXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwic2EtbGluZSBzYS1sZWZ0XCI+PC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNhLWxpbmUgc2EtcmlnaHRcIj48L3NwYW4+XG4gICAgICA8L3NwYW4+XG4gICAgPC9kaXY+YCArXG5cbiAgICAvLyBXYXJuaW5nIGljb25cbiAgICBgPGRpdiBjbGFzcz1cInNhLWljb24gc2Etd2FybmluZ1wiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJzYS1ib2R5XCI+PC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJzYS1kb3RcIj48L3NwYW4+XG4gICAgPC9kaXY+YCArXG5cbiAgICAvLyBJbmZvIGljb25cbiAgICBgPGRpdiBjbGFzcz1cInNhLWljb24gc2EtaW5mb1wiPjwvZGl2PmAgK1xuXG4gICAgLy8gU3VjY2VzcyBpY29uXG4gICAgYDxkaXYgY2xhc3M9XCJzYS1pY29uIHNhLXN1Y2Nlc3NcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2EtbGluZSBzYS10aXBcIj48L3NwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cInNhLWxpbmUgc2EtbG9uZ1wiPjwvc3Bhbj5cblxuICAgICAgPGRpdiBjbGFzcz1cInNhLXBsYWNlaG9sZGVyXCI+PC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwic2EtZml4XCI+PC9kaXY+XG4gICAgPC9kaXY+YCArXG5cbiAgICBgPGRpdiBjbGFzcz1cInNhLWljb24gc2EtY3VzdG9tXCI+PC9kaXY+YCArXG5cbiAgICAvLyBUaXRsZSwgdGV4dCBhbmQgaW5wdXRcbiAgICBgPGgyPlRpdGxlPC9oMj5cbiAgICA8cD5UZXh0PC9wPlxuICAgIDxmaWVsZHNldD5cbiAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIHRhYkluZGV4PVwiM1wiIC8+XG4gICAgICA8ZGl2IGNsYXNzPVwic2EtaW5wdXQtZXJyb3JcIj48L2Rpdj5cbiAgICA8L2ZpZWxkc2V0PmAgK1xuXG4gICAgLy8gSW5wdXQgZXJyb3JzXG4gICAgYDxkaXYgY2xhc3M9XCJzYS1lcnJvci1jb250YWluZXJcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpY29uXCI+ITwvZGl2PlxuICAgICAgPHA+Tm90IHZhbGlkITwvcD5cbiAgICA8L2Rpdj5gICtcblxuICAgIC8vIENhbmNlbCBhbmQgY29uZmlybSBidXR0b25zXG4gICAgYDxkaXYgY2xhc3M9XCJzYS1idXR0b24tY29udGFpbmVyXCI+XG4gICAgICA8YnV0dG9uIGNsYXNzPVwiY2FuY2VsXCIgdGFiSW5kZXg9XCIyXCI+Q2FuY2VsPC9idXR0b24+XG4gICAgICA8ZGl2IGNsYXNzPVwic2EtY29uZmlybS1idXR0b24tY29udGFpbmVyXCI+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJjb25maXJtXCIgdGFiSW5kZXg9XCIxXCI+T0s8L2J1dHRvbj5gICsgXG5cbiAgICAgICAgLy8gTG9hZGluZyBhbmltYXRpb25cbiAgICAgICAgYDxkaXYgY2xhc3M9XCJsYS1iYWxsLWZhbGxcIj5cbiAgICAgICAgICA8ZGl2PjwvZGl2PlxuICAgICAgICAgIDxkaXY+PC9kaXY+XG4gICAgICAgICAgPGRpdj48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5gICtcblxuICAvLyBFbmQgb2YgbW9kYWxcbiAgYDwvZGl2PmA7XG5cbmV4cG9ydCBkZWZhdWx0IGluamVjdGVkSFRNTDtcbiIsInZhciBhbGVydFR5cGVzID0gWydlcnJvcicsICd3YXJuaW5nJywgJ2luZm8nLCAnc3VjY2VzcycsICdpbnB1dCcsICdwcm9tcHQnXTtcblxuaW1wb3J0IHtcbiAgaXNJRThcbn0gZnJvbSAnLi91dGlscyc7XG5cbmltcG9ydCB7XG4gIGdldE1vZGFsLFxuICBnZXRJbnB1dCxcbiAgc2V0Rm9jdXNTdHlsZVxufSBmcm9tICcuL2hhbmRsZS1zd2FsLWRvbSc7XG5cbmltcG9ydCB7XG4gIGhhc0NsYXNzLCBhZGRDbGFzcywgcmVtb3ZlQ2xhc3MsXG4gIGVzY2FwZUh0bWwsXG4gIF9zaG93LCBzaG93LCBfaGlkZSwgaGlkZVxufSBmcm9tICcuL2hhbmRsZS1kb20nO1xuXG5cbi8qXG4gKiBTZXQgdHlwZSwgdGV4dCBhbmQgYWN0aW9ucyBvbiBtb2RhbFxuICovXG52YXIgc2V0UGFyYW1ldGVycyA9IGZ1bmN0aW9uKHBhcmFtcykge1xuICB2YXIgbW9kYWwgPSBnZXRNb2RhbCgpO1xuXG4gIHZhciAkdGl0bGUgPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCdoMicpO1xuICB2YXIgJHRleHQgPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCdwJyk7XG4gIHZhciAkY2FuY2VsQnRuID0gbW9kYWwucXVlcnlTZWxlY3RvcignYnV0dG9uLmNhbmNlbCcpO1xuICB2YXIgJGNvbmZpcm1CdG4gPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCdidXR0b24uY29uZmlybScpO1xuXG4gIC8qXG4gICAqIFRpdGxlXG4gICAqL1xuICAkdGl0bGUuaW5uZXJIVE1MID0gcGFyYW1zLmh0bWwgPyBwYXJhbXMudGl0bGUgOiBlc2NhcGVIdG1sKHBhcmFtcy50aXRsZSkuc3BsaXQoJ1xcbicpLmpvaW4oJzxicj4nKTtcblxuICAvKlxuICAgKiBUZXh0XG4gICAqL1xuICAkdGV4dC5pbm5lckhUTUwgPSBwYXJhbXMuaHRtbCA/IHBhcmFtcy50ZXh0IDogZXNjYXBlSHRtbChwYXJhbXMudGV4dCB8fCAnJykuc3BsaXQoJ1xcbicpLmpvaW4oJzxicj4nKTtcbiAgaWYgKHBhcmFtcy50ZXh0KSBzaG93KCR0ZXh0KTtcblxuICAvKlxuICAgKiBDdXN0b20gY2xhc3NcbiAgICovXG4gIGlmIChwYXJhbXMuY3VzdG9tQ2xhc3MpIHtcbiAgICBhZGRDbGFzcyhtb2RhbCwgcGFyYW1zLmN1c3RvbUNsYXNzKTtcbiAgICBtb2RhbC5zZXRBdHRyaWJ1dGUoJ2RhdGEtY3VzdG9tLWNsYXNzJywgcGFyYW1zLmN1c3RvbUNsYXNzKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBGaW5kIHByZXZpb3VzbHkgc2V0IGNsYXNzZXMgYW5kIHJlbW92ZSB0aGVtXG4gICAgbGV0IGN1c3RvbUNsYXNzID0gbW9kYWwuZ2V0QXR0cmlidXRlKCdkYXRhLWN1c3RvbS1jbGFzcycpO1xuICAgIHJlbW92ZUNsYXNzKG1vZGFsLCBjdXN0b21DbGFzcyk7XG4gICAgbW9kYWwuc2V0QXR0cmlidXRlKCdkYXRhLWN1c3RvbS1jbGFzcycsICcnKTtcbiAgfVxuXG4gIC8qXG4gICAqIEljb25cbiAgICovXG4gIGhpZGUobW9kYWwucXVlcnlTZWxlY3RvckFsbCgnLnNhLWljb24nKSk7XG5cbiAgaWYgKHBhcmFtcy50eXBlICYmICFpc0lFOCgpKSB7XG5cbiAgICBsZXQgdmFsaWRUeXBlID0gZmFsc2U7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFsZXJ0VHlwZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChwYXJhbXMudHlwZSA9PT0gYWxlcnRUeXBlc1tpXSkge1xuICAgICAgICB2YWxpZFR5cGUgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXZhbGlkVHlwZSkge1xuICAgICAgbG9nU3RyKCdVbmtub3duIGFsZXJ0IHR5cGU6ICcgKyBwYXJhbXMudHlwZSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbGV0IHR5cGVzV2l0aEljb25zID0gWydzdWNjZXNzJywgJ2Vycm9yJywgJ3dhcm5pbmcnLCAnaW5mbyddO1xuICAgIGxldCAkaWNvbjtcblxuICAgIGlmICh0eXBlc1dpdGhJY29ucy5pbmRleE9mKHBhcmFtcy50eXBlKSAhPT0gLTEpIHtcbiAgICAgICRpY29uID0gbW9kYWwucXVlcnlTZWxlY3RvcignLnNhLWljb24uJyArICdzYS0nICsgcGFyYW1zLnR5cGUpO1xuICAgICAgc2hvdygkaWNvbik7XG4gICAgfVxuXG4gICAgbGV0ICRpbnB1dCA9IGdldElucHV0KCk7XG5cbiAgICAvLyBBbmltYXRlIGljb25cbiAgICBzd2l0Y2ggKHBhcmFtcy50eXBlKSB7XG5cbiAgICAgIGNhc2UgJ3N1Y2Nlc3MnOlxuICAgICAgICBhZGRDbGFzcygkaWNvbiwgJ2FuaW1hdGUnKTtcbiAgICAgICAgYWRkQ2xhc3MoJGljb24ucXVlcnlTZWxlY3RvcignLnNhLXRpcCcpLCAnYW5pbWF0ZVN1Y2Nlc3NUaXAnKTtcbiAgICAgICAgYWRkQ2xhc3MoJGljb24ucXVlcnlTZWxlY3RvcignLnNhLWxvbmcnKSwgJ2FuaW1hdGVTdWNjZXNzTG9uZycpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnZXJyb3InOlxuICAgICAgICBhZGRDbGFzcygkaWNvbiwgJ2FuaW1hdGVFcnJvckljb24nKTtcbiAgICAgICAgYWRkQ2xhc3MoJGljb24ucXVlcnlTZWxlY3RvcignLnNhLXgtbWFyaycpLCAnYW5pbWF0ZVhNYXJrJyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICd3YXJuaW5nJzpcbiAgICAgICAgYWRkQ2xhc3MoJGljb24sICdwdWxzZVdhcm5pbmcnKTtcbiAgICAgICAgYWRkQ2xhc3MoJGljb24ucXVlcnlTZWxlY3RvcignLnNhLWJvZHknKSwgJ3B1bHNlV2FybmluZ0lucycpO1xuICAgICAgICBhZGRDbGFzcygkaWNvbi5xdWVyeVNlbGVjdG9yKCcuc2EtZG90JyksICdwdWxzZVdhcm5pbmdJbnMnKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2lucHV0JzpcbiAgICAgIGNhc2UgJ3Byb21wdCc6XG4gICAgICAgICRpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCBwYXJhbXMuaW5wdXRUeXBlKTtcbiAgICAgICAgJGlucHV0LnZhbHVlID0gcGFyYW1zLmlucHV0VmFsdWU7XG4gICAgICAgICRpbnB1dC5zZXRBdHRyaWJ1dGUoJ3BsYWNlaG9sZGVyJywgcGFyYW1zLmlucHV0UGxhY2Vob2xkZXIpO1xuICAgICAgICBhZGRDbGFzcyhtb2RhbCwgJ3Nob3ctaW5wdXQnKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgJGlucHV0LmZvY3VzKCk7XG4gICAgICAgICAgJGlucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgc3dhbC5yZXNldElucHV0RXJyb3IpO1xuICAgICAgICB9LCA0MDApO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvKlxuICAgKiBDdXN0b20gaW1hZ2VcbiAgICovXG4gIGlmIChwYXJhbXMuaW1hZ2VVcmwpIHtcbiAgICBsZXQgJGN1c3RvbUljb24gPSBtb2RhbC5xdWVyeVNlbGVjdG9yKCcuc2EtaWNvbi5zYS1jdXN0b20nKTtcblxuICAgICRjdXN0b21JY29uLnN0eWxlLmJhY2tncm91bmRJbWFnZSA9ICd1cmwoJyArIHBhcmFtcy5pbWFnZVVybCArICcpJztcbiAgICBzaG93KCRjdXN0b21JY29uKTtcblxuICAgIGxldCBfaW1nV2lkdGggPSA4MDtcbiAgICBsZXQgX2ltZ0hlaWdodCA9IDgwO1xuXG4gICAgaWYgKHBhcmFtcy5pbWFnZVNpemUpIHtcbiAgICAgIGxldCBkaW1lbnNpb25zID0gcGFyYW1zLmltYWdlU2l6ZS50b1N0cmluZygpLnNwbGl0KCd4Jyk7XG4gICAgICBsZXQgaW1nV2lkdGggPSBkaW1lbnNpb25zWzBdO1xuICAgICAgbGV0IGltZ0hlaWdodCA9IGRpbWVuc2lvbnNbMV07XG5cbiAgICAgIGlmICghaW1nV2lkdGggfHwgIWltZ0hlaWdodCkge1xuICAgICAgICBsb2dTdHIoJ1BhcmFtZXRlciBpbWFnZVNpemUgZXhwZWN0cyB2YWx1ZSB3aXRoIGZvcm1hdCBXSURUSHhIRUlHSFQsIGdvdCAnICsgcGFyYW1zLmltYWdlU2l6ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfaW1nV2lkdGggPSBpbWdXaWR0aDtcbiAgICAgICAgX2ltZ0hlaWdodCA9IGltZ0hlaWdodDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAkY3VzdG9tSWNvbi5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgJGN1c3RvbUljb24uZ2V0QXR0cmlidXRlKCdzdHlsZScpICsgJ3dpZHRoOicgKyBfaW1nV2lkdGggKyAncHg7IGhlaWdodDonICsgX2ltZ0hlaWdodCArICdweCcpO1xuICB9XG5cbiAgLypcbiAgICogU2hvdyBjYW5jZWwgYnV0dG9uP1xuICAgKi9cbiAgbW9kYWwuc2V0QXR0cmlidXRlKCdkYXRhLWhhcy1jYW5jZWwtYnV0dG9uJywgcGFyYW1zLnNob3dDYW5jZWxCdXR0b24pO1xuICBpZiAocGFyYW1zLnNob3dDYW5jZWxCdXR0b24pIHtcbiAgICAkY2FuY2VsQnRuLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJztcbiAgfSBlbHNlIHtcbiAgICBoaWRlKCRjYW5jZWxCdG4pO1xuICB9XG5cbiAgLypcbiAgICogU2hvdyBjb25maXJtIGJ1dHRvbj9cbiAgICovXG4gIG1vZGFsLnNldEF0dHJpYnV0ZSgnZGF0YS1oYXMtY29uZmlybS1idXR0b24nLCBwYXJhbXMuc2hvd0NvbmZpcm1CdXR0b24pO1xuICBpZiAocGFyYW1zLnNob3dDb25maXJtQnV0dG9uKSB7XG4gICAgJGNvbmZpcm1CdG4uc3R5bGUuZGlzcGxheSA9ICdpbmxpbmUtYmxvY2snO1xuICB9IGVsc2Uge1xuICAgIGhpZGUoJGNvbmZpcm1CdG4pO1xuICB9XG5cbiAgLypcbiAgICogQ3VzdG9tIHRleHQgb24gY2FuY2VsL2NvbmZpcm0gYnV0dG9uc1xuICAgKi9cbiAgaWYgKHBhcmFtcy5jYW5jZWxCdXR0b25UZXh0KSB7XG4gICAgJGNhbmNlbEJ0bi5pbm5lckhUTUwgPSBlc2NhcGVIdG1sKHBhcmFtcy5jYW5jZWxCdXR0b25UZXh0KTtcbiAgfVxuICBpZiAocGFyYW1zLmNvbmZpcm1CdXR0b25UZXh0KSB7XG4gICAgJGNvbmZpcm1CdG4uaW5uZXJIVE1MID0gZXNjYXBlSHRtbChwYXJhbXMuY29uZmlybUJ1dHRvblRleHQpO1xuICB9XG5cbiAgLypcbiAgICogQ3VzdG9tIGNvbG9yIG9uIGNvbmZpcm0gYnV0dG9uXG4gICAqL1xuICBpZiAocGFyYW1zLmNvbmZpcm1CdXR0b25Db2xvcikge1xuICAgIC8vIFNldCBjb25maXJtIGJ1dHRvbiB0byBzZWxlY3RlZCBiYWNrZ3JvdW5kIGNvbG9yXG4gICAgJGNvbmZpcm1CdG4uc3R5bGUuYmFja2dyb3VuZENvbG9yID0gcGFyYW1zLmNvbmZpcm1CdXR0b25Db2xvcjtcblxuICAgIC8vIFNldCB0aGUgY29uZmlybSBidXR0b24gY29sb3IgdG8gdGhlIGxvYWRpbmcgcmluZ1xuICAgICRjb25maXJtQnRuLnN0eWxlLmJvcmRlckxlZnRDb2xvciA9IHBhcmFtcy5jb25maXJtTG9hZGluZ0J1dHRvbkNvbG9yO1xuICAgICRjb25maXJtQnRuLnN0eWxlLmJvcmRlclJpZ2h0Q29sb3IgPSBwYXJhbXMuY29uZmlybUxvYWRpbmdCdXR0b25Db2xvcjtcblxuICAgIC8vIFNldCBib3gtc2hhZG93IHRvIGRlZmF1bHQgZm9jdXNlZCBidXR0b25cbiAgICBzZXRGb2N1c1N0eWxlKCRjb25maXJtQnRuLCBwYXJhbXMuY29uZmlybUJ1dHRvbkNvbG9yKTtcbiAgfVxuXG4gIC8qXG4gICAqIEFsbG93IG91dHNpZGUgY2xpY2tcbiAgICovXG4gIG1vZGFsLnNldEF0dHJpYnV0ZSgnZGF0YS1hbGxvdy1vdXRzaWRlLWNsaWNrJywgcGFyYW1zLmFsbG93T3V0c2lkZUNsaWNrKTtcblxuICAvKlxuICAgKiBDYWxsYmFjayBmdW5jdGlvblxuICAgKi9cbiAgdmFyIGhhc0RvbmVGdW5jdGlvbiA9IHBhcmFtcy5kb25lRnVuY3Rpb24gPyB0cnVlIDogZmFsc2U7XG4gIG1vZGFsLnNldEF0dHJpYnV0ZSgnZGF0YS1oYXMtZG9uZS1mdW5jdGlvbicsIGhhc0RvbmVGdW5jdGlvbik7XG5cbiAgLypcbiAgICogQW5pbWF0aW9uXG4gICAqL1xuICBpZiAoIXBhcmFtcy5hbmltYXRpb24pIHtcbiAgICBtb2RhbC5zZXRBdHRyaWJ1dGUoJ2RhdGEtYW5pbWF0aW9uJywgJ25vbmUnKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgcGFyYW1zLmFuaW1hdGlvbiA9PT0gJ3N0cmluZycpIHtcbiAgICBtb2RhbC5zZXRBdHRyaWJ1dGUoJ2RhdGEtYW5pbWF0aW9uJywgcGFyYW1zLmFuaW1hdGlvbik7IC8vIEN1c3RvbSBhbmltYXRpb25cbiAgfSBlbHNlIHtcbiAgICBtb2RhbC5zZXRBdHRyaWJ1dGUoJ2RhdGEtYW5pbWF0aW9uJywgJ3BvcCcpO1xuICB9XG5cbiAgLypcbiAgICogVGltZXJcbiAgICovXG4gIG1vZGFsLnNldEF0dHJpYnV0ZSgnZGF0YS10aW1lcicsIHBhcmFtcy50aW1lcik7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBzZXRQYXJhbWV0ZXJzO1xuIiwiLypcbiAqIEFsbG93IHVzZXIgdG8gcGFzcyB0aGVpciBvd24gcGFyYW1zXG4gKi9cbnZhciBleHRlbmQgPSBmdW5jdGlvbihhLCBiKSB7XG4gIGZvciAodmFyIGtleSBpbiBiKSB7XG4gICAgaWYgKGIuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgYVtrZXldID0gYltrZXldO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYTtcbn07XG5cbi8qXG4gKiBDb252ZXJ0IEhFWCBjb2RlcyB0byBSR0IgdmFsdWVzICgjMDAwMDAwIC0+IHJnYigwLDAsMCkpXG4gKi9cbnZhciBoZXhUb1JnYiA9IGZ1bmN0aW9uKGhleCkge1xuICB2YXIgcmVzdWx0ID0gL14jPyhbYS1mXFxkXXsyfSkoW2EtZlxcZF17Mn0pKFthLWZcXGRdezJ9KSQvaS5leGVjKGhleCk7XG4gIHJldHVybiByZXN1bHQgPyBwYXJzZUludChyZXN1bHRbMV0sIDE2KSArICcsICcgKyBwYXJzZUludChyZXN1bHRbMl0sIDE2KSArICcsICcgKyBwYXJzZUludChyZXN1bHRbM10sIDE2KSA6IG51bGw7XG59O1xuXG4vKlxuICogQ2hlY2sgaWYgdGhlIHVzZXIgaXMgdXNpbmcgSW50ZXJuZXQgRXhwbG9yZXIgOCAoZm9yIGZhbGxiYWNrcylcbiAqL1xudmFyIGlzSUU4ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAod2luZG93LmF0dGFjaEV2ZW50ICYmICF3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcik7XG59O1xuXG4vKlxuICogSUUgY29tcGF0aWJsZSBsb2dnaW5nIGZvciBkZXZlbG9wZXJzXG4gKi9cbnZhciBsb2dTdHIgPSBmdW5jdGlvbihzdHJpbmcpIHtcbiAgaWYgKHdpbmRvdy5jb25zb2xlKSB7XG4gICAgLy8gSUUuLi5cbiAgICB3aW5kb3cuY29uc29sZS5sb2coJ1N3ZWV0QWxlcnQ6ICcgKyBzdHJpbmcpO1xuICB9XG59O1xuXG4vKlxuICogU2V0IGhvdmVyLCBhY3RpdmUgYW5kIGZvY3VzLXN0YXRlcyBmb3IgYnV0dG9ucyBcbiAqIChzb3VyY2U6IGh0dHA6Ly93d3cuc2l0ZXBvaW50LmNvbS9qYXZhc2NyaXB0LWdlbmVyYXRlLWxpZ2h0ZXItZGFya2VyLWNvbG9yKVxuICovXG52YXIgY29sb3JMdW1pbmFuY2UgPSBmdW5jdGlvbihoZXgsIGx1bSkge1xuICAvLyBWYWxpZGF0ZSBoZXggc3RyaW5nXG4gIGhleCA9IFN0cmluZyhoZXgpLnJlcGxhY2UoL1teMC05YS1mXS9naSwgJycpO1xuICBpZiAoaGV4Lmxlbmd0aCA8IDYpIHtcbiAgICBoZXggPSBoZXhbMF0gKyBoZXhbMF0gKyBoZXhbMV0gKyBoZXhbMV0gKyBoZXhbMl0gKyBoZXhbMl07XG4gIH1cbiAgbHVtID0gbHVtIHx8IDA7XG5cbiAgLy8gQ29udmVydCB0byBkZWNpbWFsIGFuZCBjaGFuZ2UgbHVtaW5vc2l0eVxuICB2YXIgcmdiID0gJyMnO1xuICB2YXIgYztcbiAgdmFyIGk7XG5cbiAgZm9yIChpID0gMDsgaSA8IDM7IGkrKykge1xuICAgIGMgPSBwYXJzZUludChoZXguc3Vic3RyKGkgKiAyLCAyKSwgMTYpO1xuICAgIGMgPSBNYXRoLnJvdW5kKE1hdGgubWluKE1hdGgubWF4KDAsIGMgKyBjICogbHVtKSwgMjU1KSkudG9TdHJpbmcoMTYpO1xuICAgIHJnYiArPSAoJzAwJyArIGMpLnN1YnN0cihjLmxlbmd0aCk7XG4gIH1cblxuICByZXR1cm4gcmdiO1xufTtcblxuXG5leHBvcnQge1xuICBleHRlbmQsXG4gIGhleFRvUmdiLFxuICBpc0lFOCxcbiAgbG9nU3RyLFxuICBjb2xvckx1bWluYW5jZVxufTtcbiJdfQ==\n\n  \n  /*\n   * Use SweetAlert with RequireJS\n   */\n  \n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return sweetAlert;\n    });\n  } else if (typeof module !== 'undefined' && module.exports) {\n    module.exports = sweetAlert;\n  }\n\n})(window, document);"
  },
  {
    "path": "static/assets/plugins/sweetalert/dist/sweetalert.css",
    "content": "body.stop-scrolling {\n  height: 100%;\n  overflow: hidden; }\n\n.sweet-overlay {\n  background-color: black;\n  /* IE8 */\n  -ms-filter: \"progid:DXImageTransform.Microsoft.Alpha(Opacity=40)\";\n  /* IE8 */\n  background-color: rgba(0, 0, 0, 0.4);\n  position: fixed;\n  left: 0;\n  right: 0;\n  top: 0;\n  bottom: 0;\n  display: none;\n  z-index: 10000; }\n\n.sweet-alert {\n  background-color: white;\n  font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;\n  width: 478px;\n  padding: 17px;\n  border-radius: 5px;\n  text-align: center;\n  position: fixed;\n  left: 50%;\n  top: 50%;\n  margin-left: -256px;\n  margin-top: -200px;\n  overflow: hidden;\n  display: none;\n  z-index: 99999; }\n  @media all and (max-width: 540px) {\n    .sweet-alert {\n      width: auto;\n      margin-left: 0;\n      margin-right: 0;\n      left: 15px;\n      right: 15px; } }\n  .sweet-alert h2 {\n    color: #575757;\n    font-size: 30px;\n    text-align: center;\n    font-weight: 600;\n    text-transform: none;\n    position: relative;\n    margin: 25px 0;\n    padding: 0;\n    line-height: 40px;\n    display: block; }\n  .sweet-alert p {\n    color: #797979;\n    font-size: 16px;\n    text-align: center;\n    font-weight: 300;\n    position: relative;\n    text-align: inherit;\n    float: none;\n    margin: 0;\n    padding: 0;\n    line-height: normal; }\n  .sweet-alert fieldset {\n    border: none;\n    position: relative; }\n  .sweet-alert .sa-error-container {\n    background-color: #f1f1f1;\n    margin-left: -17px;\n    margin-right: -17px;\n    overflow: hidden;\n    padding: 0 10px;\n    max-height: 0;\n    webkit-transition: padding 0.15s, max-height 0.15s;\n    transition: padding 0.15s, max-height 0.15s; }\n    .sweet-alert .sa-error-container.show {\n      padding: 10px 0;\n      max-height: 100px;\n      webkit-transition: padding 0.2s, max-height 0.2s;\n      transition: padding 0.25s, max-height 0.25s; }\n    .sweet-alert .sa-error-container .icon {\n      display: inline-block;\n      width: 24px;\n      height: 24px;\n      border-radius: 50%;\n      background-color: #ea7d7d;\n      color: white;\n      line-height: 24px;\n      text-align: center;\n      margin-right: 3px; }\n    .sweet-alert .sa-error-container p {\n      display: inline-block; }\n  .sweet-alert .sa-input-error {\n    position: absolute;\n    top: 29px;\n    right: 26px;\n    width: 20px;\n    height: 20px;\n    opacity: 0;\n    -webkit-transform: scale(0.5);\n    transform: scale(0.5);\n    -webkit-transform-origin: 50% 50%;\n    transform-origin: 50% 50%;\n    -webkit-transition: all 0.1s;\n    transition: all 0.1s; }\n    .sweet-alert .sa-input-error::before, .sweet-alert .sa-input-error::after {\n      content: \"\";\n      width: 20px;\n      height: 6px;\n      background-color: #f06e57;\n      border-radius: 3px;\n      position: absolute;\n      top: 50%;\n      margin-top: -4px;\n      left: 50%;\n      margin-left: -9px; }\n    .sweet-alert .sa-input-error::before {\n      -webkit-transform: rotate(-45deg);\n      transform: rotate(-45deg); }\n    .sweet-alert .sa-input-error::after {\n      -webkit-transform: rotate(45deg);\n      transform: rotate(45deg); }\n    .sweet-alert .sa-input-error.show {\n      opacity: 1;\n      -webkit-transform: scale(1);\n      transform: scale(1); }\n  .sweet-alert input {\n    width: 100%;\n    box-sizing: border-box;\n    border-radius: 3px;\n    border: 1px solid #d7d7d7;\n    height: 43px;\n    margin-top: 10px;\n    margin-bottom: 17px;\n    font-size: 18px;\n    box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.06);\n    padding: 0 12px;\n    display: none;\n    -webkit-transition: all 0.3s;\n    transition: all 0.3s; }\n    .sweet-alert input:focus {\n      outline: none;\n      box-shadow: 0px 0px 3px #c4e6f5;\n      border: 1px solid #b4dbed; }\n      .sweet-alert input:focus::-moz-placeholder {\n        transition: opacity 0.3s 0.03s ease;\n        opacity: 0.5; }\n      .sweet-alert input:focus:-ms-input-placeholder {\n        transition: opacity 0.3s 0.03s ease;\n        opacity: 0.5; }\n      .sweet-alert input:focus::-webkit-input-placeholder {\n        transition: opacity 0.3s 0.03s ease;\n        opacity: 0.5; }\n    .sweet-alert input::-moz-placeholder {\n      color: #bdbdbd; }\n    .sweet-alert input:-ms-input-placeholder {\n      color: #bdbdbd; }\n    .sweet-alert input::-webkit-input-placeholder {\n      color: #bdbdbd; }\n  .sweet-alert.show-input input {\n    display: block; }\n  .sweet-alert .sa-confirm-button-container {\n    display: inline-block;\n    position: relative; }\n  .sweet-alert .la-ball-fall {\n    position: absolute;\n    left: 50%;\n    top: 50%;\n    margin-left: -27px;\n    margin-top: 4px;\n    opacity: 0;\n    visibility: hidden; }\n  .sweet-alert button {\n    background-color: #8CD4F5;\n    color: white;\n    border: none;\n    box-shadow: none;\n    font-size: 17px;\n    font-weight: 500;\n    -webkit-border-radius: 4px;\n    border-radius: 5px;\n    padding: 10px 32px;\n    margin: 26px 5px 0 5px;\n    cursor: pointer; }\n    .sweet-alert button:focus {\n      outline: none;\n      box-shadow: 0 0 2px rgba(128, 179, 235, 0.5), inset 0 0 0 1px rgba(0, 0, 0, 0.05); }\n    .sweet-alert button:hover {\n      background-color: #7ecff4; }\n    .sweet-alert button:active {\n      background-color: #5dc2f1; }\n    .sweet-alert button.cancel {\n      background-color: #C1C1C1; }\n      .sweet-alert button.cancel:hover {\n        background-color: #b9b9b9; }\n      .sweet-alert button.cancel:active {\n        background-color: #a8a8a8; }\n      .sweet-alert button.cancel:focus {\n        box-shadow: rgba(197, 205, 211, 0.8) 0px 0px 2px, rgba(0, 0, 0, 0.0470588) 0px 0px 0px 1px inset !important; }\n    .sweet-alert button[disabled] {\n      opacity: .6;\n      cursor: default; }\n    .sweet-alert button.confirm[disabled] {\n      color: transparent; }\n      .sweet-alert button.confirm[disabled] ~ .la-ball-fall {\n        opacity: 1;\n        visibility: visible;\n        transition-delay: 0s; }\n    .sweet-alert button::-moz-focus-inner {\n      border: 0; }\n  .sweet-alert[data-has-cancel-button=false] button {\n    box-shadow: none !important; }\n  .sweet-alert[data-has-confirm-button=false][data-has-cancel-button=false] {\n    padding-bottom: 40px; }\n  .sweet-alert .sa-icon {\n    width: 80px;\n    height: 80px;\n    border: 4px solid gray;\n    -webkit-border-radius: 40px;\n    border-radius: 40px;\n    border-radius: 50%;\n    margin: 20px auto;\n    padding: 0;\n    position: relative;\n    box-sizing: content-box; }\n    .sweet-alert .sa-icon.sa-error {\n      border-color: #F27474; }\n      .sweet-alert .sa-icon.sa-error .sa-x-mark {\n        position: relative;\n        display: block; }\n      .sweet-alert .sa-icon.sa-error .sa-line {\n        position: absolute;\n        height: 5px;\n        width: 47px;\n        background-color: #F27474;\n        display: block;\n        top: 37px;\n        border-radius: 2px; }\n        .sweet-alert .sa-icon.sa-error .sa-line.sa-left {\n          -webkit-transform: rotate(45deg);\n          transform: rotate(45deg);\n          left: 17px; }\n        .sweet-alert .sa-icon.sa-error .sa-line.sa-right {\n          -webkit-transform: rotate(-45deg);\n          transform: rotate(-45deg);\n          right: 16px; }\n    .sweet-alert .sa-icon.sa-warning {\n      border-color: #F8BB86; }\n      .sweet-alert .sa-icon.sa-warning .sa-body {\n        position: absolute;\n        width: 5px;\n        height: 47px;\n        left: 50%;\n        top: 10px;\n        -webkit-border-radius: 2px;\n        border-radius: 2px;\n        margin-left: -2px;\n        background-color: #F8BB86; }\n      .sweet-alert .sa-icon.sa-warning .sa-dot {\n        position: absolute;\n        width: 7px;\n        height: 7px;\n        -webkit-border-radius: 50%;\n        border-radius: 50%;\n        margin-left: -3px;\n        left: 50%;\n        bottom: 10px;\n        background-color: #F8BB86; }\n    .sweet-alert .sa-icon.sa-info {\n      border-color: #C9DAE1; }\n      .sweet-alert .sa-icon.sa-info::before {\n        content: \"\";\n        position: absolute;\n        width: 5px;\n        height: 29px;\n        left: 50%;\n        bottom: 17px;\n        border-radius: 2px;\n        margin-left: -2px;\n        background-color: #C9DAE1; }\n      .sweet-alert .sa-icon.sa-info::after {\n        content: \"\";\n        position: absolute;\n        width: 7px;\n        height: 7px;\n        border-radius: 50%;\n        margin-left: -3px;\n        top: 19px;\n        background-color: #C9DAE1; }\n    .sweet-alert .sa-icon.sa-success {\n      border-color: #A5DC86; }\n      .sweet-alert .sa-icon.sa-success::before, .sweet-alert .sa-icon.sa-success::after {\n        content: '';\n        -webkit-border-radius: 40px;\n        border-radius: 40px;\n        border-radius: 50%;\n        position: absolute;\n        width: 60px;\n        height: 120px;\n        background: white;\n        -webkit-transform: rotate(45deg);\n        transform: rotate(45deg); }\n      .sweet-alert .sa-icon.sa-success::before {\n        -webkit-border-radius: 120px 0 0 120px;\n        border-radius: 120px 0 0 120px;\n        top: -7px;\n        left: -33px;\n        -webkit-transform: rotate(-45deg);\n        transform: rotate(-45deg);\n        -webkit-transform-origin: 60px 60px;\n        transform-origin: 60px 60px; }\n      .sweet-alert .sa-icon.sa-success::after {\n        -webkit-border-radius: 0 120px 120px 0;\n        border-radius: 0 120px 120px 0;\n        top: -11px;\n        left: 30px;\n        -webkit-transform: rotate(-45deg);\n        transform: rotate(-45deg);\n        -webkit-transform-origin: 0px 60px;\n        transform-origin: 0px 60px; }\n      .sweet-alert .sa-icon.sa-success .sa-placeholder {\n        width: 80px;\n        height: 80px;\n        border: 4px solid rgba(165, 220, 134, 0.2);\n        -webkit-border-radius: 40px;\n        border-radius: 40px;\n        border-radius: 50%;\n        box-sizing: content-box;\n        position: absolute;\n        left: -4px;\n        top: -4px;\n        z-index: 2; }\n      .sweet-alert .sa-icon.sa-success .sa-fix {\n        width: 5px;\n        height: 90px;\n        background-color: white;\n        position: absolute;\n        left: 28px;\n        top: 8px;\n        z-index: 1;\n        -webkit-transform: rotate(-45deg);\n        transform: rotate(-45deg); }\n      .sweet-alert .sa-icon.sa-success .sa-line {\n        height: 5px;\n        background-color: #A5DC86;\n        display: block;\n        border-radius: 2px;\n        position: absolute;\n        z-index: 2; }\n        .sweet-alert .sa-icon.sa-success .sa-line.sa-tip {\n          width: 25px;\n          left: 14px;\n          top: 46px;\n          -webkit-transform: rotate(45deg);\n          transform: rotate(45deg); }\n        .sweet-alert .sa-icon.sa-success .sa-line.sa-long {\n          width: 47px;\n          right: 8px;\n          top: 38px;\n          -webkit-transform: rotate(-45deg);\n          transform: rotate(-45deg); }\n    .sweet-alert .sa-icon.sa-custom {\n      background-size: contain;\n      border-radius: 0;\n      border: none;\n      background-position: center center;\n      background-repeat: no-repeat; }\n\n/*\n * Animations\n */\n@-webkit-keyframes showSweetAlert {\n  0% {\n    transform: scale(0.7);\n    -webkit-transform: scale(0.7); }\n  45% {\n    transform: scale(1.05);\n    -webkit-transform: scale(1.05); }\n  80% {\n    transform: scale(0.95);\n    -webkit-transform: scale(0.95); }\n  100% {\n    transform: scale(1);\n    -webkit-transform: scale(1); } }\n\n@keyframes showSweetAlert {\n  0% {\n    transform: scale(0.7);\n    -webkit-transform: scale(0.7); }\n  45% {\n    transform: scale(1.05);\n    -webkit-transform: scale(1.05); }\n  80% {\n    transform: scale(0.95);\n    -webkit-transform: scale(0.95); }\n  100% {\n    transform: scale(1);\n    -webkit-transform: scale(1); } }\n\n@-webkit-keyframes hideSweetAlert {\n  0% {\n    transform: scale(1);\n    -webkit-transform: scale(1); }\n  100% {\n    transform: scale(0.5);\n    -webkit-transform: scale(0.5); } }\n\n@keyframes hideSweetAlert {\n  0% {\n    transform: scale(1);\n    -webkit-transform: scale(1); }\n  100% {\n    transform: scale(0.5);\n    -webkit-transform: scale(0.5); } }\n\n@-webkit-keyframes slideFromTop {\n  0% {\n    top: 0%; }\n  100% {\n    top: 50%; } }\n\n@keyframes slideFromTop {\n  0% {\n    top: 0%; }\n  100% {\n    top: 50%; } }\n\n@-webkit-keyframes slideToTop {\n  0% {\n    top: 50%; }\n  100% {\n    top: 0%; } }\n\n@keyframes slideToTop {\n  0% {\n    top: 50%; }\n  100% {\n    top: 0%; } }\n\n@-webkit-keyframes slideFromBottom {\n  0% {\n    top: 70%; }\n  100% {\n    top: 50%; } }\n\n@keyframes slideFromBottom {\n  0% {\n    top: 70%; }\n  100% {\n    top: 50%; } }\n\n@-webkit-keyframes slideToBottom {\n  0% {\n    top: 50%; }\n  100% {\n    top: 70%; } }\n\n@keyframes slideToBottom {\n  0% {\n    top: 50%; }\n  100% {\n    top: 70%; } }\n\n.showSweetAlert[data-animation=pop] {\n  -webkit-animation: showSweetAlert 0.3s;\n  animation: showSweetAlert 0.3s; }\n\n.showSweetAlert[data-animation=none] {\n  -webkit-animation: none;\n  animation: none; }\n\n.showSweetAlert[data-animation=slide-from-top] {\n  -webkit-animation: slideFromTop 0.3s;\n  animation: slideFromTop 0.3s; }\n\n.showSweetAlert[data-animation=slide-from-bottom] {\n  -webkit-animation: slideFromBottom 0.3s;\n  animation: slideFromBottom 0.3s; }\n\n.hideSweetAlert[data-animation=pop] {\n  -webkit-animation: hideSweetAlert 0.2s;\n  animation: hideSweetAlert 0.2s; }\n\n.hideSweetAlert[data-animation=none] {\n  -webkit-animation: none;\n  animation: none; }\n\n.hideSweetAlert[data-animation=slide-from-top] {\n  -webkit-animation: slideToTop 0.4s;\n  animation: slideToTop 0.4s; }\n\n.hideSweetAlert[data-animation=slide-from-bottom] {\n  -webkit-animation: slideToBottom 0.3s;\n  animation: slideToBottom 0.3s; }\n\n@-webkit-keyframes animateSuccessTip {\n  0% {\n    width: 0;\n    left: 1px;\n    top: 19px; }\n  54% {\n    width: 0;\n    left: 1px;\n    top: 19px; }\n  70% {\n    width: 50px;\n    left: -8px;\n    top: 37px; }\n  84% {\n    width: 17px;\n    left: 21px;\n    top: 48px; }\n  100% {\n    width: 25px;\n    left: 14px;\n    top: 45px; } }\n\n@keyframes animateSuccessTip {\n  0% {\n    width: 0;\n    left: 1px;\n    top: 19px; }\n  54% {\n    width: 0;\n    left: 1px;\n    top: 19px; }\n  70% {\n    width: 50px;\n    left: -8px;\n    top: 37px; }\n  84% {\n    width: 17px;\n    left: 21px;\n    top: 48px; }\n  100% {\n    width: 25px;\n    left: 14px;\n    top: 45px; } }\n\n@-webkit-keyframes animateSuccessLong {\n  0% {\n    width: 0;\n    right: 46px;\n    top: 54px; }\n  65% {\n    width: 0;\n    right: 46px;\n    top: 54px; }\n  84% {\n    width: 55px;\n    right: 0px;\n    top: 35px; }\n  100% {\n    width: 47px;\n    right: 8px;\n    top: 38px; } }\n\n@keyframes animateSuccessLong {\n  0% {\n    width: 0;\n    right: 46px;\n    top: 54px; }\n  65% {\n    width: 0;\n    right: 46px;\n    top: 54px; }\n  84% {\n    width: 55px;\n    right: 0px;\n    top: 35px; }\n  100% {\n    width: 47px;\n    right: 8px;\n    top: 38px; } }\n\n@-webkit-keyframes rotatePlaceholder {\n  0% {\n    transform: rotate(-45deg);\n    -webkit-transform: rotate(-45deg); }\n  5% {\n    transform: rotate(-45deg);\n    -webkit-transform: rotate(-45deg); }\n  12% {\n    transform: rotate(-405deg);\n    -webkit-transform: rotate(-405deg); }\n  100% {\n    transform: rotate(-405deg);\n    -webkit-transform: rotate(-405deg); } }\n\n@keyframes rotatePlaceholder {\n  0% {\n    transform: rotate(-45deg);\n    -webkit-transform: rotate(-45deg); }\n  5% {\n    transform: rotate(-45deg);\n    -webkit-transform: rotate(-45deg); }\n  12% {\n    transform: rotate(-405deg);\n    -webkit-transform: rotate(-405deg); }\n  100% {\n    transform: rotate(-405deg);\n    -webkit-transform: rotate(-405deg); } }\n\n.animateSuccessTip {\n  -webkit-animation: animateSuccessTip 0.75s;\n  animation: animateSuccessTip 0.75s; }\n\n.animateSuccessLong {\n  -webkit-animation: animateSuccessLong 0.75s;\n  animation: animateSuccessLong 0.75s; }\n\n.sa-icon.sa-success.animate::after {\n  -webkit-animation: rotatePlaceholder 4.25s ease-in;\n  animation: rotatePlaceholder 4.25s ease-in; }\n\n@-webkit-keyframes animateErrorIcon {\n  0% {\n    transform: rotateX(100deg);\n    -webkit-transform: rotateX(100deg);\n    opacity: 0; }\n  100% {\n    transform: rotateX(0deg);\n    -webkit-transform: rotateX(0deg);\n    opacity: 1; } }\n\n@keyframes animateErrorIcon {\n  0% {\n    transform: rotateX(100deg);\n    -webkit-transform: rotateX(100deg);\n    opacity: 0; }\n  100% {\n    transform: rotateX(0deg);\n    -webkit-transform: rotateX(0deg);\n    opacity: 1; } }\n\n.animateErrorIcon {\n  -webkit-animation: animateErrorIcon 0.5s;\n  animation: animateErrorIcon 0.5s; }\n\n@-webkit-keyframes animateXMark {\n  0% {\n    transform: scale(0.4);\n    -webkit-transform: scale(0.4);\n    margin-top: 26px;\n    opacity: 0; }\n  50% {\n    transform: scale(0.4);\n    -webkit-transform: scale(0.4);\n    margin-top: 26px;\n    opacity: 0; }\n  80% {\n    transform: scale(1.15);\n    -webkit-transform: scale(1.15);\n    margin-top: -6px; }\n  100% {\n    transform: scale(1);\n    -webkit-transform: scale(1);\n    margin-top: 0;\n    opacity: 1; } }\n\n@keyframes animateXMark {\n  0% {\n    transform: scale(0.4);\n    -webkit-transform: scale(0.4);\n    margin-top: 26px;\n    opacity: 0; }\n  50% {\n    transform: scale(0.4);\n    -webkit-transform: scale(0.4);\n    margin-top: 26px;\n    opacity: 0; }\n  80% {\n    transform: scale(1.15);\n    -webkit-transform: scale(1.15);\n    margin-top: -6px; }\n  100% {\n    transform: scale(1);\n    -webkit-transform: scale(1);\n    margin-top: 0;\n    opacity: 1; } }\n\n.animateXMark {\n  -webkit-animation: animateXMark 0.5s;\n  animation: animateXMark 0.5s; }\n\n@-webkit-keyframes pulseWarning {\n  0% {\n    border-color: #F8D486; }\n  100% {\n    border-color: #F8BB86; } }\n\n@keyframes pulseWarning {\n  0% {\n    border-color: #F8D486; }\n  100% {\n    border-color: #F8BB86; } }\n\n.pulseWarning {\n  -webkit-animation: pulseWarning 0.75s infinite alternate;\n  animation: pulseWarning 0.75s infinite alternate; }\n\n@-webkit-keyframes pulseWarningIns {\n  0% {\n    background-color: #F8D486; }\n  100% {\n    background-color: #F8BB86; } }\n\n@keyframes pulseWarningIns {\n  0% {\n    background-color: #F8D486; }\n  100% {\n    background-color: #F8BB86; } }\n\n.pulseWarningIns {\n  -webkit-animation: pulseWarningIns 0.75s infinite alternate;\n  animation: pulseWarningIns 0.75s infinite alternate; }\n\n@-webkit-keyframes rotate-loading {\n  0% {\n    transform: rotate(0deg); }\n  100% {\n    transform: rotate(360deg); } }\n\n@keyframes rotate-loading {\n  0% {\n    transform: rotate(0deg); }\n  100% {\n    transform: rotate(360deg); } }\n\n/* Internet Explorer 9 has some special quirks that are fixed here */\n/* The icons are not animated. */\n/* This file is automatically merged into sweet-alert.min.js through Gulp */\n/* Error icon */\n.sweet-alert .sa-icon.sa-error .sa-line.sa-left {\n  -ms-transform: rotate(45deg) \\9; }\n\n.sweet-alert .sa-icon.sa-error .sa-line.sa-right {\n  -ms-transform: rotate(-45deg) \\9; }\n\n/* Success icon */\n.sweet-alert .sa-icon.sa-success {\n  border-color: transparent\\9; }\n\n.sweet-alert .sa-icon.sa-success .sa-line.sa-tip {\n  -ms-transform: rotate(45deg) \\9; }\n\n.sweet-alert .sa-icon.sa-success .sa-line.sa-long {\n  -ms-transform: rotate(-45deg) \\9; }\n\n/*!\n * Load Awesome v1.1.0 (http://github.danielcardoso.net/load-awesome/)\n * Copyright 2015 Daniel Cardoso <@DanielCardoso>\n * Licensed under MIT\n */\n.la-ball-fall,\n.la-ball-fall > div {\n  position: relative;\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box; }\n\n.la-ball-fall {\n  display: block;\n  font-size: 0;\n  color: #fff; }\n\n.la-ball-fall.la-dark {\n  color: #333; }\n\n.la-ball-fall > div {\n  display: inline-block;\n  float: none;\n  background-color: currentColor;\n  border: 0 solid currentColor; }\n\n.la-ball-fall {\n  width: 54px;\n  height: 18px; }\n\n.la-ball-fall > div {\n  width: 10px;\n  height: 10px;\n  margin: 4px;\n  border-radius: 100%;\n  opacity: 0;\n  -webkit-animation: ball-fall 1s ease-in-out infinite;\n  -moz-animation: ball-fall 1s ease-in-out infinite;\n  -o-animation: ball-fall 1s ease-in-out infinite;\n  animation: ball-fall 1s ease-in-out infinite; }\n\n.la-ball-fall > div:nth-child(1) {\n  -webkit-animation-delay: -200ms;\n  -moz-animation-delay: -200ms;\n  -o-animation-delay: -200ms;\n  animation-delay: -200ms; }\n\n.la-ball-fall > div:nth-child(2) {\n  -webkit-animation-delay: -100ms;\n  -moz-animation-delay: -100ms;\n  -o-animation-delay: -100ms;\n  animation-delay: -100ms; }\n\n.la-ball-fall > div:nth-child(3) {\n  -webkit-animation-delay: 0ms;\n  -moz-animation-delay: 0ms;\n  -o-animation-delay: 0ms;\n  animation-delay: 0ms; }\n\n.la-ball-fall.la-sm {\n  width: 26px;\n  height: 8px; }\n\n.la-ball-fall.la-sm > div {\n  width: 4px;\n  height: 4px;\n  margin: 2px; }\n\n.la-ball-fall.la-2x {\n  width: 108px;\n  height: 36px; }\n\n.la-ball-fall.la-2x > div {\n  width: 20px;\n  height: 20px;\n  margin: 8px; }\n\n.la-ball-fall.la-3x {\n  width: 162px;\n  height: 54px; }\n\n.la-ball-fall.la-3x > div {\n  width: 30px;\n  height: 30px;\n  margin: 12px; }\n\n/*\n * Animation\n */\n@-webkit-keyframes ball-fall {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateY(-145%);\n    transform: translateY(-145%); }\n  10% {\n    opacity: .5; }\n  20% {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n    transform: translateY(0); }\n  80% {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n    transform: translateY(0); }\n  90% {\n    opacity: .5; }\n  100% {\n    opacity: 0;\n    -webkit-transform: translateY(145%);\n    transform: translateY(145%); } }\n\n@-moz-keyframes ball-fall {\n  0% {\n    opacity: 0;\n    -moz-transform: translateY(-145%);\n    transform: translateY(-145%); }\n  10% {\n    opacity: .5; }\n  20% {\n    opacity: 1;\n    -moz-transform: translateY(0);\n    transform: translateY(0); }\n  80% {\n    opacity: 1;\n    -moz-transform: translateY(0);\n    transform: translateY(0); }\n  90% {\n    opacity: .5; }\n  100% {\n    opacity: 0;\n    -moz-transform: translateY(145%);\n    transform: translateY(145%); } }\n\n@-o-keyframes ball-fall {\n  0% {\n    opacity: 0;\n    -o-transform: translateY(-145%);\n    transform: translateY(-145%); }\n  10% {\n    opacity: .5; }\n  20% {\n    opacity: 1;\n    -o-transform: translateY(0);\n    transform: translateY(0); }\n  80% {\n    opacity: 1;\n    -o-transform: translateY(0);\n    transform: translateY(0); }\n  90% {\n    opacity: .5; }\n  100% {\n    opacity: 0;\n    -o-transform: translateY(145%);\n    transform: translateY(145%); } }\n\n@keyframes ball-fall {\n  0% {\n    opacity: 0;\n    -webkit-transform: translateY(-145%);\n    -moz-transform: translateY(-145%);\n    -o-transform: translateY(-145%);\n    transform: translateY(-145%); }\n  10% {\n    opacity: .5; }\n  20% {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n    -moz-transform: translateY(0);\n    -o-transform: translateY(0);\n    transform: translateY(0); }\n  80% {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n    -moz-transform: translateY(0);\n    -o-transform: translateY(0);\n    transform: translateY(0); }\n  90% {\n    opacity: .5; }\n  100% {\n    opacity: 0;\n    -webkit-transform: translateY(145%);\n    -moz-transform: translateY(145%);\n    -o-transform: translateY(145%);\n    transform: translateY(145%); } }\n"
  },
  {
    "path": "static/assets/plugins/switchery/dist/switchery.css",
    "content": "/*\n *\n * Main stylesheet for Switchery.\n * http://abpetkov.github.io/switchery/\n *\n */\n\n/* Switchery defaults. */\n\n.switchery {\n  background-color: #fff;\n  border: 1px solid #dfdfdf;\n  border-radius: 20px;\n  cursor: pointer;\n  display: inline-block;\n  height: 30px;\n  position: relative;\n  vertical-align: middle;\n  width: 50px;\n\n  -moz-user-select: none;\n  -khtml-user-select: none;\n  -webkit-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  box-sizing: content-box;\n  background-clip: content-box;\n}\n\n.switchery > small {\n  background: #fff;\n  border-radius: 100%;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);\n  height: 30px;\n  position: absolute;\n  top: 0;\n  width: 30px;\n}\n\n/* Switchery sizes. */\n\n.switchery-small {\n  border-radius: 20px;\n  height: 20px;\n  width: 33px;\n}\n\n.switchery-small > small {\n  height: 20px;\n  width: 20px;\n}\n\n.switchery-large {\n  border-radius: 40px;\n  height: 40px;\n  width: 66px;\n}\n\n.switchery-large > small {\n  height: 40px;\n  width: 40px;\n}\n\n\n"
  },
  {
    "path": "static/assets/plugins/switchery/dist/switchery.js",
    "content": "\n;(function(){\n\n/**\n * Require the module at `name`.\n *\n * @param {String} name\n * @return {Object} exports\n * @api public\n */\n\nfunction require(name) {\n  var module = require.modules[name];\n  if (!module) throw new Error('failed to require \"' + name + '\"');\n\n  if (!('exports' in module) && typeof module.definition === 'function') {\n    module.client = module.component = true;\n    module.definition.call(this, module.exports = {}, module);\n    delete module.definition;\n  }\n\n  return module.exports;\n}\n\n/**\n * Meta info, accessible in the global scope unless you use AMD option.\n */\n\nrequire.loader = 'component';\n\n/**\n * Internal helper object, contains a sorting function for semantiv versioning\n */\nrequire.helper = {};\nrequire.helper.semVerSort = function(a, b) {\n  var aArray = a.version.split('.');\n  var bArray = b.version.split('.');\n  for (var i=0; i<aArray.length; ++i) {\n    var aInt = parseInt(aArray[i], 10);\n    var bInt = parseInt(bArray[i], 10);\n    if (aInt === bInt) {\n      var aLex = aArray[i].substr((\"\"+aInt).length);\n      var bLex = bArray[i].substr((\"\"+bInt).length);\n      if (aLex === '' && bLex !== '') return 1;\n      if (aLex !== '' && bLex === '') return -1;\n      if (aLex !== '' && bLex !== '') return aLex > bLex ? 1 : -1;\n      continue;\n    } else if (aInt > bInt) {\n      return 1;\n    } else {\n      return -1;\n    }\n  }\n  return 0;\n}\n\n/**\n * Find and require a module which name starts with the provided name.\n * If multiple modules exists, the highest semver is used. \n * This function can only be used for remote dependencies.\n\n * @param {String} name - module name: `user~repo`\n * @param {Boolean} returnPath - returns the canonical require path if true, \n *                               otherwise it returns the epxorted module\n */\nrequire.latest = function (name, returnPath) {\n  function showError(name) {\n    throw new Error('failed to find latest module of \"' + name + '\"');\n  }\n  // only remotes with semvers, ignore local files conataining a '/'\n  var versionRegexp = /(.*)~(.*)@v?(\\d+\\.\\d+\\.\\d+[^\\/]*)$/;\n  var remoteRegexp = /(.*)~(.*)/;\n  if (!remoteRegexp.test(name)) showError(name);\n  var moduleNames = Object.keys(require.modules);\n  var semVerCandidates = [];\n  var otherCandidates = []; // for instance: name of the git branch\n  for (var i=0; i<moduleNames.length; i++) {\n    var moduleName = moduleNames[i];\n    if (new RegExp(name + '@').test(moduleName)) {\n        var version = moduleName.substr(name.length+1);\n        var semVerMatch = versionRegexp.exec(moduleName);\n        if (semVerMatch != null) {\n          semVerCandidates.push({version: version, name: moduleName});\n        } else {\n          otherCandidates.push({version: version, name: moduleName});\n        } \n    }\n  }\n  if (semVerCandidates.concat(otherCandidates).length === 0) {\n    showError(name);\n  }\n  if (semVerCandidates.length > 0) {\n    var module = semVerCandidates.sort(require.helper.semVerSort).pop().name;\n    if (returnPath === true) {\n      return module;\n    }\n    return require(module);\n  }\n  // if the build contains more than one branch of the same module\n  // you should not use this funciton\n  var module = otherCandidates.sort(function(a, b) {return a.name > b.name})[0].name;\n  if (returnPath === true) {\n    return module;\n  }\n  return require(module);\n}\n\n/**\n * Registered modules.\n */\n\nrequire.modules = {};\n\n/**\n * Register module at `name` with callback `definition`.\n *\n * @param {String} name\n * @param {Function} definition\n * @api private\n */\n\nrequire.register = function (name, definition) {\n  require.modules[name] = {\n    definition: definition\n  };\n};\n\n/**\n * Define a module's exports immediately with `exports`.\n *\n * @param {String} name\n * @param {Generic} exports\n * @api private\n */\n\nrequire.define = function (name, exports) {\n  require.modules[name] = {\n    exports: exports\n  };\n};\nrequire.register(\"abpetkov~transitionize@0.0.3\", function (exports, module) {\n\n/**\n * Transitionize 0.0.2\n * https://github.com/abpetkov/transitionize\n *\n * Authored by Alexander Petkov\n * https://github.com/abpetkov\n *\n * Copyright 2013, Alexander Petkov\n * License: The MIT License (MIT)\n * http://opensource.org/licenses/MIT\n *\n */\n\n/**\n * Expose `Transitionize`.\n */\n\nmodule.exports = Transitionize;\n\n/**\n * Initialize new Transitionize.\n *\n * @param {Object} element\n * @param {Object} props\n * @api public\n */\n\nfunction Transitionize(element, props) {\n  if (!(this instanceof Transitionize)) return new Transitionize(element, props);\n\n  this.element = element;\n  this.props = props || {};\n  this.init();\n}\n\n/**\n * Detect if Safari.\n *\n * @returns {Boolean}\n * @api private\n */\n\nTransitionize.prototype.isSafari = function() {\n  return (/Safari/).test(navigator.userAgent) && (/Apple Computer/).test(navigator.vendor);\n};\n\n/**\n * Loop though the object and push the keys and values in an array.\n * Apply the CSS3 transition to the element and prefix with -webkit- for Safari.\n *\n * @api private\n */\n\nTransitionize.prototype.init = function() {\n  var transitions = [];\n\n  for (var key in this.props) {\n    transitions.push(key + ' ' + this.props[key]);\n  }\n\n  this.element.style.transition = transitions.join(', ');\n  if (this.isSafari()) this.element.style.webkitTransition = transitions.join(', ');\n};\n});\n\nrequire.register(\"ftlabs~fastclick@v0.6.11\", function (exports, module) {\n/**\n * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs.\n *\n * @version 0.6.11\n * @codingstandard ftlabs-jsv2\n * @copyright The Financial Times Limited [All Rights Reserved]\n * @license MIT License (see LICENSE.txt)\n */\n\n/*jslint browser:true, node:true*/\n/*global define, Event, Node*/\n\n\n/**\n * Instantiate fast-clicking listeners on the specificed layer.\n *\n * @constructor\n * @param {Element} layer The layer to listen on\n */\nfunction FastClick(layer) {\n\t'use strict';\n\tvar oldOnClick, self = this;\n\n\n\t/**\n\t * Whether a click is currently being tracked.\n\t *\n\t * @type boolean\n\t */\n\tthis.trackingClick = false;\n\n\n\t/**\n\t * Timestamp for when when click tracking started.\n\t *\n\t * @type number\n\t */\n\tthis.trackingClickStart = 0;\n\n\n\t/**\n\t * The element being tracked for a click.\n\t *\n\t * @type EventTarget\n\t */\n\tthis.targetElement = null;\n\n\n\t/**\n\t * X-coordinate of touch start event.\n\t *\n\t * @type number\n\t */\n\tthis.touchStartX = 0;\n\n\n\t/**\n\t * Y-coordinate of touch start event.\n\t *\n\t * @type number\n\t */\n\tthis.touchStartY = 0;\n\n\n\t/**\n\t * ID of the last touch, retrieved from Touch.identifier.\n\t *\n\t * @type number\n\t */\n\tthis.lastTouchIdentifier = 0;\n\n\n\t/**\n\t * Touchmove boundary, beyond which a click will be cancelled.\n\t *\n\t * @type number\n\t */\n\tthis.touchBoundary = 10;\n\n\n\t/**\n\t * The FastClick layer.\n\t *\n\t * @type Element\n\t */\n\tthis.layer = layer;\n\n\tif (!layer || !layer.nodeType) {\n\t\tthrow new TypeError('Layer must be a document node');\n\t}\n\n\t/** @type function() */\n\tthis.onClick = function() { return FastClick.prototype.onClick.apply(self, arguments); };\n\n\t/** @type function() */\n\tthis.onMouse = function() { return FastClick.prototype.onMouse.apply(self, arguments); };\n\n\t/** @type function() */\n\tthis.onTouchStart = function() { return FastClick.prototype.onTouchStart.apply(self, arguments); };\n\n\t/** @type function() */\n\tthis.onTouchMove = function() { return FastClick.prototype.onTouchMove.apply(self, arguments); };\n\n\t/** @type function() */\n\tthis.onTouchEnd = function() { return FastClick.prototype.onTouchEnd.apply(self, arguments); };\n\n\t/** @type function() */\n\tthis.onTouchCancel = function() { return FastClick.prototype.onTouchCancel.apply(self, arguments); };\n\n\tif (FastClick.notNeeded(layer)) {\n\t\treturn;\n\t}\n\n\t// Set up event handlers as required\n\tif (this.deviceIsAndroid) {\n\t\tlayer.addEventListener('mouseover', this.onMouse, true);\n\t\tlayer.addEventListener('mousedown', this.onMouse, true);\n\t\tlayer.addEventListener('mouseup', this.onMouse, true);\n\t}\n\n\tlayer.addEventListener('click', this.onClick, true);\n\tlayer.addEventListener('touchstart', this.onTouchStart, false);\n\tlayer.addEventListener('touchmove', this.onTouchMove, false);\n\tlayer.addEventListener('touchend', this.onTouchEnd, false);\n\tlayer.addEventListener('touchcancel', this.onTouchCancel, false);\n\n\t// Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)\n\t// which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick\n\t// layer when they are cancelled.\n\tif (!Event.prototype.stopImmediatePropagation) {\n\t\tlayer.removeEventListener = function(type, callback, capture) {\n\t\t\tvar rmv = Node.prototype.removeEventListener;\n\t\t\tif (type === 'click') {\n\t\t\t\trmv.call(layer, type, callback.hijacked || callback, capture);\n\t\t\t} else {\n\t\t\t\trmv.call(layer, type, callback, capture);\n\t\t\t}\n\t\t};\n\n\t\tlayer.addEventListener = function(type, callback, capture) {\n\t\t\tvar adv = Node.prototype.addEventListener;\n\t\t\tif (type === 'click') {\n\t\t\t\tadv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {\n\t\t\t\t\tif (!event.propagationStopped) {\n\t\t\t\t\t\tcallback(event);\n\t\t\t\t\t}\n\t\t\t\t}), capture);\n\t\t\t} else {\n\t\t\t\tadv.call(layer, type, callback, capture);\n\t\t\t}\n\t\t};\n\t}\n\n\t// If a handler is already declared in the element's onclick attribute, it will be fired before\n\t// FastClick's onClick handler. Fix this by pulling out the user-defined handler function and\n\t// adding it as listener.\n\tif (typeof layer.onclick === 'function') {\n\n\t\t// Android browser on at least 3.2 requires a new reference to the function in layer.onclick\n\t\t// - the old one won't work if passed to addEventListener directly.\n\t\toldOnClick = layer.onclick;\n\t\tlayer.addEventListener('click', function(event) {\n\t\t\toldOnClick(event);\n\t\t}, false);\n\t\tlayer.onclick = null;\n\t}\n}\n\n\n/**\n * Android requires exceptions.\n *\n * @type boolean\n */\nFastClick.prototype.deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0;\n\n\n/**\n * iOS requires exceptions.\n *\n * @type boolean\n */\nFastClick.prototype.deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent);\n\n\n/**\n * iOS 4 requires an exception for select elements.\n *\n * @type boolean\n */\nFastClick.prototype.deviceIsIOS4 = FastClick.prototype.deviceIsIOS && (/OS 4_\\d(_\\d)?/).test(navigator.userAgent);\n\n\n/**\n * iOS 6.0(+?) requires the target element to be manually derived\n *\n * @type boolean\n */\nFastClick.prototype.deviceIsIOSWithBadTarget = FastClick.prototype.deviceIsIOS && (/OS ([6-9]|\\d{2})_\\d/).test(navigator.userAgent);\n\n\n/**\n * Determine whether a given element requires a native click.\n *\n * @param {EventTarget|Element} target Target DOM element\n * @returns {boolean} Returns true if the element needs a native click\n */\nFastClick.prototype.needsClick = function(target) {\n\t'use strict';\n\tswitch (target.nodeName.toLowerCase()) {\n\n\t// Don't send a synthetic click to disabled inputs (issue #62)\n\tcase 'button':\n\tcase 'select':\n\tcase 'textarea':\n\t\tif (target.disabled) {\n\t\t\treturn true;\n\t\t}\n\n\t\tbreak;\n\tcase 'input':\n\n\t\t// File inputs need real clicks on iOS 6 due to a browser bug (issue #68)\n\t\tif ((this.deviceIsIOS && target.type === 'file') || target.disabled) {\n\t\t\treturn true;\n\t\t}\n\n\t\tbreak;\n\tcase 'label':\n\tcase 'video':\n\t\treturn true;\n\t}\n\n\treturn (/\\bneedsclick\\b/).test(target.className);\n};\n\n\n/**\n * Determine whether a given element requires a call to focus to simulate click into element.\n *\n * @param {EventTarget|Element} target Target DOM element\n * @returns {boolean} Returns true if the element requires a call to focus to simulate native click.\n */\nFastClick.prototype.needsFocus = function(target) {\n\t'use strict';\n\tswitch (target.nodeName.toLowerCase()) {\n\tcase 'textarea':\n\t\treturn true;\n\tcase 'select':\n\t\treturn !this.deviceIsAndroid;\n\tcase 'input':\n\t\tswitch (target.type) {\n\t\tcase 'button':\n\t\tcase 'checkbox':\n\t\tcase 'file':\n\t\tcase 'image':\n\t\tcase 'radio':\n\t\tcase 'submit':\n\t\t\treturn false;\n\t\t}\n\n\t\t// No point in attempting to focus disabled inputs\n\t\treturn !target.disabled && !target.readOnly;\n\tdefault:\n\t\treturn (/\\bneedsfocus\\b/).test(target.className);\n\t}\n};\n\n\n/**\n * Send a click event to the specified element.\n *\n * @param {EventTarget|Element} targetElement\n * @param {Event} event\n */\nFastClick.prototype.sendClick = function(targetElement, event) {\n\t'use strict';\n\tvar clickEvent, touch;\n\n\t// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)\n\tif (document.activeElement && document.activeElement !== targetElement) {\n\t\tdocument.activeElement.blur();\n\t}\n\n\ttouch = event.changedTouches[0];\n\n\t// Synthesise a click event, with an extra attribute so it can be tracked\n\tclickEvent = document.createEvent('MouseEvents');\n\tclickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);\n\tclickEvent.forwardedTouchEvent = true;\n\ttargetElement.dispatchEvent(clickEvent);\n};\n\nFastClick.prototype.determineEventType = function(targetElement) {\n\t'use strict';\n\n\t//Issue #159: Android Chrome Select Box does not open with a synthetic click event\n\tif (this.deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') {\n\t\treturn 'mousedown';\n\t}\n\n\treturn 'click';\n};\n\n\n/**\n * @param {EventTarget|Element} targetElement\n */\nFastClick.prototype.focus = function(targetElement) {\n\t'use strict';\n\tvar length;\n\n\t// Issue #160: on iOS 7, some input elements (e.g. date datetime) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.\n\tif (this.deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time') {\n\t\tlength = targetElement.value.length;\n\t\ttargetElement.setSelectionRange(length, length);\n\t} else {\n\t\ttargetElement.focus();\n\t}\n};\n\n\n/**\n * Check whether the given target element is a child of a scrollable layer and if so, set a flag on it.\n *\n * @param {EventTarget|Element} targetElement\n */\nFastClick.prototype.updateScrollParent = function(targetElement) {\n\t'use strict';\n\tvar scrollParent, parentElement;\n\n\tscrollParent = targetElement.fastClickScrollParent;\n\n\t// Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the\n\t// target element was moved to another parent.\n\tif (!scrollParent || !scrollParent.contains(targetElement)) {\n\t\tparentElement = targetElement;\n\t\tdo {\n\t\t\tif (parentElement.scrollHeight > parentElement.offsetHeight) {\n\t\t\t\tscrollParent = parentElement;\n\t\t\t\ttargetElement.fastClickScrollParent = parentElement;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tparentElement = parentElement.parentElement;\n\t\t} while (parentElement);\n\t}\n\n\t// Always update the scroll top tracker if possible.\n\tif (scrollParent) {\n\t\tscrollParent.fastClickLastScrollTop = scrollParent.scrollTop;\n\t}\n};\n\n\n/**\n * @param {EventTarget} targetElement\n * @returns {Element|EventTarget}\n */\nFastClick.prototype.getTargetElementFromEventTarget = function(eventTarget) {\n\t'use strict';\n\n\t// On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node.\n\tif (eventTarget.nodeType === Node.TEXT_NODE) {\n\t\treturn eventTarget.parentNode;\n\t}\n\n\treturn eventTarget;\n};\n\n\n/**\n * On touch start, record the position and scroll offset.\n *\n * @param {Event} event\n * @returns {boolean}\n */\nFastClick.prototype.onTouchStart = function(event) {\n\t'use strict';\n\tvar targetElement, touch, selection;\n\n\t// Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111).\n\tif (event.targetTouches.length > 1) {\n\t\treturn true;\n\t}\n\n\ttargetElement = this.getTargetElementFromEventTarget(event.target);\n\ttouch = event.targetTouches[0];\n\n\tif (this.deviceIsIOS) {\n\n\t\t// Only trusted events will deselect text on iOS (issue #49)\n\t\tselection = window.getSelection();\n\t\tif (selection.rangeCount && !selection.isCollapsed) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (!this.deviceIsIOS4) {\n\n\t\t\t// Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23):\n\t\t\t// when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched\n\t\t\t// with the same identifier as the touch event that previously triggered the click that triggered the alert.\n\t\t\t// Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an\n\t\t\t// immediately preceeding touch event (issue #52), so this fix is unavailable on that platform.\n\t\t\tif (touch.identifier === this.lastTouchIdentifier) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis.lastTouchIdentifier = touch.identifier;\n\n\t\t\t// If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and:\n\t\t\t// 1) the user does a fling scroll on the scrollable layer\n\t\t\t// 2) the user stops the fling scroll with another tap\n\t\t\t// then the event.target of the last 'touchend' event will be the element that was under the user's finger\n\t\t\t// when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check\n\t\t\t// is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42).\n\t\t\tthis.updateScrollParent(targetElement);\n\t\t}\n\t}\n\n\tthis.trackingClick = true;\n\tthis.trackingClickStart = event.timeStamp;\n\tthis.targetElement = targetElement;\n\n\tthis.touchStartX = touch.pageX;\n\tthis.touchStartY = touch.pageY;\n\n\t// Prevent phantom clicks on fast double-tap (issue #36)\n\tif ((event.timeStamp - this.lastClickTime) < 200) {\n\t\tevent.preventDefault();\n\t}\n\n\treturn true;\n};\n\n\n/**\n * Based on a touchmove event object, check whether the touch has moved past a boundary since it started.\n *\n * @param {Event} event\n * @returns {boolean}\n */\nFastClick.prototype.touchHasMoved = function(event) {\n\t'use strict';\n\tvar touch = event.changedTouches[0], boundary = this.touchBoundary;\n\n\tif (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n\n/**\n * Update the last position.\n *\n * @param {Event} event\n * @returns {boolean}\n */\nFastClick.prototype.onTouchMove = function(event) {\n\t'use strict';\n\tif (!this.trackingClick) {\n\t\treturn true;\n\t}\n\n\t// If the touch has moved, cancel the click tracking\n\tif (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {\n\t\tthis.trackingClick = false;\n\t\tthis.targetElement = null;\n\t}\n\n\treturn true;\n};\n\n\n/**\n * Attempt to find the labelled control for the given label element.\n *\n * @param {EventTarget|HTMLLabelElement} labelElement\n * @returns {Element|null}\n */\nFastClick.prototype.findControl = function(labelElement) {\n\t'use strict';\n\n\t// Fast path for newer browsers supporting the HTML5 control attribute\n\tif (labelElement.control !== undefined) {\n\t\treturn labelElement.control;\n\t}\n\n\t// All browsers under test that support touch events also support the HTML5 htmlFor attribute\n\tif (labelElement.htmlFor) {\n\t\treturn document.getElementById(labelElement.htmlFor);\n\t}\n\n\t// If no for attribute exists, attempt to retrieve the first labellable descendant element\n\t// the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label\n\treturn labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea');\n};\n\n\n/**\n * On touch end, determine whether to send a click event at once.\n *\n * @param {Event} event\n * @returns {boolean}\n */\nFastClick.prototype.onTouchEnd = function(event) {\n\t'use strict';\n\tvar forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;\n\n\tif (!this.trackingClick) {\n\t\treturn true;\n\t}\n\n\t// Prevent phantom clicks on fast double-tap (issue #36)\n\tif ((event.timeStamp - this.lastClickTime) < 200) {\n\t\tthis.cancelNextClick = true;\n\t\treturn true;\n\t}\n\n\t// Reset to prevent wrong click cancel on input (issue #156).\n\tthis.cancelNextClick = false;\n\n\tthis.lastClickTime = event.timeStamp;\n\n\ttrackingClickStart = this.trackingClickStart;\n\tthis.trackingClick = false;\n\tthis.trackingClickStart = 0;\n\n\t// On some iOS devices, the targetElement supplied with the event is invalid if the layer\n\t// is performing a transition or scroll, and has to be re-detected manually. Note that\n\t// for this to function correctly, it must be called *after* the event target is checked!\n\t// See issue #57; also filed as rdar://13048589 .\n\tif (this.deviceIsIOSWithBadTarget) {\n\t\ttouch = event.changedTouches[0];\n\n\t\t// In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null\n\t\ttargetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;\n\t\ttargetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;\n\t}\n\n\ttargetTagName = targetElement.tagName.toLowerCase();\n\tif (targetTagName === 'label') {\n\t\tforElement = this.findControl(targetElement);\n\t\tif (forElement) {\n\t\t\tthis.focus(targetElement);\n\t\t\tif (this.deviceIsAndroid) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\ttargetElement = forElement;\n\t\t}\n\t} else if (this.needsFocus(targetElement)) {\n\n\t\t// Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through.\n\t\t// Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37).\n\t\tif ((event.timeStamp - trackingClickStart) > 100 || (this.deviceIsIOS && window.top !== window && targetTagName === 'input')) {\n\t\t\tthis.targetElement = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.focus(targetElement);\n\n\t\t// Select elements need the event to go through on iOS 4, otherwise the selector menu won't open.\n\t\tif (!this.deviceIsIOS4 || targetTagName !== 'select') {\n\t\t\tthis.targetElement = null;\n\t\t\tevent.preventDefault();\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tif (this.deviceIsIOS && !this.deviceIsIOS4) {\n\n\t\t// Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled\n\t\t// and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42).\n\t\tscrollParent = targetElement.fastClickScrollParent;\n\t\tif (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Prevent the actual click from going though - unless the target node is marked as requiring\n\t// real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted.\n\tif (!this.needsClick(targetElement)) {\n\t\tevent.preventDefault();\n\t\tthis.sendClick(targetElement, event);\n\t}\n\n\treturn false;\n};\n\n\n/**\n * On touch cancel, stop tracking the click.\n *\n * @returns {void}\n */\nFastClick.prototype.onTouchCancel = function() {\n\t'use strict';\n\tthis.trackingClick = false;\n\tthis.targetElement = null;\n};\n\n\n/**\n * Determine mouse events which should be permitted.\n *\n * @param {Event} event\n * @returns {boolean}\n */\nFastClick.prototype.onMouse = function(event) {\n\t'use strict';\n\n\t// If a target element was never set (because a touch event was never fired) allow the event\n\tif (!this.targetElement) {\n\t\treturn true;\n\t}\n\n\tif (event.forwardedTouchEvent) {\n\t\treturn true;\n\t}\n\n\t// Programmatically generated events targeting a specific element should be permitted\n\tif (!event.cancelable) {\n\t\treturn true;\n\t}\n\n\t// Derive and check the target element to see whether the mouse event needs to be permitted;\n\t// unless explicitly enabled, prevent non-touch click events from triggering actions,\n\t// to prevent ghost/doubleclicks.\n\tif (!this.needsClick(this.targetElement) || this.cancelNextClick) {\n\n\t\t// Prevent any user-added listeners declared on FastClick element from being fired.\n\t\tif (event.stopImmediatePropagation) {\n\t\t\tevent.stopImmediatePropagation();\n\t\t} else {\n\n\t\t\t// Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)\n\t\t\tevent.propagationStopped = true;\n\t\t}\n\n\t\t// Cancel the event\n\t\tevent.stopPropagation();\n\t\tevent.preventDefault();\n\n\t\treturn false;\n\t}\n\n\t// If the mouse event is permitted, return true for the action to go through.\n\treturn true;\n};\n\n\n/**\n * On actual clicks, determine whether this is a touch-generated click, a click action occurring\n * naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or\n * an actual click which should be permitted.\n *\n * @param {Event} event\n * @returns {boolean}\n */\nFastClick.prototype.onClick = function(event) {\n\t'use strict';\n\tvar permitted;\n\n\t// It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early.\n\tif (this.trackingClick) {\n\t\tthis.targetElement = null;\n\t\tthis.trackingClick = false;\n\t\treturn true;\n\t}\n\n\t// Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target.\n\tif (event.target.type === 'submit' && event.detail === 0) {\n\t\treturn true;\n\t}\n\n\tpermitted = this.onMouse(event);\n\n\t// Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through.\n\tif (!permitted) {\n\t\tthis.targetElement = null;\n\t}\n\n\t// If clicks are permitted, return true for the action to go through.\n\treturn permitted;\n};\n\n\n/**\n * Remove all FastClick's event listeners.\n *\n * @returns {void}\n */\nFastClick.prototype.destroy = function() {\n\t'use strict';\n\tvar layer = this.layer;\n\n\tif (this.deviceIsAndroid) {\n\t\tlayer.removeEventListener('mouseover', this.onMouse, true);\n\t\tlayer.removeEventListener('mousedown', this.onMouse, true);\n\t\tlayer.removeEventListener('mouseup', this.onMouse, true);\n\t}\n\n\tlayer.removeEventListener('click', this.onClick, true);\n\tlayer.removeEventListener('touchstart', this.onTouchStart, false);\n\tlayer.removeEventListener('touchmove', this.onTouchMove, false);\n\tlayer.removeEventListener('touchend', this.onTouchEnd, false);\n\tlayer.removeEventListener('touchcancel', this.onTouchCancel, false);\n};\n\n\n/**\n * Check whether FastClick is needed.\n *\n * @param {Element} layer The layer to listen on\n */\nFastClick.notNeeded = function(layer) {\n\t'use strict';\n\tvar metaViewport;\n\tvar chromeVersion;\n\n\t// Devices that don't support touch don't need FastClick\n\tif (typeof window.ontouchstart === 'undefined') {\n\t\treturn true;\n\t}\n\n\t// Chrome version - zero for other browsers\n\tchromeVersion = +(/Chrome\\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];\n\n\tif (chromeVersion) {\n\n\t\tif (FastClick.prototype.deviceIsAndroid) {\n\t\t\tmetaViewport = document.querySelector('meta[name=viewport]');\n\t\t\t\n\t\t\tif (metaViewport) {\n\t\t\t\t// Chrome on Android with user-scalable=\"no\" doesn't need FastClick (issue #89)\n\t\t\t\tif (metaViewport.content.indexOf('user-scalable=no') !== -1) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// Chrome 32 and above with width=device-width or less don't need FastClick\n\t\t\t\tif (chromeVersion > 31 && window.innerWidth <= window.screen.width) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Chrome desktop doesn't need FastClick (issue #15)\n\t\t} else {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// IE10 with -ms-touch-action: none, which disables double-tap-to-zoom (issue #97)\n\tif (layer.style.msTouchAction === 'none') {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n\n/**\n * Factory method for creating a FastClick object\n *\n * @param {Element} layer The layer to listen on\n */\nFastClick.attach = function(layer) {\n\t'use strict';\n\treturn new FastClick(layer);\n};\n\n\nif (typeof define !== 'undefined' && define.amd) {\n\n\t// AMD. Register as an anonymous module.\n\tdefine(function() {\n\t\t'use strict';\n\t\treturn FastClick;\n\t});\n} else if (typeof module !== 'undefined' && module.exports) {\n\tmodule.exports = FastClick.attach;\n\tmodule.exports.FastClick = FastClick;\n} else {\n\twindow.FastClick = FastClick;\n}\n\n});\n\nrequire.register(\"component~indexof@0.0.3\", function (exports, module) {\nmodule.exports = function(arr, obj){\n  if (arr.indexOf) return arr.indexOf(obj);\n  for (var i = 0; i < arr.length; ++i) {\n    if (arr[i] === obj) return i;\n  }\n  return -1;\n};\n});\n\nrequire.register(\"component~classes@1.2.1\", function (exports, module) {\n/**\n * Module dependencies.\n */\n\nvar index = require('component~indexof@0.0.3');\n\n/**\n * Whitespace regexp.\n */\n\nvar re = /\\s+/;\n\n/**\n * toString reference.\n */\n\nvar toString = Object.prototype.toString;\n\n/**\n * Wrap `el` in a `ClassList`.\n *\n * @param {Element} el\n * @return {ClassList}\n * @api public\n */\n\nmodule.exports = function(el){\n  return new ClassList(el);\n};\n\n/**\n * Initialize a new ClassList for `el`.\n *\n * @param {Element} el\n * @api private\n */\n\nfunction ClassList(el) {\n  if (!el) throw new Error('A DOM element reference is required');\n  this.el = el;\n  this.list = el.classList;\n}\n\n/**\n * Add class `name` if not already present.\n *\n * @param {String} name\n * @return {ClassList}\n * @api public\n */\n\nClassList.prototype.add = function(name){\n  // classList\n  if (this.list) {\n    this.list.add(name);\n    return this;\n  }\n\n  // fallback\n  var arr = this.array();\n  var i = index(arr, name);\n  if (!~i) arr.push(name);\n  this.el.className = arr.join(' ');\n  return this;\n};\n\n/**\n * Remove class `name` when present, or\n * pass a regular expression to remove\n * any which match.\n *\n * @param {String|RegExp} name\n * @return {ClassList}\n * @api public\n */\n\nClassList.prototype.remove = function(name){\n  if ('[object RegExp]' == toString.call(name)) {\n    return this.removeMatching(name);\n  }\n\n  // classList\n  if (this.list) {\n    this.list.remove(name);\n    return this;\n  }\n\n  // fallback\n  var arr = this.array();\n  var i = index(arr, name);\n  if (~i) arr.splice(i, 1);\n  this.el.className = arr.join(' ');\n  return this;\n};\n\n/**\n * Remove all classes matching `re`.\n *\n * @param {RegExp} re\n * @return {ClassList}\n * @api private\n */\n\nClassList.prototype.removeMatching = function(re){\n  var arr = this.array();\n  for (var i = 0; i < arr.length; i++) {\n    if (re.test(arr[i])) {\n      this.remove(arr[i]);\n    }\n  }\n  return this;\n};\n\n/**\n * Toggle class `name`, can force state via `force`.\n *\n * For browsers that support classList, but do not support `force` yet,\n * the mistake will be detected and corrected.\n *\n * @param {String} name\n * @param {Boolean} force\n * @return {ClassList}\n * @api public\n */\n\nClassList.prototype.toggle = function(name, force){\n  // classList\n  if (this.list) {\n    if (\"undefined\" !== typeof force) {\n      if (force !== this.list.toggle(name, force)) {\n        this.list.toggle(name); // toggle again to correct\n      }\n    } else {\n      this.list.toggle(name);\n    }\n    return this;\n  }\n\n  // fallback\n  if (\"undefined\" !== typeof force) {\n    if (!force) {\n      this.remove(name);\n    } else {\n      this.add(name);\n    }\n  } else {\n    if (this.has(name)) {\n      this.remove(name);\n    } else {\n      this.add(name);\n    }\n  }\n\n  return this;\n};\n\n/**\n * Return an array of classes.\n *\n * @return {Array}\n * @api public\n */\n\nClassList.prototype.array = function(){\n  var str = this.el.className.replace(/^\\s+|\\s+$/g, '');\n  var arr = str.split(re);\n  if ('' === arr[0]) arr.shift();\n  return arr;\n};\n\n/**\n * Check if class `name` is present.\n *\n * @param {String} name\n * @return {ClassList}\n * @api public\n */\n\nClassList.prototype.has =\nClassList.prototype.contains = function(name){\n  return this.list\n    ? this.list.contains(name)\n    : !! ~index(this.array(), name);\n};\n\n});\n\nrequire.register(\"component~event@0.1.4\", function (exports, module) {\nvar bind = window.addEventListener ? 'addEventListener' : 'attachEvent',\n    unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent',\n    prefix = bind !== 'addEventListener' ? 'on' : '';\n\n/**\n * Bind `el` event `type` to `fn`.\n *\n * @param {Element} el\n * @param {String} type\n * @param {Function} fn\n * @param {Boolean} capture\n * @return {Function}\n * @api public\n */\n\nexports.bind = function(el, type, fn, capture){\n  el[bind](prefix + type, fn, capture || false);\n  return fn;\n};\n\n/**\n * Unbind `el` event `type`'s callback `fn`.\n *\n * @param {Element} el\n * @param {String} type\n * @param {Function} fn\n * @param {Boolean} capture\n * @return {Function}\n * @api public\n */\n\nexports.unbind = function(el, type, fn, capture){\n  el[unbind](prefix + type, fn, capture || false);\n  return fn;\n};\n});\n\nrequire.register(\"component~query@0.0.3\", function (exports, module) {\nfunction one(selector, el) {\n  return el.querySelector(selector);\n}\n\nexports = module.exports = function(selector, el){\n  el = el || document;\n  return one(selector, el);\n};\n\nexports.all = function(selector, el){\n  el = el || document;\n  return el.querySelectorAll(selector);\n};\n\nexports.engine = function(obj){\n  if (!obj.one) throw new Error('.one callback required');\n  if (!obj.all) throw new Error('.all callback required');\n  one = obj.one;\n  exports.all = obj.all;\n  return exports;\n};\n\n});\n\nrequire.register(\"component~matches-selector@0.1.5\", function (exports, module) {\n/**\n * Module dependencies.\n */\n\nvar query = require('component~query@0.0.3');\n\n/**\n * Element prototype.\n */\n\nvar proto = Element.prototype;\n\n/**\n * Vendor function.\n */\n\nvar vendor = proto.matches\n  || proto.webkitMatchesSelector\n  || proto.mozMatchesSelector\n  || proto.msMatchesSelector\n  || proto.oMatchesSelector;\n\n/**\n * Expose `match()`.\n */\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n  if (!el || el.nodeType !== 1) return false;\n  if (vendor) return vendor.call(el, selector);\n  var nodes = query.all(selector, el.parentNode);\n  for (var i = 0; i < nodes.length; ++i) {\n    if (nodes[i] == el) return true;\n  }\n  return false;\n}\n\n});\n\nrequire.register(\"component~closest@0.1.4\", function (exports, module) {\nvar matches = require('component~matches-selector@0.1.5')\n\nmodule.exports = function (element, selector, checkYoSelf, root) {\n  element = checkYoSelf ? {parentNode: element} : element\n\n  root = root || document\n\n  // Make sure `element !== document` and `element != null`\n  // otherwise we get an illegal invocation\n  while ((element = element.parentNode) && element !== document) {\n    if (matches(element, selector))\n      return element\n    // After `matches` on the edge case that\n    // the selector matches the root\n    // (when the root is not the document)\n    if (element === root)\n      return\n  }\n}\n\n});\n\nrequire.register(\"component~delegate@0.2.3\", function (exports, module) {\n/**\n * Module dependencies.\n */\n\nvar closest = require('component~closest@0.1.4')\n  , event = require('component~event@0.1.4');\n\n/**\n * Delegate event `type` to `selector`\n * and invoke `fn(e)`. A callback function\n * is returned which may be passed to `.unbind()`.\n *\n * @param {Element} el\n * @param {String} selector\n * @param {String} type\n * @param {Function} fn\n * @param {Boolean} capture\n * @return {Function}\n * @api public\n */\n\nexports.bind = function(el, selector, type, fn, capture){\n  return event.bind(el, type, function(e){\n    var target = e.target || e.srcElement;\n    e.delegateTarget = closest(target, selector, true, el);\n    if (e.delegateTarget) fn.call(el, e);\n  }, capture);\n};\n\n/**\n * Unbind event `type`'s callback `fn`.\n *\n * @param {Element} el\n * @param {String} type\n * @param {Function} fn\n * @param {Boolean} capture\n * @api public\n */\n\nexports.unbind = function(el, type, fn, capture){\n  event.unbind(el, type, fn, capture);\n};\n\n});\n\nrequire.register(\"component~events@1.0.9\", function (exports, module) {\n\n/**\n * Module dependencies.\n */\n\nvar events = require('component~event@0.1.4');\nvar delegate = require('component~delegate@0.2.3');\n\n/**\n * Expose `Events`.\n */\n\nmodule.exports = Events;\n\n/**\n * Initialize an `Events` with the given\n * `el` object which events will be bound to,\n * and the `obj` which will receive method calls.\n *\n * @param {Object} el\n * @param {Object} obj\n * @api public\n */\n\nfunction Events(el, obj) {\n  if (!(this instanceof Events)) return new Events(el, obj);\n  if (!el) throw new Error('element required');\n  if (!obj) throw new Error('object required');\n  this.el = el;\n  this.obj = obj;\n  this._events = {};\n}\n\n/**\n * Subscription helper.\n */\n\nEvents.prototype.sub = function(event, method, cb){\n  this._events[event] = this._events[event] || {};\n  this._events[event][method] = cb;\n};\n\n/**\n * Bind to `event` with optional `method` name.\n * When `method` is undefined it becomes `event`\n * with the \"on\" prefix.\n *\n * Examples:\n *\n *  Direct event handling:\n *\n *    events.bind('click') // implies \"onclick\"\n *    events.bind('click', 'remove')\n *    events.bind('click', 'sort', 'asc')\n *\n *  Delegated event handling:\n *\n *    events.bind('click li > a')\n *    events.bind('click li > a', 'remove')\n *    events.bind('click a.sort-ascending', 'sort', 'asc')\n *    events.bind('click a.sort-descending', 'sort', 'desc')\n *\n * @param {String} event\n * @param {String|function} [method]\n * @return {Function} callback\n * @api public\n */\n\nEvents.prototype.bind = function(event, method){\n  var e = parse(event);\n  var el = this.el;\n  var obj = this.obj;\n  var name = e.name;\n  var method = method || 'on' + name;\n  var args = [].slice.call(arguments, 2);\n\n  // callback\n  function cb(){\n    var a = [].slice.call(arguments).concat(args);\n    obj[method].apply(obj, a);\n  }\n\n  // bind\n  if (e.selector) {\n    cb = delegate.bind(el, e.selector, name, cb);\n  } else {\n    events.bind(el, name, cb);\n  }\n\n  // subscription for unbinding\n  this.sub(name, method, cb);\n\n  return cb;\n};\n\n/**\n * Unbind a single binding, all bindings for `event`,\n * or all bindings within the manager.\n *\n * Examples:\n *\n *  Unbind direct handlers:\n *\n *     events.unbind('click', 'remove')\n *     events.unbind('click')\n *     events.unbind()\n *\n * Unbind delegate handlers:\n *\n *     events.unbind('click', 'remove')\n *     events.unbind('click')\n *     events.unbind()\n *\n * @param {String|Function} [event]\n * @param {String|Function} [method]\n * @api public\n */\n\nEvents.prototype.unbind = function(event, method){\n  if (0 == arguments.length) return this.unbindAll();\n  if (1 == arguments.length) return this.unbindAllOf(event);\n\n  // no bindings for this event\n  var bindings = this._events[event];\n  if (!bindings) return;\n\n  // no bindings for this method\n  var cb = bindings[method];\n  if (!cb) return;\n\n  events.unbind(this.el, event, cb);\n};\n\n/**\n * Unbind all events.\n *\n * @api private\n */\n\nEvents.prototype.unbindAll = function(){\n  for (var event in this._events) {\n    this.unbindAllOf(event);\n  }\n};\n\n/**\n * Unbind all events for `event`.\n *\n * @param {String} event\n * @api private\n */\n\nEvents.prototype.unbindAllOf = function(event){\n  var bindings = this._events[event];\n  if (!bindings) return;\n\n  for (var method in bindings) {\n    this.unbind(event, method);\n  }\n};\n\n/**\n * Parse `event`.\n *\n * @param {String} event\n * @return {Object}\n * @api private\n */\n\nfunction parse(event) {\n  var parts = event.split(/ +/);\n  return {\n    name: parts.shift(),\n    selector: parts.join(' ')\n  }\n}\n\n});\n\nrequire.register(\"switchery\", function (exports, module) {\n/**\n * Switchery 0.8.1\n * http://abpetkov.github.io/switchery/\n *\n * Authored by Alexander Petkov\n * https://github.com/abpetkov\n *\n * Copyright 2013-2015, Alexander Petkov\n * License: The MIT License (MIT)\n * http://opensource.org/licenses/MIT\n *\n */\n\n/**\n * External dependencies.\n */\n\nvar transitionize = require('abpetkov~transitionize@0.0.3')\n  , fastclick = require('ftlabs~fastclick@v0.6.11')\n  , classes = require('component~classes@1.2.1')\n  , events = require('component~events@1.0.9');\n\n/**\n * Expose `Switchery`.\n */\n\nmodule.exports = Switchery;\n\n/**\n * Set Switchery default values.\n *\n * @api public\n */\n\nvar defaults = {\n    color             : '#64bd63'\n  , secondaryColor    : '#dfdfdf'\n  , jackColor         : '#fff'\n  , jackSecondaryColor: null\n  , className         : 'switchery'\n  , disabled          : false\n  , disabledOpacity   : 0.5\n  , speed             : '0.4s'\n  , size              : 'default'\n};\n\n/**\n * Create Switchery object.\n *\n * @param {Object} element\n * @param {Object} options\n * @api public\n */\n\nfunction Switchery(element, options) {\n  if (!(this instanceof Switchery)) return new Switchery(element, options);\n\n  this.element = element;\n  this.options = options || {};\n\n  for (var i in defaults) {\n    if (this.options[i] == null) {\n      this.options[i] = defaults[i];\n    }\n  }\n\n  if (this.element != null && this.element.type == 'checkbox') this.init();\n  if (this.isDisabled() === true) this.disable();\n}\n\n/**\n * Hide the target element.\n *\n * @api private\n */\n\nSwitchery.prototype.hide = function() {\n  this.element.style.display = 'none';\n};\n\n/**\n * Show custom switch after the target element.\n *\n * @api private\n */\n\nSwitchery.prototype.show = function() {\n  var switcher = this.create();\n  this.insertAfter(this.element, switcher);\n};\n\n/**\n * Create custom switch.\n *\n * @returns {Object} this.switcher\n * @api private\n */\n\nSwitchery.prototype.create = function() {\n  this.switcher = document.createElement('span');\n  this.jack = document.createElement('small');\n  this.switcher.appendChild(this.jack);\n  this.switcher.className = this.options.className;\n  this.events = events(this.switcher, this);\n\n  return this.switcher;\n};\n\n/**\n * Insert after element after another element.\n *\n * @param {Object} reference\n * @param {Object} target\n * @api private\n */\n\nSwitchery.prototype.insertAfter = function(reference, target) {\n  reference.parentNode.insertBefore(target, reference.nextSibling);\n};\n\n/**\n * Set switch jack proper position.\n *\n * @param {Boolean} clicked - we need this in order to uncheck the input when the switch is clicked\n * @api private\n */\n\nSwitchery.prototype.setPosition = function (clicked) {\n  var checked = this.isChecked()\n    , switcher = this.switcher\n    , jack = this.jack;\n\n  if (clicked && checked) checked = false;\n  else if (clicked && !checked) checked = true;\n\n  if (checked === true) {\n    this.element.checked = true;\n\n    if (window.getComputedStyle) jack.style.left = parseInt(window.getComputedStyle(switcher).width) - parseInt(window.getComputedStyle(jack).width) + 'px';\n    else jack.style.left = parseInt(switcher.currentStyle['width']) - parseInt(jack.currentStyle['width']) + 'px';\n\n    if (this.options.color) this.colorize();\n    this.setSpeed();\n  } else {\n    jack.style.left = 0;\n    this.element.checked = false;\n    this.switcher.style.boxShadow = 'inset 0 0 0 0 ' + this.options.secondaryColor;\n    this.switcher.style.borderColor = this.options.secondaryColor;\n    this.switcher.style.backgroundColor = (this.options.secondaryColor !== defaults.secondaryColor) ? this.options.secondaryColor : '#fff';\n    this.jack.style.backgroundColor = (this.options.jackSecondaryColor !== this.options.jackColor) ? this.options.jackSecondaryColor : this.options.jackColor;\n    this.setSpeed();\n  }\n};\n\n/**\n * Set speed.\n *\n * @api private\n */\n\nSwitchery.prototype.setSpeed = function() {\n  var switcherProp = {}\n    , jackProp = {\n        'background-color': this.options.speed\n      , 'left': this.options.speed.replace(/[a-z]/, '') / 2 + 's'\n    };\n\n  if (this.isChecked()) {\n    switcherProp = {\n        'border': this.options.speed\n      , 'box-shadow': this.options.speed\n      , 'background-color': this.options.speed.replace(/[a-z]/, '') * 3 + 's'\n    };\n  } else {\n    switcherProp = {\n        'border': this.options.speed\n      , 'box-shadow': this.options.speed\n    };\n  }\n\n  transitionize(this.switcher, switcherProp);\n  transitionize(this.jack, jackProp);\n};\n\n/**\n * Set switch size.\n *\n * @api private\n */\n\nSwitchery.prototype.setSize = function() {\n  var small = 'switchery-small'\n    , normal = 'switchery-default'\n    , large = 'switchery-large';\n\n  switch (this.options.size) {\n    case 'small':\n      classes(this.switcher).add(small)\n      break;\n    case 'large':\n      classes(this.switcher).add(large)\n      break;\n    default:\n      classes(this.switcher).add(normal)\n      break;\n  }\n};\n\n/**\n * Set switch color.\n *\n * @api private\n */\n\nSwitchery.prototype.colorize = function() {\n  var switcherHeight = this.switcher.offsetHeight / 2;\n\n  this.switcher.style.backgroundColor = this.options.color;\n  this.switcher.style.borderColor = this.options.color;\n  this.switcher.style.boxShadow = 'inset 0 0 0 ' + switcherHeight + 'px ' + this.options.color;\n  this.jack.style.backgroundColor = this.options.jackColor;\n};\n\n/**\n * Handle the onchange event.\n *\n * @param {Boolean} state\n * @api private\n */\n\nSwitchery.prototype.handleOnchange = function(state) {\n  if (document.dispatchEvent) {\n    var event = document.createEvent('HTMLEvents');\n    event.initEvent('change', true, true);\n    this.element.dispatchEvent(event);\n  } else {\n    this.element.fireEvent('onchange');\n  }\n};\n\n/**\n * Handle the native input element state change.\n * A `change` event must be fired in order to detect the change.\n *\n * @api private\n */\n\nSwitchery.prototype.handleChange = function() {\n  var self = this\n    , el = this.element;\n\n  if (el.addEventListener) {\n    el.addEventListener('change', function() {\n      self.setPosition();\n    });\n  } else {\n    el.attachEvent('onchange', function() {\n      self.setPosition();\n    });\n  }\n};\n\n/**\n * Handle the switch click event.\n *\n * @api private\n */\n\nSwitchery.prototype.handleClick = function() {\n  var switcher = this.switcher;\n\n  fastclick(switcher);\n  this.events.bind('click', 'bindClick');\n};\n\n/**\n * Attach all methods that need to happen on switcher click.\n *\n * @api private\n */\n\nSwitchery.prototype.bindClick = function() {\n  var parent = this.element.parentNode.tagName.toLowerCase()\n    , labelParent = (parent === 'label') ? false : true;\n\n  this.setPosition(labelParent);\n  this.handleOnchange(this.element.checked);\n};\n\n/**\n * Mark an individual switch as already handled.\n *\n * @api private\n */\n\nSwitchery.prototype.markAsSwitched = function() {\n  this.element.setAttribute('data-switchery', true);\n};\n\n/**\n * Check if an individual switch is already handled.\n *\n * @api private\n */\n\nSwitchery.prototype.markedAsSwitched = function() {\n  return this.element.getAttribute('data-switchery');\n};\n\n/**\n * Initialize Switchery.\n *\n * @api private\n */\n\nSwitchery.prototype.init = function() {\n  this.hide();\n  this.show();\n  this.setSize();\n  this.setPosition();\n  this.markAsSwitched();\n  this.handleChange();\n  this.handleClick();\n};\n\n/**\n * See if input is checked.\n *\n * @returns {Boolean}\n * @api public\n */\n\nSwitchery.prototype.isChecked = function() {\n  return this.element.checked;\n};\n\n/**\n * See if switcher should be disabled.\n *\n * @returns {Boolean}\n * @api public\n */\n\nSwitchery.prototype.isDisabled = function() {\n  return this.options.disabled || this.element.disabled || this.element.readOnly;\n};\n\n/**\n * Destroy all event handlers attached to the switch.\n *\n * @api public\n */\n\nSwitchery.prototype.destroy = function() {\n  this.events.unbind();\n};\n\n/**\n * Enable disabled switch element.\n *\n * @api public\n */\n\nSwitchery.prototype.enable = function() {\n  if (this.options.disabled) this.options.disabled = false;\n  if (this.element.disabled) this.element.disabled = false;\n  if (this.element.readOnly) this.element.readOnly = false;\n  this.switcher.style.opacity = 1;\n  this.events.bind('click', 'bindClick');\n};\n\n/**\n * Disable switch element.\n *\n * @api public\n */\n\nSwitchery.prototype.disable = function() {\n  if (!this.options.disabled) this.options.disabled = true;\n  if (!this.element.disabled) this.element.disabled = true;\n  if (!this.element.readOnly) this.element.readOnly = true;\n  this.switcher.style.opacity = this.options.disabledOpacity;\n  this.destroy();\n};\n\n});\n\nif (typeof exports == \"object\") {\n  module.exports = require(\"switchery\");\n} else if (typeof define == \"function\" && define.amd) {\n  define(\"Switchery\", [], function(){ return require(\"switchery\"); });\n} else {\n  (this || window)[\"Switchery\"] = require(\"switchery\");\n}\n})()\n"
  },
  {
    "path": "static/assets/plugins/switchery/meteor/export.js",
    "content": "/*global Switchery:true*/ // Meteor creates a file-scope global for exporting. This comment prevents a potential JSHint warning.\nSwitchery = window.Switchery;\ndelete window.Switchery;"
  },
  {
    "path": "static/assets/plugins/switchery/meteor/tests.js",
    "content": "'use strict';\n\nTinytest.add('Switchery integration', function (test) {\n\n    var checkbox = document.createElement('input');\n    checkbox.className = 'js-switch';\n    var switchy = new Switchery(checkbox);\n\n    test.instanceOf(switchy, Switchery, 'instantiation OK');\n});"
  },
  {
    "path": "static/assets/plugins/switchery/switchery.css",
    "content": "/*\n *\n * Main stylesheet for Switchery.\n * http://abpetkov.github.io/switchery/\n *\n */\n\n/* Switchery defaults. */\n\n.switchery {\n  background-color: #fff;\n  border: 1px solid #dfdfdf;\n  border-radius: 20px;\n  cursor: pointer;\n  display: inline-block;\n  height: 30px;\n  position: relative;\n  vertical-align: middle;\n  width: 50px;\n\n  -moz-user-select: none;\n  -khtml-user-select: none;\n  -webkit-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n\n  -webkit-background-clip: content-box;\n  background-clip: content-box;\n}\n\n.switchery > small {\n  background: #fff;\n  border-radius: 100%;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);\n  height: 30px;\n  position: absolute;\n  top: 0;\n  width: 30px;\n}\n\n/* Switchery sizes. */\n\n.switchery-small {\n  border-radius: 20px;\n  height: 20px;\n  width: 33px;\n}\n\n.switchery-small > small {\n  height: 20px;\n  width: 20px;\n}\n\n.switchery-large {\n  border-radius: 40px;\n  height: 40px;\n  width: 66px;\n}\n\n.switchery-large > small {\n  height: 40px;\n  width: 40px;\n}\n"
  },
  {
    "path": "static/assets/plugins/switchery/switchery.js",
    "content": "/**\n * Switchery 0.8.1\n * http://abpetkov.github.io/switchery/\n *\n * Authored by Alexander Petkov\n * https://github.com/abpetkov\n *\n * Copyright 2013-2015, Alexander Petkov\n * License: The MIT License (MIT)\n * http://opensource.org/licenses/MIT\n *\n */\n\n/**\n * External dependencies.\n */\n\nvar transitionize = require('transitionize')\n  , fastclick = require('fastclick')\n  , classes = require('classes')\n  , events = require('events');\n\n/**\n * Expose `Switchery`.\n */\n\nmodule.exports = Switchery;\n\n/**\n * Set Switchery default values.\n *\n * @api public\n */\n\nvar defaults = {\n    color             : '#64bd63'\n  , secondaryColor    : '#dfdfdf'\n  , jackColor         : '#fff'\n  , jackSecondaryColor: null\n  , className         : 'switchery'\n  , disabled          : false\n  , disabledOpacity   : 0.5\n  , speed             : '0.4s'\n  , size              : 'default'\n};\n\n/**\n * Create Switchery object.\n *\n * @param {Object} element\n * @param {Object} options\n * @api public\n */\n\nfunction Switchery(element, options) {\n  if (!(this instanceof Switchery)) return new Switchery(element, options);\n\n  this.element = element;\n  this.options = options || {};\n\n  for (var i in defaults) {\n    if (this.options[i] == null) {\n      this.options[i] = defaults[i];\n    }\n  }\n\n  if (this.element != null && this.element.type == 'checkbox') this.init();\n  if (this.isDisabled() === true) this.disable();\n}\n\n/**\n * Hide the target element.\n *\n * @api private\n */\n\nSwitchery.prototype.hide = function() {\n  this.element.style.display = 'none';\n};\n\n/**\n * Show custom switch after the target element.\n *\n * @api private\n */\n\nSwitchery.prototype.show = function() {\n  var switcher = this.create();\n  this.insertAfter(this.element, switcher);\n};\n\n/**\n * Create custom switch.\n *\n * @returns {Object} this.switcher\n * @api private\n */\n\nSwitchery.prototype.create = function() {\n  this.switcher = document.createElement('span');\n  this.jack = document.createElement('small');\n  this.switcher.appendChild(this.jack);\n  this.switcher.className = this.options.className;\n  this.events = events(this.switcher, this);\n\n  return this.switcher;\n};\n\n/**\n * Insert after element after another element.\n *\n * @param {Object} reference\n * @param {Object} target\n * @api private\n */\n\nSwitchery.prototype.insertAfter = function(reference, target) {\n  reference.parentNode.insertBefore(target, reference.nextSibling);\n};\n\n/**\n * Set switch jack proper position.\n *\n * @param {Boolean} clicked - we need this in order to uncheck the input when the switch is clicked\n * @api private\n */\n\nSwitchery.prototype.setPosition = function (clicked) {\n  var checked = this.isChecked()\n    , switcher = this.switcher\n    , jack = this.jack;\n\n  if (clicked && checked) checked = false;\n  else if (clicked && !checked) checked = true;\n\n  if (checked === true) {\n    this.element.checked = true;\n\n    if (window.getComputedStyle) jack.style.left = parseInt(window.getComputedStyle(switcher).width) - parseInt(window.getComputedStyle(jack).width) + 'px';\n    else jack.style.left = parseInt(switcher.currentStyle['width']) - parseInt(jack.currentStyle['width']) + 'px';\n\n    if (this.options.color) this.colorize();\n    this.setSpeed();\n  } else {\n    jack.style.left = 0;\n    this.element.checked = false;\n    this.switcher.style.boxShadow = 'inset 0 0 0 0 ' + this.options.secondaryColor;\n    this.switcher.style.borderColor = this.options.secondaryColor;\n    this.switcher.style.backgroundColor = (this.options.secondaryColor !== defaults.secondaryColor) ? this.options.secondaryColor : '#fff';\n    this.jack.style.backgroundColor = (this.options.jackSecondaryColor !== this.options.jackColor) ? this.options.jackSecondaryColor : this.options.jackColor;\n    this.setSpeed();\n  }\n};\n\n/**\n * Set speed.\n *\n * @api private\n */\n\nSwitchery.prototype.setSpeed = function() {\n  var switcherProp = {}\n    , jackProp = {\n        'background-color': this.options.speed\n      , 'left': this.options.speed.replace(/[a-z]/, '') / 2 + 's'\n    };\n\n  if (this.isChecked()) {\n    switcherProp = {\n        'border': this.options.speed\n      , 'box-shadow': this.options.speed\n      , 'background-color': this.options.speed.replace(/[a-z]/, '') * 3 + 's'\n    };\n  } else {\n    switcherProp = {\n        'border': this.options.speed\n      , 'box-shadow': this.options.speed\n    };\n  }\n\n  transitionize(this.switcher, switcherProp);\n  transitionize(this.jack, jackProp);\n};\n\n/**\n * Set switch size.\n *\n * @api private\n */\n\nSwitchery.prototype.setSize = function() {\n  var small = 'switchery-small'\n    , normal = 'switchery-default'\n    , large = 'switchery-large';\n\n  switch (this.options.size) {\n    case 'small':\n      classes(this.switcher).add(small)\n      break;\n    case 'large':\n      classes(this.switcher).add(large)\n      break;\n    default:\n      classes(this.switcher).add(normal)\n      break;\n  }\n};\n\n/**\n * Set switch color.\n *\n * @api private\n */\n\nSwitchery.prototype.colorize = function() {\n  var switcherHeight = this.switcher.offsetHeight / 2;\n\n  this.switcher.style.backgroundColor = this.options.color;\n  this.switcher.style.borderColor = this.options.color;\n  this.switcher.style.boxShadow = 'inset 0 0 0 ' + switcherHeight + 'px ' + this.options.color;\n  this.jack.style.backgroundColor = this.options.jackColor;\n};\n\n/**\n * Handle the onchange event.\n *\n * @param {Boolean} state\n * @api private\n */\n\nSwitchery.prototype.handleOnchange = function(state) {\n  if (document.dispatchEvent) {\n    var event = document.createEvent('HTMLEvents');\n    event.initEvent('change', true, true);\n    this.element.dispatchEvent(event);\n  } else {\n    this.element.fireEvent('onchange');\n  }\n};\n\n/**\n * Handle the native input element state change.\n * A `change` event must be fired in order to detect the change.\n *\n * @api private\n */\n\nSwitchery.prototype.handleChange = function() {\n  var self = this\n    , el = this.element;\n\n  if (el.addEventListener) {\n    el.addEventListener('change', function() {\n      self.setPosition();\n    });\n  } else {\n    el.attachEvent('onchange', function() {\n      self.setPosition();\n    });\n  }\n};\n\n/**\n * Handle the switch click event.\n *\n * @api private\n */\n\nSwitchery.prototype.handleClick = function() {\n  var switcher = this.switcher;\n\n  fastclick(switcher);\n  this.events.bind('click', 'bindClick');\n};\n\n/**\n * Attach all methods that need to happen on switcher click.\n *\n * @api private\n */\n\nSwitchery.prototype.bindClick = function() {\n  var parent = this.element.parentNode.tagName.toLowerCase()\n    , labelParent = (parent === 'label') ? false : true;\n\n  this.setPosition(labelParent);\n  this.handleOnchange(this.element.checked);\n};\n\n/**\n * Mark an individual switch as already handled.\n *\n * @api private\n */\n\nSwitchery.prototype.markAsSwitched = function() {\n  this.element.setAttribute('data-switchery', true);\n};\n\n/**\n * Check if an individual switch is already handled.\n *\n * @api private\n */\n\nSwitchery.prototype.markedAsSwitched = function() {\n  return this.element.getAttribute('data-switchery');\n};\n\n/**\n * Initialize Switchery.\n *\n * @api private\n */\n\nSwitchery.prototype.init = function() {\n  this.hide();\n  this.show();\n  this.setSize();\n  this.setPosition();\n  this.markAsSwitched();\n  this.handleChange();\n  this.handleClick();\n};\n\n/**\n * See if input is checked.\n *\n * @returns {Boolean}\n * @api public\n */\n\nSwitchery.prototype.isChecked = function() {\n  return this.element.checked;\n};\n\n/**\n * See if switcher should be disabled.\n *\n * @returns {Boolean}\n * @api public\n */\n\nSwitchery.prototype.isDisabled = function() {\n  return this.options.disabled || this.element.disabled || this.element.readOnly;\n};\n\n/**\n * Destroy all event handlers attached to the switch.\n *\n * @api public\n */\n\nSwitchery.prototype.destroy = function() {\n  this.events.unbind();\n};\n\n/**\n * Enable disabled switch element.\n *\n * @api public\n */\n\nSwitchery.prototype.enable = function() {\n  if (this.options.disabled) this.options.disabled = false;\n  if (this.element.disabled) this.element.disabled = false;\n  if (this.element.readOnly) this.element.readOnly = false;\n  this.switcher.style.opacity = 1;\n  this.events.bind('click', 'bindClick');\n};\n\n/**\n * Disable switch element.\n *\n * @api public\n */\n\nSwitchery.prototype.disable = function() {\n  if (!this.options.disabled) this.options.disabled = true;\n  if (!this.element.disabled) this.element.disabled = true;\n  if (!this.element.readOnly) this.element.readOnly = true;\n  this.switcher.style.opacity = this.options.disabledOpacity;\n  this.destroy();\n};\n"
  },
  {
    "path": "static/assets/plugins/tiny-editable/mindmup-editabletable.js",
    "content": "/*global $, window*/\n$.fn.editableTableWidget = function (options) {\n\t'use strict';\n\treturn $(this).each(function () {\n\t\tvar buildDefaultOptions = function () {\n\t\t\t\tvar opts = $.extend({}, $.fn.editableTableWidget.defaultOptions);\n\t\t\t\topts.editor = opts.editor.clone();\n\t\t\t\treturn opts;\n\t\t\t},\n\t\t\tactiveOptions = $.extend(buildDefaultOptions(), options),\n\t\t\tARROW_LEFT = 37, ARROW_UP = 38, ARROW_RIGHT = 39, ARROW_DOWN = 40, ENTER = 13, ESC = 27, TAB = 9,\n\t\t\telement = $(this),\n\t\t\teditor = activeOptions.editor.css('position', 'absolute').hide().appendTo(element.parent()),\n\t\t\tactive,\n\t\t\tshowEditor = function (select) {\n\t\t\t\tactive = element.find('td:focus');\n\t\t\t\tif (active.length) {\n\t\t\t\t\teditor.val(active.text())\n\t\t\t\t\t\t.removeClass('error')\n\t\t\t\t\t\t.show()\n\t\t\t\t\t\t.offset(active.offset())\n\t\t\t\t\t\t.css(active.css(activeOptions.cloneProperties))\n\t\t\t\t\t\t.width(active.width())\n\t\t\t\t\t\t.height(active.height())\n\t\t\t\t\t\t.focus();\n\t\t\t\t\tif (select) {\n\t\t\t\t\t\teditor.select();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetActiveText = function () {\n\t\t\t\tvar text = editor.val(),\n\t\t\t\t\tevt = $.Event('change'),\n\t\t\t\t\toriginalContent;\n\t\t\t\tif (active.text() === text || editor.hasClass('error')) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\toriginalContent = active.html();\n\t\t\t\tactive.text(text).trigger(evt, text);\n\t\t\t\tif (evt.result === false) {\n\t\t\t\t\tactive.html(originalContent);\n\t\t\t\t}\n\t\t\t},\n\t\t\tmovement = function (element, keycode) {\n\t\t\t\tif (keycode === ARROW_RIGHT) {\n\t\t\t\t\treturn element.next('td');\n\t\t\t\t} else if (keycode === ARROW_LEFT) {\n\t\t\t\t\treturn element.prev('td');\n\t\t\t\t} else if (keycode === ARROW_UP) {\n\t\t\t\t\treturn element.parent().prev().children().eq(element.index());\n\t\t\t\t} else if (keycode === ARROW_DOWN) {\n\t\t\t\t\treturn element.parent().next().children().eq(element.index());\n\t\t\t\t}\n\t\t\t\treturn [];\n\t\t\t};\n\t\teditor.blur(function () {\n\t\t\tsetActiveText();\n\t\t\teditor.hide();\n\t\t}).keydown(function (e) {\n\t\t\tif (e.which === ENTER) {\n\t\t\t\tsetActiveText();\n\t\t\t\teditor.hide();\n\t\t\t\tactive.focus();\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t} else if (e.which === ESC) {\n\t\t\t\teditor.val(active.text());\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t\teditor.hide();\n\t\t\t\tactive.focus();\n\t\t\t} else if (e.which === TAB) {\n\t\t\t\tactive.focus();\n\t\t\t} else if (this.selectionEnd - this.selectionStart === this.value.length) {\n\t\t\t\tvar possibleMove = movement(active, e.which);\n\t\t\t\tif (possibleMove.length > 0) {\n\t\t\t\t\tpossibleMove.focus();\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t\t.on('input paste', function () {\n\t\t\tvar evt = $.Event('validate');\n\t\t\tactive.trigger(evt, editor.val());\n\t\t\tif (evt.result === false) {\n\t\t\t\teditor.addClass('error');\n\t\t\t} else {\n\t\t\t\teditor.removeClass('error');\n\t\t\t}\n\t\t});\n\t\telement.on('click keypress dblclick', showEditor)\n\t\t.css('cursor', 'pointer')\n\t\t.keydown(function (e) {\n\t\t\tvar prevent = true,\n\t\t\t\tpossibleMove = movement($(e.target), e.which);\n\t\t\tif (possibleMove.length > 0) {\n\t\t\t\tpossibleMove.focus();\n\t\t\t} else if (e.which === ENTER) {\n\t\t\t\tshowEditor(false);\n\t\t\t} else if (e.which === 17 || e.which === 91 || e.which === 93) {\n\t\t\t\tshowEditor(true);\n\t\t\t\tprevent = false;\n\t\t\t} else {\n\t\t\t\tprevent = false;\n\t\t\t}\n\t\t\tif (prevent) {\n\t\t\t\te.stopPropagation();\n\t\t\t\te.preventDefault();\n\t\t\t}\n\t\t});\n\n\t\telement.find('td').prop('tabindex', 1);\n\n\t\t$(window).on('resize', function () {\n\t\t\tif (editor.is(':visible')) {\n\t\t\t\teditor.offset(active.offset())\n\t\t\t\t.width(active.width())\n\t\t\t\t.height(active.height());\n\t\t\t}\n\t\t});\n\t});\n\n};\n$.fn.editableTableWidget.defaultOptions = {\n\tcloneProperties: ['padding', 'padding-top', 'padding-bottom', 'padding-left', 'padding-right',\n\t\t\t\t\t  'text-align', 'font', 'font-size', 'font-family', 'font-weight',\n\t\t\t\t\t  'border', 'border-top', 'border-bottom', 'border-left', 'border-right'],\n\teditor: $('<input>')\n};\n\n"
  },
  {
    "path": "static/assets/plugins/tiny-editable/numeric-input-example.js",
    "content": "/* global $ */\n/* this is an example for validation and change events */\n$.fn.numericInputExample = function () {\n\t'use strict';\n\tvar element = $(this),\n\t\tfooter = element.find('tfoot tr'),\n\t\tdataRows = element.find('tbody tr'),\n\t\tinitialTotal = function () {\n\t\t\tvar column, total;\n\t\t\tfor (column = 1; column < footer.children().size(); column++) {\n\t\t\t\ttotal = 0;\n\t\t\t\tdataRows.each(function () {\n\t\t\t\t\tvar row = $(this);\n\t\t\t\t\ttotal += parseFloat(row.children().eq(column).text());\n\t\t\t\t});\n\t\t\t\tfooter.children().eq(column).text(total);\n\t\t\t};\n\t\t};\n\telement.find('td').on('change', function (evt) {\n\t\tvar cell = $(this),\n\t\t\tcolumn = cell.index(),\n\t\t\ttotal = 0;\n\t\tif (column === 0) {\n\t\t\treturn;\n\t\t}\n\t\telement.find('tbody tr').each(function () {\n\t\t\tvar row = $(this);\n\t\t\ttotal += parseFloat(row.children().eq(column).text());\n\t\t});\n\t\tif (column === 1 && total > 5000) {\n\t\t\t$('.alert').show();\n\t\t\treturn false; // changes can be rejected\n\t\t} else {\n\t\t\t$('.alert').hide();\n\t\t\tfooter.children().eq(column).text(total);\n\t\t}\n\t}).on('validate', function (evt, value) {\n\t\tvar cell = $(this),\n\t\t\tcolumn = cell.index();\n\t\tif (column === 0) {\n\t\t\treturn !!value && value.trim().length > 0;\n\t\t} else {\n\t\t\treturn !isNaN(parseFloat(value)) && isFinite(value);\n\t\t}\n\t});\n\tinitialTotal();\n\treturn this;\n};\n"
  },
  {
    "path": "static/assets/plugins/waypoints/lib/jquery.waypoints.js",
    "content": "/*!\nWaypoints - 3.1.1\nCopyright © 2011-2015 Caleb Troughton\nLicensed under the MIT license.\nhttps://github.com/imakewebthings/waypoints/blog/master/licenses.txt\n*/\n(function() {\n  'use strict'\n\n  var keyCounter = 0\n  var allWaypoints = {}\n\n  /* http://imakewebthings.com/waypoints/api/waypoint */\n  function Waypoint(options) {\n    if (!options) {\n      throw new Error('No options passed to Waypoint constructor')\n    }\n    if (!options.element) {\n      throw new Error('No element option passed to Waypoint constructor')\n    }\n    if (!options.handler) {\n      throw new Error('No handler option passed to Waypoint constructor')\n    }\n\n    this.key = 'waypoint-' + keyCounter\n    this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)\n    this.element = this.options.element\n    this.adapter = new Waypoint.Adapter(this.element)\n    this.callback = options.handler\n    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'\n    this.enabled = this.options.enabled\n    this.triggerPoint = null\n    this.group = Waypoint.Group.findOrCreate({\n      name: this.options.group,\n      axis: this.axis\n    })\n    this.context = Waypoint.Context.findOrCreateByElement(this.options.context)\n\n    if (Waypoint.offsetAliases[this.options.offset]) {\n      this.options.offset = Waypoint.offsetAliases[this.options.offset]\n    }\n    this.group.add(this)\n    this.context.add(this)\n    allWaypoints[this.key] = this\n    keyCounter += 1\n  }\n\n  /* Private */\n  Waypoint.prototype.queueTrigger = function(direction) {\n    this.group.queueTrigger(this, direction)\n  }\n\n  /* Private */\n  Waypoint.prototype.trigger = function(args) {\n    if (!this.enabled) {\n      return\n    }\n    if (this.callback) {\n      this.callback.apply(this, args)\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/destroy */\n  Waypoint.prototype.destroy = function() {\n    this.context.remove(this)\n    this.group.remove(this)\n    delete allWaypoints[this.key]\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/disable */\n  Waypoint.prototype.disable = function() {\n    this.enabled = false\n    return this\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/enable */\n  Waypoint.prototype.enable = function() {\n    this.context.refresh()\n    this.enabled = true\n    return this\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/next */\n  Waypoint.prototype.next = function() {\n    return this.group.next(this)\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/previous */\n  Waypoint.prototype.previous = function() {\n    return this.group.previous(this)\n  }\n\n  /* Private */\n  Waypoint.invokeAll = function(method) {\n    var allWaypointsArray = []\n    for (var waypointKey in allWaypoints) {\n      allWaypointsArray.push(allWaypoints[waypointKey])\n    }\n    for (var i = 0, end = allWaypointsArray.length; i < end; i++) {\n      allWaypointsArray[i][method]()\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/destroy-all */\n  Waypoint.destroyAll = function() {\n    Waypoint.invokeAll('destroy')\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/disable-all */\n  Waypoint.disableAll = function() {\n    Waypoint.invokeAll('disable')\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/enable-all */\n  Waypoint.enableAll = function() {\n    Waypoint.invokeAll('enable')\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/refresh-all */\n  Waypoint.refreshAll = function() {\n    Waypoint.Context.refreshAll()\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/viewport-height */\n  Waypoint.viewportHeight = function() {\n    return window.innerHeight || document.documentElement.clientHeight\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/viewport-width */\n  Waypoint.viewportWidth = function() {\n    return document.documentElement.clientWidth\n  }\n\n  Waypoint.adapters = []\n\n  Waypoint.defaults = {\n    context: window,\n    continuous: true,\n    enabled: true,\n    group: 'default',\n    horizontal: false,\n    offset: 0\n  }\n\n  Waypoint.offsetAliases = {\n    'bottom-in-view': function() {\n      return this.context.innerHeight() - this.adapter.outerHeight()\n    },\n    'right-in-view': function() {\n      return this.context.innerWidth() - this.adapter.outerWidth()\n    }\n  }\n\n  window.Waypoint = Waypoint\n}())\n;(function() {\n  'use strict'\n\n  function requestAnimationFrameShim(callback) {\n    window.setTimeout(callback, 1000 / 60)\n  }\n\n  var keyCounter = 0\n  var contexts = {}\n  var Waypoint = window.Waypoint\n  var oldWindowLoad = window.onload\n\n  /* http://imakewebthings.com/waypoints/api/context */\n  function Context(element) {\n    this.element = element\n    this.Adapter = Waypoint.Adapter\n    this.adapter = new this.Adapter(element)\n    this.key = 'waypoint-context-' + keyCounter\n    this.didScroll = false\n    this.didResize = false\n    this.oldScroll = {\n      x: this.adapter.scrollLeft(),\n      y: this.adapter.scrollTop()\n    }\n    this.waypoints = {\n      vertical: {},\n      horizontal: {}\n    }\n\n    element.waypointContextKey = this.key\n    contexts[element.waypointContextKey] = this\n    keyCounter += 1\n\n    this.createThrottledScrollHandler()\n    this.createThrottledResizeHandler()\n  }\n\n  /* Private */\n  Context.prototype.add = function(waypoint) {\n    var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'\n    this.waypoints[axis][waypoint.key] = waypoint\n    this.refresh()\n  }\n\n  /* Private */\n  Context.prototype.checkEmpty = function() {\n    var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)\n    var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)\n    if (horizontalEmpty && verticalEmpty) {\n      this.adapter.off('.waypoints')\n      delete contexts[this.key]\n    }\n  }\n\n  /* Private */\n  Context.prototype.createThrottledResizeHandler = function() {\n    var self = this\n\n    function resizeHandler() {\n      self.handleResize()\n      self.didResize = false\n    }\n\n    this.adapter.on('resize.waypoints', function() {\n      if (!self.didResize) {\n        self.didResize = true\n        Waypoint.requestAnimationFrame(resizeHandler)\n      }\n    })\n  }\n\n  /* Private */\n  Context.prototype.createThrottledScrollHandler = function() {\n    var self = this\n    function scrollHandler() {\n      self.handleScroll()\n      self.didScroll = false\n    }\n\n    this.adapter.on('scroll.waypoints', function() {\n      if (!self.didScroll || Waypoint.isTouch) {\n        self.didScroll = true\n        Waypoint.requestAnimationFrame(scrollHandler)\n      }\n    })\n  }\n\n  /* Private */\n  Context.prototype.handleResize = function() {\n    Waypoint.Context.refreshAll()\n  }\n\n  /* Private */\n  Context.prototype.handleScroll = function() {\n    var triggeredGroups = {}\n    var axes = {\n      horizontal: {\n        newScroll: this.adapter.scrollLeft(),\n        oldScroll: this.oldScroll.x,\n        forward: 'right',\n        backward: 'left'\n      },\n      vertical: {\n        newScroll: this.adapter.scrollTop(),\n        oldScroll: this.oldScroll.y,\n        forward: 'down',\n        backward: 'up'\n      }\n    }\n\n    for (var axisKey in axes) {\n      var axis = axes[axisKey]\n      var isForward = axis.newScroll > axis.oldScroll\n      var direction = isForward ? axis.forward : axis.backward\n\n      for (var waypointKey in this.waypoints[axisKey]) {\n        var waypoint = this.waypoints[axisKey][waypointKey]\n        var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint\n        var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint\n        var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint\n        var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint\n        if (crossedForward || crossedBackward) {\n          waypoint.queueTrigger(direction)\n          triggeredGroups[waypoint.group.id] = waypoint.group\n        }\n      }\n    }\n\n    for (var groupKey in triggeredGroups) {\n      triggeredGroups[groupKey].flushTriggers()\n    }\n\n    this.oldScroll = {\n      x: axes.horizontal.newScroll,\n      y: axes.vertical.newScroll\n    }\n  }\n\n  /* Private */\n  Context.prototype.innerHeight = function() {\n    /*eslint-disable eqeqeq */\n    if (this.element == this.element.window) {\n      return Waypoint.viewportHeight()\n    }\n    /*eslint-enable eqeqeq */\n    return this.adapter.innerHeight()\n  }\n\n  /* Private */\n  Context.prototype.remove = function(waypoint) {\n    delete this.waypoints[waypoint.axis][waypoint.key]\n    this.checkEmpty()\n  }\n\n  /* Private */\n  Context.prototype.innerWidth = function() {\n    /*eslint-disable eqeqeq */\n    if (this.element == this.element.window) {\n      return Waypoint.viewportWidth()\n    }\n    /*eslint-enable eqeqeq */\n    return this.adapter.innerWidth()\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/context-destroy */\n  Context.prototype.destroy = function() {\n    var allWaypoints = []\n    for (var axis in this.waypoints) {\n      for (var waypointKey in this.waypoints[axis]) {\n        allWaypoints.push(this.waypoints[axis][waypointKey])\n      }\n    }\n    for (var i = 0, end = allWaypoints.length; i < end; i++) {\n      allWaypoints[i].destroy()\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/context-refresh */\n  Context.prototype.refresh = function() {\n    /*eslint-disable eqeqeq */\n    var isWindow = this.element == this.element.window\n    /*eslint-enable eqeqeq */\n    var contextOffset = this.adapter.offset()\n    var triggeredGroups = {}\n    var axes\n\n    this.handleScroll()\n    axes = {\n      horizontal: {\n        contextOffset: isWindow ? 0 : contextOffset.left,\n        contextScroll: isWindow ? 0 : this.oldScroll.x,\n        contextDimension: this.innerWidth(),\n        oldScroll: this.oldScroll.x,\n        forward: 'right',\n        backward: 'left',\n        offsetProp: 'left'\n      },\n      vertical: {\n        contextOffset: isWindow ? 0 : contextOffset.top,\n        contextScroll: isWindow ? 0 : this.oldScroll.y,\n        contextDimension: this.innerHeight(),\n        oldScroll: this.oldScroll.y,\n        forward: 'down',\n        backward: 'up',\n        offsetProp: 'top'\n      }\n    }\n\n    for (var axisKey in axes) {\n      var axis = axes[axisKey]\n      for (var waypointKey in this.waypoints[axisKey]) {\n        var waypoint = this.waypoints[axisKey][waypointKey]\n        var adjustment = waypoint.options.offset\n        var oldTriggerPoint = waypoint.triggerPoint\n        var elementOffset = 0\n        var freshWaypoint = oldTriggerPoint == null\n        var contextModifier, wasBeforeScroll, nowAfterScroll\n        var triggeredBackward, triggeredForward\n\n        if (waypoint.element !== waypoint.element.window) {\n          elementOffset = waypoint.adapter.offset()[axis.offsetProp]\n        }\n\n        if (typeof adjustment === 'function') {\n          adjustment = adjustment.apply(waypoint)\n        }\n        else if (typeof adjustment === 'string') {\n          adjustment = parseFloat(adjustment)\n          if (waypoint.options.offset.indexOf('%') > - 1) {\n            adjustment = Math.ceil(axis.contextDimension * adjustment / 100)\n          }\n        }\n\n        contextModifier = axis.contextScroll - axis.contextOffset\n        waypoint.triggerPoint = elementOffset + contextModifier - adjustment\n        wasBeforeScroll = oldTriggerPoint < axis.oldScroll\n        nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll\n        triggeredBackward = wasBeforeScroll && nowAfterScroll\n        triggeredForward = !wasBeforeScroll && !nowAfterScroll\n\n        if (!freshWaypoint && triggeredBackward) {\n          waypoint.queueTrigger(axis.backward)\n          triggeredGroups[waypoint.group.id] = waypoint.group\n        }\n        else if (!freshWaypoint && triggeredForward) {\n          waypoint.queueTrigger(axis.forward)\n          triggeredGroups[waypoint.group.id] = waypoint.group\n        }\n        else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {\n          waypoint.queueTrigger(axis.forward)\n          triggeredGroups[waypoint.group.id] = waypoint.group\n        }\n      }\n    }\n\n    for (var groupKey in triggeredGroups) {\n      triggeredGroups[groupKey].flushTriggers()\n    }\n\n    return this\n  }\n\n  /* Private */\n  Context.findOrCreateByElement = function(element) {\n    return Context.findByElement(element) || new Context(element)\n  }\n\n  /* Private */\n  Context.refreshAll = function() {\n    for (var contextId in contexts) {\n      contexts[contextId].refresh()\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/context-find-by-element */\n  Context.findByElement = function(element) {\n    return contexts[element.waypointContextKey]\n  }\n\n  window.onload = function() {\n    if (oldWindowLoad) {\n      oldWindowLoad()\n    }\n    Context.refreshAll()\n  }\n\n  Waypoint.requestAnimationFrame = function(callback) {\n    var requestFn = window.requestAnimationFrame ||\n      window.mozRequestAnimationFrame ||\n      window.webkitRequestAnimationFrame ||\n      requestAnimationFrameShim\n    requestFn.call(window, callback)\n  }\n  Waypoint.Context = Context\n}())\n;(function() {\n  'use strict'\n\n  function byTriggerPoint(a, b) {\n    return a.triggerPoint - b.triggerPoint\n  }\n\n  function byReverseTriggerPoint(a, b) {\n    return b.triggerPoint - a.triggerPoint\n  }\n\n  var groups = {\n    vertical: {},\n    horizontal: {}\n  }\n  var Waypoint = window.Waypoint\n\n  /* http://imakewebthings.com/waypoints/api/group */\n  function Group(options) {\n    this.name = options.name\n    this.axis = options.axis\n    this.id = this.name + '-' + this.axis\n    this.waypoints = []\n    this.clearTriggerQueues()\n    groups[this.axis][this.name] = this\n  }\n\n  /* Private */\n  Group.prototype.add = function(waypoint) {\n    this.waypoints.push(waypoint)\n  }\n\n  /* Private */\n  Group.prototype.clearTriggerQueues = function() {\n    this.triggerQueues = {\n      up: [],\n      down: [],\n      left: [],\n      right: []\n    }\n  }\n\n  /* Private */\n  Group.prototype.flushTriggers = function() {\n    for (var direction in this.triggerQueues) {\n      var waypoints = this.triggerQueues[direction]\n      var reverse = direction === 'up' || direction === 'left'\n      waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)\n      for (var i = 0, end = waypoints.length; i < end; i += 1) {\n        var waypoint = waypoints[i]\n        if (waypoint.options.continuous || i === waypoints.length - 1) {\n          waypoint.trigger([direction])\n        }\n      }\n    }\n    this.clearTriggerQueues()\n  }\n\n  /* Private */\n  Group.prototype.next = function(waypoint) {\n    this.waypoints.sort(byTriggerPoint)\n    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)\n    var isLast = index === this.waypoints.length - 1\n    return isLast ? null : this.waypoints[index + 1]\n  }\n\n  /* Private */\n  Group.prototype.previous = function(waypoint) {\n    this.waypoints.sort(byTriggerPoint)\n    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)\n    return index ? this.waypoints[index - 1] : null\n  }\n\n  /* Private */\n  Group.prototype.queueTrigger = function(waypoint, direction) {\n    this.triggerQueues[direction].push(waypoint)\n  }\n\n  /* Private */\n  Group.prototype.remove = function(waypoint) {\n    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)\n    if (index > -1) {\n      this.waypoints.splice(index, 1)\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/first */\n  Group.prototype.first = function() {\n    return this.waypoints[0]\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/last */\n  Group.prototype.last = function() {\n    return this.waypoints[this.waypoints.length - 1]\n  }\n\n  /* Private */\n  Group.findOrCreate = function(options) {\n    return groups[options.axis][options.name] || new Group(options)\n  }\n\n  Waypoint.Group = Group\n}())\n;(function() {\n  'use strict'\n\n  var $ = window.jQuery\n  var Waypoint = window.Waypoint\n\n  function JQueryAdapter(element) {\n    this.$element = $(element)\n  }\n\n  $.each([\n    'innerHeight',\n    'innerWidth',\n    'off',\n    'offset',\n    'on',\n    'outerHeight',\n    'outerWidth',\n    'scrollLeft',\n    'scrollTop'\n  ], function(i, method) {\n    JQueryAdapter.prototype[method] = function() {\n      var args = Array.prototype.slice.call(arguments)\n      return this.$element[method].apply(this.$element, args)\n    }\n  })\n\n  $.each([\n    'extend',\n    'inArray',\n    'isEmptyObject'\n  ], function(i, method) {\n    JQueryAdapter[method] = $[method]\n  })\n\n  Waypoint.adapters.push({\n    name: 'jquery',\n    Adapter: JQueryAdapter\n  })\n  Waypoint.Adapter = JQueryAdapter\n}())\n;(function() {\n  'use strict'\n\n  var Waypoint = window.Waypoint\n\n  function createExtension(framework) {\n    return function() {\n      var waypoints = []\n      var overrides = arguments[0]\n\n      if (framework.isFunction(arguments[0])) {\n        overrides = framework.extend({}, arguments[1])\n        overrides.handler = arguments[0]\n      }\n\n      this.each(function() {\n        var options = framework.extend({}, overrides, {\n          element: this\n        })\n        if (typeof options.context === 'string') {\n          options.context = framework(this).closest(options.context)[0]\n        }\n        waypoints.push(new Waypoint(options))\n      })\n\n      return waypoints\n    }\n  }\n\n  if (window.jQuery) {\n    window.jQuery.fn.waypoint = createExtension(window.jQuery)\n  }\n  if (window.Zepto) {\n    window.Zepto.fn.waypoint = createExtension(window.Zepto)\n  }\n}())\n;"
  },
  {
    "path": "static/assets/plugins/waypoints/lib/noframework.waypoints.js",
    "content": "/*!\nWaypoints - 3.1.1\nCopyright © 2011-2015 Caleb Troughton\nLicensed under the MIT license.\nhttps://github.com/imakewebthings/waypoints/blog/master/licenses.txt\n*/\n(function() {\n  'use strict'\n\n  var keyCounter = 0\n  var allWaypoints = {}\n\n  /* http://imakewebthings.com/waypoints/api/waypoint */\n  function Waypoint(options) {\n    if (!options) {\n      throw new Error('No options passed to Waypoint constructor')\n    }\n    if (!options.element) {\n      throw new Error('No element option passed to Waypoint constructor')\n    }\n    if (!options.handler) {\n      throw new Error('No handler option passed to Waypoint constructor')\n    }\n\n    this.key = 'waypoint-' + keyCounter\n    this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)\n    this.element = this.options.element\n    this.adapter = new Waypoint.Adapter(this.element)\n    this.callback = options.handler\n    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'\n    this.enabled = this.options.enabled\n    this.triggerPoint = null\n    this.group = Waypoint.Group.findOrCreate({\n      name: this.options.group,\n      axis: this.axis\n    })\n    this.context = Waypoint.Context.findOrCreateByElement(this.options.context)\n\n    if (Waypoint.offsetAliases[this.options.offset]) {\n      this.options.offset = Waypoint.offsetAliases[this.options.offset]\n    }\n    this.group.add(this)\n    this.context.add(this)\n    allWaypoints[this.key] = this\n    keyCounter += 1\n  }\n\n  /* Private */\n  Waypoint.prototype.queueTrigger = function(direction) {\n    this.group.queueTrigger(this, direction)\n  }\n\n  /* Private */\n  Waypoint.prototype.trigger = function(args) {\n    if (!this.enabled) {\n      return\n    }\n    if (this.callback) {\n      this.callback.apply(this, args)\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/destroy */\n  Waypoint.prototype.destroy = function() {\n    this.context.remove(this)\n    this.group.remove(this)\n    delete allWaypoints[this.key]\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/disable */\n  Waypoint.prototype.disable = function() {\n    this.enabled = false\n    return this\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/enable */\n  Waypoint.prototype.enable = function() {\n    this.context.refresh()\n    this.enabled = true\n    return this\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/next */\n  Waypoint.prototype.next = function() {\n    return this.group.next(this)\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/previous */\n  Waypoint.prototype.previous = function() {\n    return this.group.previous(this)\n  }\n\n  /* Private */\n  Waypoint.invokeAll = function(method) {\n    var allWaypointsArray = []\n    for (var waypointKey in allWaypoints) {\n      allWaypointsArray.push(allWaypoints[waypointKey])\n    }\n    for (var i = 0, end = allWaypointsArray.length; i < end; i++) {\n      allWaypointsArray[i][method]()\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/destroy-all */\n  Waypoint.destroyAll = function() {\n    Waypoint.invokeAll('destroy')\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/disable-all */\n  Waypoint.disableAll = function() {\n    Waypoint.invokeAll('disable')\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/enable-all */\n  Waypoint.enableAll = function() {\n    Waypoint.invokeAll('enable')\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/refresh-all */\n  Waypoint.refreshAll = function() {\n    Waypoint.Context.refreshAll()\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/viewport-height */\n  Waypoint.viewportHeight = function() {\n    return window.innerHeight || document.documentElement.clientHeight\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/viewport-width */\n  Waypoint.viewportWidth = function() {\n    return document.documentElement.clientWidth\n  }\n\n  Waypoint.adapters = []\n\n  Waypoint.defaults = {\n    context: window,\n    continuous: true,\n    enabled: true,\n    group: 'default',\n    horizontal: false,\n    offset: 0\n  }\n\n  Waypoint.offsetAliases = {\n    'bottom-in-view': function() {\n      return this.context.innerHeight() - this.adapter.outerHeight()\n    },\n    'right-in-view': function() {\n      return this.context.innerWidth() - this.adapter.outerWidth()\n    }\n  }\n\n  window.Waypoint = Waypoint\n}())\n;(function() {\n  'use strict'\n\n  function requestAnimationFrameShim(callback) {\n    window.setTimeout(callback, 1000 / 60)\n  }\n\n  var keyCounter = 0\n  var contexts = {}\n  var Waypoint = window.Waypoint\n  var oldWindowLoad = window.onload\n\n  /* http://imakewebthings.com/waypoints/api/context */\n  function Context(element) {\n    this.element = element\n    this.Adapter = Waypoint.Adapter\n    this.adapter = new this.Adapter(element)\n    this.key = 'waypoint-context-' + keyCounter\n    this.didScroll = false\n    this.didResize = false\n    this.oldScroll = {\n      x: this.adapter.scrollLeft(),\n      y: this.adapter.scrollTop()\n    }\n    this.waypoints = {\n      vertical: {},\n      horizontal: {}\n    }\n\n    element.waypointContextKey = this.key\n    contexts[element.waypointContextKey] = this\n    keyCounter += 1\n\n    this.createThrottledScrollHandler()\n    this.createThrottledResizeHandler()\n  }\n\n  /* Private */\n  Context.prototype.add = function(waypoint) {\n    var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'\n    this.waypoints[axis][waypoint.key] = waypoint\n    this.refresh()\n  }\n\n  /* Private */\n  Context.prototype.checkEmpty = function() {\n    var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)\n    var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)\n    if (horizontalEmpty && verticalEmpty) {\n      this.adapter.off('.waypoints')\n      delete contexts[this.key]\n    }\n  }\n\n  /* Private */\n  Context.prototype.createThrottledResizeHandler = function() {\n    var self = this\n\n    function resizeHandler() {\n      self.handleResize()\n      self.didResize = false\n    }\n\n    this.adapter.on('resize.waypoints', function() {\n      if (!self.didResize) {\n        self.didResize = true\n        Waypoint.requestAnimationFrame(resizeHandler)\n      }\n    })\n  }\n\n  /* Private */\n  Context.prototype.createThrottledScrollHandler = function() {\n    var self = this\n    function scrollHandler() {\n      self.handleScroll()\n      self.didScroll = false\n    }\n\n    this.adapter.on('scroll.waypoints', function() {\n      if (!self.didScroll || Waypoint.isTouch) {\n        self.didScroll = true\n        Waypoint.requestAnimationFrame(scrollHandler)\n      }\n    })\n  }\n\n  /* Private */\n  Context.prototype.handleResize = function() {\n    Waypoint.Context.refreshAll()\n  }\n\n  /* Private */\n  Context.prototype.handleScroll = function() {\n    var triggeredGroups = {}\n    var axes = {\n      horizontal: {\n        newScroll: this.adapter.scrollLeft(),\n        oldScroll: this.oldScroll.x,\n        forward: 'right',\n        backward: 'left'\n      },\n      vertical: {\n        newScroll: this.adapter.scrollTop(),\n        oldScroll: this.oldScroll.y,\n        forward: 'down',\n        backward: 'up'\n      }\n    }\n\n    for (var axisKey in axes) {\n      var axis = axes[axisKey]\n      var isForward = axis.newScroll > axis.oldScroll\n      var direction = isForward ? axis.forward : axis.backward\n\n      for (var waypointKey in this.waypoints[axisKey]) {\n        var waypoint = this.waypoints[axisKey][waypointKey]\n        var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint\n        var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint\n        var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint\n        var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint\n        if (crossedForward || crossedBackward) {\n          waypoint.queueTrigger(direction)\n          triggeredGroups[waypoint.group.id] = waypoint.group\n        }\n      }\n    }\n\n    for (var groupKey in triggeredGroups) {\n      triggeredGroups[groupKey].flushTriggers()\n    }\n\n    this.oldScroll = {\n      x: axes.horizontal.newScroll,\n      y: axes.vertical.newScroll\n    }\n  }\n\n  /* Private */\n  Context.prototype.innerHeight = function() {\n    /*eslint-disable eqeqeq */\n    if (this.element == this.element.window) {\n      return Waypoint.viewportHeight()\n    }\n    /*eslint-enable eqeqeq */\n    return this.adapter.innerHeight()\n  }\n\n  /* Private */\n  Context.prototype.remove = function(waypoint) {\n    delete this.waypoints[waypoint.axis][waypoint.key]\n    this.checkEmpty()\n  }\n\n  /* Private */\n  Context.prototype.innerWidth = function() {\n    /*eslint-disable eqeqeq */\n    if (this.element == this.element.window) {\n      return Waypoint.viewportWidth()\n    }\n    /*eslint-enable eqeqeq */\n    return this.adapter.innerWidth()\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/context-destroy */\n  Context.prototype.destroy = function() {\n    var allWaypoints = []\n    for (var axis in this.waypoints) {\n      for (var waypointKey in this.waypoints[axis]) {\n        allWaypoints.push(this.waypoints[axis][waypointKey])\n      }\n    }\n    for (var i = 0, end = allWaypoints.length; i < end; i++) {\n      allWaypoints[i].destroy()\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/context-refresh */\n  Context.prototype.refresh = function() {\n    /*eslint-disable eqeqeq */\n    var isWindow = this.element == this.element.window\n    /*eslint-enable eqeqeq */\n    var contextOffset = this.adapter.offset()\n    var triggeredGroups = {}\n    var axes\n\n    this.handleScroll()\n    axes = {\n      horizontal: {\n        contextOffset: isWindow ? 0 : contextOffset.left,\n        contextScroll: isWindow ? 0 : this.oldScroll.x,\n        contextDimension: this.innerWidth(),\n        oldScroll: this.oldScroll.x,\n        forward: 'right',\n        backward: 'left',\n        offsetProp: 'left'\n      },\n      vertical: {\n        contextOffset: isWindow ? 0 : contextOffset.top,\n        contextScroll: isWindow ? 0 : this.oldScroll.y,\n        contextDimension: this.innerHeight(),\n        oldScroll: this.oldScroll.y,\n        forward: 'down',\n        backward: 'up',\n        offsetProp: 'top'\n      }\n    }\n\n    for (var axisKey in axes) {\n      var axis = axes[axisKey]\n      for (var waypointKey in this.waypoints[axisKey]) {\n        var waypoint = this.waypoints[axisKey][waypointKey]\n        var adjustment = waypoint.options.offset\n        var oldTriggerPoint = waypoint.triggerPoint\n        var elementOffset = 0\n        var freshWaypoint = oldTriggerPoint == null\n        var contextModifier, wasBeforeScroll, nowAfterScroll\n        var triggeredBackward, triggeredForward\n\n        if (waypoint.element !== waypoint.element.window) {\n          elementOffset = waypoint.adapter.offset()[axis.offsetProp]\n        }\n\n        if (typeof adjustment === 'function') {\n          adjustment = adjustment.apply(waypoint)\n        }\n        else if (typeof adjustment === 'string') {\n          adjustment = parseFloat(adjustment)\n          if (waypoint.options.offset.indexOf('%') > - 1) {\n            adjustment = Math.ceil(axis.contextDimension * adjustment / 100)\n          }\n        }\n\n        contextModifier = axis.contextScroll - axis.contextOffset\n        waypoint.triggerPoint = elementOffset + contextModifier - adjustment\n        wasBeforeScroll = oldTriggerPoint < axis.oldScroll\n        nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll\n        triggeredBackward = wasBeforeScroll && nowAfterScroll\n        triggeredForward = !wasBeforeScroll && !nowAfterScroll\n\n        if (!freshWaypoint && triggeredBackward) {\n          waypoint.queueTrigger(axis.backward)\n          triggeredGroups[waypoint.group.id] = waypoint.group\n        }\n        else if (!freshWaypoint && triggeredForward) {\n          waypoint.queueTrigger(axis.forward)\n          triggeredGroups[waypoint.group.id] = waypoint.group\n        }\n        else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {\n          waypoint.queueTrigger(axis.forward)\n          triggeredGroups[waypoint.group.id] = waypoint.group\n        }\n      }\n    }\n\n    for (var groupKey in triggeredGroups) {\n      triggeredGroups[groupKey].flushTriggers()\n    }\n\n    return this\n  }\n\n  /* Private */\n  Context.findOrCreateByElement = function(element) {\n    return Context.findByElement(element) || new Context(element)\n  }\n\n  /* Private */\n  Context.refreshAll = function() {\n    for (var contextId in contexts) {\n      contexts[contextId].refresh()\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/context-find-by-element */\n  Context.findByElement = function(element) {\n    return contexts[element.waypointContextKey]\n  }\n\n  window.onload = function() {\n    if (oldWindowLoad) {\n      oldWindowLoad()\n    }\n    Context.refreshAll()\n  }\n\n  Waypoint.requestAnimationFrame = function(callback) {\n    var requestFn = window.requestAnimationFrame ||\n      window.mozRequestAnimationFrame ||\n      window.webkitRequestAnimationFrame ||\n      requestAnimationFrameShim\n    requestFn.call(window, callback)\n  }\n  Waypoint.Context = Context\n}())\n;(function() {\n  'use strict'\n\n  function byTriggerPoint(a, b) {\n    return a.triggerPoint - b.triggerPoint\n  }\n\n  function byReverseTriggerPoint(a, b) {\n    return b.triggerPoint - a.triggerPoint\n  }\n\n  var groups = {\n    vertical: {},\n    horizontal: {}\n  }\n  var Waypoint = window.Waypoint\n\n  /* http://imakewebthings.com/waypoints/api/group */\n  function Group(options) {\n    this.name = options.name\n    this.axis = options.axis\n    this.id = this.name + '-' + this.axis\n    this.waypoints = []\n    this.clearTriggerQueues()\n    groups[this.axis][this.name] = this\n  }\n\n  /* Private */\n  Group.prototype.add = function(waypoint) {\n    this.waypoints.push(waypoint)\n  }\n\n  /* Private */\n  Group.prototype.clearTriggerQueues = function() {\n    this.triggerQueues = {\n      up: [],\n      down: [],\n      left: [],\n      right: []\n    }\n  }\n\n  /* Private */\n  Group.prototype.flushTriggers = function() {\n    for (var direction in this.triggerQueues) {\n      var waypoints = this.triggerQueues[direction]\n      var reverse = direction === 'up' || direction === 'left'\n      waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)\n      for (var i = 0, end = waypoints.length; i < end; i += 1) {\n        var waypoint = waypoints[i]\n        if (waypoint.options.continuous || i === waypoints.length - 1) {\n          waypoint.trigger([direction])\n        }\n      }\n    }\n    this.clearTriggerQueues()\n  }\n\n  /* Private */\n  Group.prototype.next = function(waypoint) {\n    this.waypoints.sort(byTriggerPoint)\n    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)\n    var isLast = index === this.waypoints.length - 1\n    return isLast ? null : this.waypoints[index + 1]\n  }\n\n  /* Private */\n  Group.prototype.previous = function(waypoint) {\n    this.waypoints.sort(byTriggerPoint)\n    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)\n    return index ? this.waypoints[index - 1] : null\n  }\n\n  /* Private */\n  Group.prototype.queueTrigger = function(waypoint, direction) {\n    this.triggerQueues[direction].push(waypoint)\n  }\n\n  /* Private */\n  Group.prototype.remove = function(waypoint) {\n    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)\n    if (index > -1) {\n      this.waypoints.splice(index, 1)\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/first */\n  Group.prototype.first = function() {\n    return this.waypoints[0]\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/last */\n  Group.prototype.last = function() {\n    return this.waypoints[this.waypoints.length - 1]\n  }\n\n  /* Private */\n  Group.findOrCreate = function(options) {\n    return groups[options.axis][options.name] || new Group(options)\n  }\n\n  Waypoint.Group = Group\n}())\n;(function() {\n  'use strict'\n\n  var Waypoint = window.Waypoint\n\n  function isWindow(element) {\n    return element === element.window\n  }\n\n  function getWindow(element) {\n    if (isWindow(element)) {\n      return element\n    }\n    return element.defaultView\n  }\n\n  function NoFrameworkAdapter(element) {\n    this.element = element\n    this.handlers = {}\n  }\n\n  NoFrameworkAdapter.prototype.innerHeight = function() {\n    var isWin = isWindow(this.element)\n    return isWin ? this.element.innerHeight : this.element.clientHeight\n  }\n\n  NoFrameworkAdapter.prototype.innerWidth = function() {\n    var isWin = isWindow(this.element)\n    return isWin ? this.element.innerWidth : this.element.clientWidth\n  }\n\n  NoFrameworkAdapter.prototype.off = function(event, handler) {\n    function removeListeners(element, listeners, handler) {\n      for (var i = 0, end = listeners.length - 1; i < end; i++) {\n        var listener = listeners[i]\n        if (!handler || handler === listener) {\n          element.removeEventListener(listener)\n        }\n      }\n    }\n\n    var eventParts = event.split('.')\n    var eventType = eventParts[0]\n    var namespace = eventParts[1]\n    var element = this.element\n\n    if (namespace && this.handlers[namespace] && eventType) {\n      removeListeners(element, this.handlers[namespace][eventType], handler)\n      this.handlers[namespace][eventType] = []\n    }\n    else if (eventType) {\n      for (var ns in this.handlers) {\n        removeListeners(element, this.handlers[ns][eventType] || [], handler)\n        this.handlers[ns][eventType] = []\n      }\n    }\n    else if (namespace && this.handlers[namespace]) {\n      for (var type in this.handlers[namespace]) {\n        removeListeners(element, this.handlers[namespace][type], handler)\n      }\n      this.handlers[namespace] = {}\n    }\n  }\n\n  /* Adapted from jQuery 1.x offset() */\n  NoFrameworkAdapter.prototype.offset = function() {\n    if (!this.element.ownerDocument) {\n      return null\n    }\n\n    var documentElement = this.element.ownerDocument.documentElement\n    var win = getWindow(this.element.ownerDocument)\n    var rect = {\n      top: 0,\n      left: 0\n    }\n\n    if (this.element.getBoundingClientRect) {\n      rect = this.element.getBoundingClientRect()\n    }\n\n    return {\n      top: rect.top + win.pageYOffset - documentElement.clientTop,\n      left: rect.left + win.pageXOffset - documentElement.clientLeft\n    }\n  }\n\n  NoFrameworkAdapter.prototype.on = function(event, handler) {\n    var eventParts = event.split('.')\n    var eventType = eventParts[0]\n    var namespace = eventParts[1] || '__default'\n    var nsHandlers = this.handlers[namespace] = this.handlers[namespace] || {}\n    var nsTypeList = nsHandlers[eventType] = nsHandlers[eventType] || []\n\n    nsTypeList.push(handler)\n    this.element.addEventListener(eventType, handler)\n  }\n\n  NoFrameworkAdapter.prototype.outerHeight = function(includeMargin) {\n    var height = this.innerHeight()\n    var computedStyle\n\n    if (includeMargin && !isWindow(this.element)) {\n      computedStyle = window.getComputedStyle(this.element)\n      height += parseInt(computedStyle.marginTop, 10)\n      height += parseInt(computedStyle.marginBottom, 10)\n    }\n\n    return height\n  }\n\n  NoFrameworkAdapter.prototype.outerWidth = function(includeMargin) {\n    var width = this.innerWidth()\n    var computedStyle\n\n    if (includeMargin && !isWindow(this.element)) {\n      computedStyle = window.getComputedStyle(this.element)\n      width += parseInt(computedStyle.marginLeft, 10)\n      width += parseInt(computedStyle.marginRight, 10)\n    }\n\n    return width\n  }\n\n  NoFrameworkAdapter.prototype.scrollLeft = function() {\n    var win = getWindow(this.element)\n    return win ? win.pageXOffset : this.element.scrollLeft\n  }\n\n  NoFrameworkAdapter.prototype.scrollTop = function() {\n    var win = getWindow(this.element)\n    return win ? win.pageYOffset : this.element.scrollTop\n  }\n\n  NoFrameworkAdapter.extend = function() {\n    var args = Array.prototype.slice.call(arguments)\n\n    function merge(target, obj) {\n      if (typeof target === 'object' && typeof obj === 'object') {\n        for (var key in obj) {\n          if (obj.hasOwnProperty(key)) {\n            target[key] = obj[key]\n          }\n        }\n      }\n\n      return target\n    }\n\n    for (var i = 1, end = args.length; i < end; i++) {\n      merge(args[0], args[i])\n    }\n    return args[0]\n  }\n\n  NoFrameworkAdapter.inArray = function(element, array, i) {\n    return array == null ? -1 : array.indexOf(element, i)\n  }\n\n  NoFrameworkAdapter.isEmptyObject = function(obj) {\n    /* eslint no-unused-vars: 0 */\n    for (var name in obj) {\n      return false\n    }\n    return true\n  }\n\n  Waypoint.adapters.push({\n    name: 'noframework',\n    Adapter: NoFrameworkAdapter\n  })\n  Waypoint.Adapter = NoFrameworkAdapter\n}())\n;"
  },
  {
    "path": "static/assets/plugins/waypoints/lib/shortcuts/infinite.js",
    "content": "/*!\nWaypoints Infinite Scroll Shortcut - 3.1.1\nCopyright © 2011-2015 Caleb Troughton\nLicensed under the MIT license.\nhttps://github.com/imakewebthings/waypoints/blog/master/licenses.txt\n*/\n(function() {\n  'use strict'\n\n  var $ = window.jQuery\n  var Waypoint = window.Waypoint\n\n  /* http://imakewebthings.com/waypoints/shortcuts/infinite-scroll */\n  function Infinite(options) {\n    this.options = $.extend({}, Infinite.defaults, options)\n    this.container = this.options.element\n    if (this.options.container !== 'auto') {\n      this.container = this.options.container\n    }\n    this.$container = $(this.container)\n    this.$more = $(this.options.more)\n\n    if (this.$more.length) {\n      this.setupHandler()\n      this.waypoint = new Waypoint(this.options)\n    }\n  }\n\n  /* Private */\n  Infinite.prototype.setupHandler = function() {\n    this.options.handler = $.proxy(function() {\n      this.options.onBeforePageLoad()\n      this.destroy()\n      this.$container.addClass(this.options.loadingClass)\n\n      $.get($(this.options.more).attr('href'), $.proxy(function(data) {\n        var $data = $($.parseHTML(data))\n        var $newMore = $data.find(this.options.more)\n\n        var $items = $data.find(this.options.items)\n        if (!$items.length) {\n          $items = $data.filter(this.options.items)\n        }\n\n        this.$container.append($items)\n        this.$container.removeClass(this.options.loadingClass)\n\n        if (!$newMore.length) {\n          $newMore = $data.filter(this.options.more)\n        }\n        if ($newMore.length) {\n          this.$more.replaceWith($newMore)\n          this.$more = $newMore\n          this.waypoint = new Waypoint(this.options)\n        }\n        else {\n          this.$more.remove()\n        }\n\n        this.options.onAfterPageLoad()\n      }, this))\n    }, this)\n  }\n\n  /* Public */\n  Infinite.prototype.destroy = function() {\n    if (this.waypoint) {\n      this.waypoint.destroy()\n    }\n  }\n\n  Infinite.defaults = {\n    container: 'auto',\n    items: '.infinite-item',\n    more: '.infinite-more-link',\n    offset: 'bottom-in-view',\n    loadingClass: 'infinite-loading',\n    onBeforePageLoad: $.noop,\n    onAfterPageLoad: $.noop\n  }\n\n  Waypoint.Infinite = Infinite\n}())\n;"
  },
  {
    "path": "static/assets/plugins/waypoints/lib/shortcuts/inview.js",
    "content": "/*!\nWaypoints Inview Shortcut - 3.1.1\nCopyright © 2011-2015 Caleb Troughton\nLicensed under the MIT license.\nhttps://github.com/imakewebthings/waypoints/blog/master/licenses.txt\n*/\n(function() {\n  'use strict'\n\n  function noop() {}\n\n  var Waypoint = window.Waypoint\n\n  /* http://imakewebthings.com/waypoints/shortcuts/inview */\n  function Inview(options) {\n    this.options = Waypoint.Adapter.extend({}, Inview.defaults, options)\n    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'\n    this.waypoints = []\n    this.createWaypoints()\n  }\n\n  /* Private */\n  Inview.prototype.createWaypoints = function() {\n    var configs = {\n      vertical: [{\n        down: 'enter',\n        up: 'exited',\n        offset: '100%'\n      }, {\n        down: 'entered',\n        up: 'exit',\n        offset: 'bottom-in-view'\n      }, {\n        down: 'exit',\n        up: 'entered',\n        offset: 0\n      }, {\n        down: 'exited',\n        up: 'enter',\n        offset: function() {\n          return -this.adapter.outerHeight()\n        }\n      }],\n      horizontal: [{\n        right: 'enter',\n        left: 'exited',\n        offset: '100%'\n      }, {\n        right: 'entered',\n        left: 'exit',\n        offset: 'right-in-view'\n      }, {\n        right: 'exit',\n        left: 'entered',\n        offset: 0\n      }, {\n        right: 'exited',\n        left: 'enter',\n        offset: function() {\n          return -this.adapter.outerWidth()\n        }\n      }]\n    }\n\n    for (var i = 0, end = configs[this.axis].length; i < end; i++) {\n      var config = configs[this.axis][i]\n      this.createWaypoint(config)\n    }\n  }\n\n  /* Private */\n  Inview.prototype.createWaypoint = function(config) {\n    var self = this\n    this.waypoints.push(new Waypoint({\n      element: this.options.element,\n      handler: (function(config) {\n        return function(direction) {\n          self.options[config[direction]].call(this, direction)\n        }\n      }(config)),\n      offset: config.offset,\n      horizontal: this.options.horizontal\n    }))\n  }\n\n  /* Public */\n  Inview.prototype.destroy = function() {\n    for (var i = 0, end = this.waypoints.length; i < end; i++) {\n      this.waypoints[i].destroy()\n    }\n    this.waypoints = []\n  }\n\n  Inview.defaults = {\n    enter: noop,\n    entered: noop,\n    exit: noop,\n    exited: noop\n  }\n\n  Waypoint.Inview = Inview\n}())\n;"
  },
  {
    "path": "static/assets/plugins/waypoints/lib/shortcuts/sticky.js",
    "content": "/*!\nWaypoints Sticky Element Shortcut - 3.1.1\nCopyright © 2011-2015 Caleb Troughton\nLicensed under the MIT license.\nhttps://github.com/imakewebthings/waypoints/blog/master/licenses.txt\n*/\n(function() {\n  'use strict'\n\n  var $ = window.jQuery\n  var Waypoint = window.Waypoint\n\n  /* http://imakewebthings.com/waypoints/shortcuts/sticky-elements */\n  function Sticky(options) {\n    this.options = $.extend({}, Waypoint.defaults, Sticky.defaults, options)\n    this.element = this.options.element\n    this.$element = $(this.element)\n    this.createWrapper()\n    this.createWaypoint()\n  }\n\n  /* Private */\n  Sticky.prototype.createWaypoint = function() {\n    var originalHandler = this.options.handler\n\n    this.waypoint = new Waypoint($.extend({}, this.options, {\n      element: this.wrapper,\n      handler: $.proxy(function(direction) {\n        var shouldBeStuck = this.options.direction.indexOf(direction) > -1\n        var wrapperHeight = shouldBeStuck ? this.$element.outerHeight(true) : ''\n\n        this.$wrapper.height(wrapperHeight)\n        this.$element.toggleClass(this.options.stuckClass, shouldBeStuck)\n\n        if (originalHandler) {\n          originalHandler.call(this, direction)\n        }\n      }, this)\n    }))\n  }\n\n  /* Private */\n  Sticky.prototype.createWrapper = function() {\n    this.$element.wrap(this.options.wrapper)\n    this.$wrapper = this.$element.parent()\n    this.wrapper = this.$wrapper[0]\n  }\n\n  /* Public */\n  Sticky.prototype.destroy = function() {\n    if (this.$element.parent()[0] === this.wrapper) {\n      this.waypoint.destroy()\n      this.$element.removeClass(this.options.stuckClass).unwrap()\n    }\n  }\n\n  Sticky.defaults = {\n    wrapper: '<div class=\"sticky-wrapper\" />',\n    stuckClass: 'stuck',\n    direction: 'down right'\n  }\n\n  Waypoint.Sticky = Sticky\n}())\n;"
  },
  {
    "path": "static/assets/plugins/waypoints/lib/waypoints.debug.js",
    "content": "/*!\nWaypoints Debug - 3.1.1\nCopyright © 2011-2015 Caleb Troughton\nLicensed under the MIT license.\nhttps://github.com/imakewebthings/waypoints/blog/master/licenses.txt\n*/\n(function() {\n  'use strict'\n\n  var displayNoneMessage = [\n    'You have a Waypoint element with display none. For more information on ',\n    'why this is a bad idea read ',\n    'http://imakewebthings.com/waypoints/guides/debugging/#display-none'\n  ].join('')\n  var fixedMessage = [\n    'You have a Waypoint element with fixed positioning. For more ',\n    'information on why this is a bad idea read ',\n    'http://imakewebthings.com/waypoints/guides/debugging/#fixed-position'\n  ].join('')\n\n  function checkWaypointStyles() {\n    var originalRefresh = window.Waypoint.Context.prototype.refresh\n\n    window.Waypoint.Context.prototype.refresh = function() {\n      for (var axis in this.waypoints) {\n        for (var key in this.waypoints[axis]) {\n          var waypoint = this.waypoints[axis][key]\n          var style = window.getComputedStyle(waypoint.element)\n          if (!waypoint.enabled) {\n            continue\n          }\n          if (style && style.display === 'none') {\n            console.error(displayNoneMessage)\n          }\n          if (style && style.position === 'fixed') {\n            console.error(fixedMessage)\n          }\n        }\n      }\n      return originalRefresh.call(this)\n    }\n  }\n\n  checkWaypointStyles()\n}())\n;"
  },
  {
    "path": "static/assets/plugins/waypoints/lib/zepto.waypoints.js",
    "content": "/*!\nWaypoints - 3.1.1\nCopyright © 2011-2015 Caleb Troughton\nLicensed under the MIT license.\nhttps://github.com/imakewebthings/waypoints/blog/master/licenses.txt\n*/\n(function() {\n  'use strict'\n\n  var keyCounter = 0\n  var allWaypoints = {}\n\n  /* http://imakewebthings.com/waypoints/api/waypoint */\n  function Waypoint(options) {\n    if (!options) {\n      throw new Error('No options passed to Waypoint constructor')\n    }\n    if (!options.element) {\n      throw new Error('No element option passed to Waypoint constructor')\n    }\n    if (!options.handler) {\n      throw new Error('No handler option passed to Waypoint constructor')\n    }\n\n    this.key = 'waypoint-' + keyCounter\n    this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)\n    this.element = this.options.element\n    this.adapter = new Waypoint.Adapter(this.element)\n    this.callback = options.handler\n    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'\n    this.enabled = this.options.enabled\n    this.triggerPoint = null\n    this.group = Waypoint.Group.findOrCreate({\n      name: this.options.group,\n      axis: this.axis\n    })\n    this.context = Waypoint.Context.findOrCreateByElement(this.options.context)\n\n    if (Waypoint.offsetAliases[this.options.offset]) {\n      this.options.offset = Waypoint.offsetAliases[this.options.offset]\n    }\n    this.group.add(this)\n    this.context.add(this)\n    allWaypoints[this.key] = this\n    keyCounter += 1\n  }\n\n  /* Private */\n  Waypoint.prototype.queueTrigger = function(direction) {\n    this.group.queueTrigger(this, direction)\n  }\n\n  /* Private */\n  Waypoint.prototype.trigger = function(args) {\n    if (!this.enabled) {\n      return\n    }\n    if (this.callback) {\n      this.callback.apply(this, args)\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/destroy */\n  Waypoint.prototype.destroy = function() {\n    this.context.remove(this)\n    this.group.remove(this)\n    delete allWaypoints[this.key]\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/disable */\n  Waypoint.prototype.disable = function() {\n    this.enabled = false\n    return this\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/enable */\n  Waypoint.prototype.enable = function() {\n    this.context.refresh()\n    this.enabled = true\n    return this\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/next */\n  Waypoint.prototype.next = function() {\n    return this.group.next(this)\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/previous */\n  Waypoint.prototype.previous = function() {\n    return this.group.previous(this)\n  }\n\n  /* Private */\n  Waypoint.invokeAll = function(method) {\n    var allWaypointsArray = []\n    for (var waypointKey in allWaypoints) {\n      allWaypointsArray.push(allWaypoints[waypointKey])\n    }\n    for (var i = 0, end = allWaypointsArray.length; i < end; i++) {\n      allWaypointsArray[i][method]()\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/destroy-all */\n  Waypoint.destroyAll = function() {\n    Waypoint.invokeAll('destroy')\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/disable-all */\n  Waypoint.disableAll = function() {\n    Waypoint.invokeAll('disable')\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/enable-all */\n  Waypoint.enableAll = function() {\n    Waypoint.invokeAll('enable')\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/refresh-all */\n  Waypoint.refreshAll = function() {\n    Waypoint.Context.refreshAll()\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/viewport-height */\n  Waypoint.viewportHeight = function() {\n    return window.innerHeight || document.documentElement.clientHeight\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/viewport-width */\n  Waypoint.viewportWidth = function() {\n    return document.documentElement.clientWidth\n  }\n\n  Waypoint.adapters = []\n\n  Waypoint.defaults = {\n    context: window,\n    continuous: true,\n    enabled: true,\n    group: 'default',\n    horizontal: false,\n    offset: 0\n  }\n\n  Waypoint.offsetAliases = {\n    'bottom-in-view': function() {\n      return this.context.innerHeight() - this.adapter.outerHeight()\n    },\n    'right-in-view': function() {\n      return this.context.innerWidth() - this.adapter.outerWidth()\n    }\n  }\n\n  window.Waypoint = Waypoint\n}())\n;(function() {\n  'use strict'\n\n  function requestAnimationFrameShim(callback) {\n    window.setTimeout(callback, 1000 / 60)\n  }\n\n  var keyCounter = 0\n  var contexts = {}\n  var Waypoint = window.Waypoint\n  var oldWindowLoad = window.onload\n\n  /* http://imakewebthings.com/waypoints/api/context */\n  function Context(element) {\n    this.element = element\n    this.Adapter = Waypoint.Adapter\n    this.adapter = new this.Adapter(element)\n    this.key = 'waypoint-context-' + keyCounter\n    this.didScroll = false\n    this.didResize = false\n    this.oldScroll = {\n      x: this.adapter.scrollLeft(),\n      y: this.adapter.scrollTop()\n    }\n    this.waypoints = {\n      vertical: {},\n      horizontal: {}\n    }\n\n    element.waypointContextKey = this.key\n    contexts[element.waypointContextKey] = this\n    keyCounter += 1\n\n    this.createThrottledScrollHandler()\n    this.createThrottledResizeHandler()\n  }\n\n  /* Private */\n  Context.prototype.add = function(waypoint) {\n    var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'\n    this.waypoints[axis][waypoint.key] = waypoint\n    this.refresh()\n  }\n\n  /* Private */\n  Context.prototype.checkEmpty = function() {\n    var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)\n    var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)\n    if (horizontalEmpty && verticalEmpty) {\n      this.adapter.off('.waypoints')\n      delete contexts[this.key]\n    }\n  }\n\n  /* Private */\n  Context.prototype.createThrottledResizeHandler = function() {\n    var self = this\n\n    function resizeHandler() {\n      self.handleResize()\n      self.didResize = false\n    }\n\n    this.adapter.on('resize.waypoints', function() {\n      if (!self.didResize) {\n        self.didResize = true\n        Waypoint.requestAnimationFrame(resizeHandler)\n      }\n    })\n  }\n\n  /* Private */\n  Context.prototype.createThrottledScrollHandler = function() {\n    var self = this\n    function scrollHandler() {\n      self.handleScroll()\n      self.didScroll = false\n    }\n\n    this.adapter.on('scroll.waypoints', function() {\n      if (!self.didScroll || Waypoint.isTouch) {\n        self.didScroll = true\n        Waypoint.requestAnimationFrame(scrollHandler)\n      }\n    })\n  }\n\n  /* Private */\n  Context.prototype.handleResize = function() {\n    Waypoint.Context.refreshAll()\n  }\n\n  /* Private */\n  Context.prototype.handleScroll = function() {\n    var triggeredGroups = {}\n    var axes = {\n      horizontal: {\n        newScroll: this.adapter.scrollLeft(),\n        oldScroll: this.oldScroll.x,\n        forward: 'right',\n        backward: 'left'\n      },\n      vertical: {\n        newScroll: this.adapter.scrollTop(),\n        oldScroll: this.oldScroll.y,\n        forward: 'down',\n        backward: 'up'\n      }\n    }\n\n    for (var axisKey in axes) {\n      var axis = axes[axisKey]\n      var isForward = axis.newScroll > axis.oldScroll\n      var direction = isForward ? axis.forward : axis.backward\n\n      for (var waypointKey in this.waypoints[axisKey]) {\n        var waypoint = this.waypoints[axisKey][waypointKey]\n        var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint\n        var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint\n        var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint\n        var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint\n        if (crossedForward || crossedBackward) {\n          waypoint.queueTrigger(direction)\n          triggeredGroups[waypoint.group.id] = waypoint.group\n        }\n      }\n    }\n\n    for (var groupKey in triggeredGroups) {\n      triggeredGroups[groupKey].flushTriggers()\n    }\n\n    this.oldScroll = {\n      x: axes.horizontal.newScroll,\n      y: axes.vertical.newScroll\n    }\n  }\n\n  /* Private */\n  Context.prototype.innerHeight = function() {\n    /*eslint-disable eqeqeq */\n    if (this.element == this.element.window) {\n      return Waypoint.viewportHeight()\n    }\n    /*eslint-enable eqeqeq */\n    return this.adapter.innerHeight()\n  }\n\n  /* Private */\n  Context.prototype.remove = function(waypoint) {\n    delete this.waypoints[waypoint.axis][waypoint.key]\n    this.checkEmpty()\n  }\n\n  /* Private */\n  Context.prototype.innerWidth = function() {\n    /*eslint-disable eqeqeq */\n    if (this.element == this.element.window) {\n      return Waypoint.viewportWidth()\n    }\n    /*eslint-enable eqeqeq */\n    return this.adapter.innerWidth()\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/context-destroy */\n  Context.prototype.destroy = function() {\n    var allWaypoints = []\n    for (var axis in this.waypoints) {\n      for (var waypointKey in this.waypoints[axis]) {\n        allWaypoints.push(this.waypoints[axis][waypointKey])\n      }\n    }\n    for (var i = 0, end = allWaypoints.length; i < end; i++) {\n      allWaypoints[i].destroy()\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/context-refresh */\n  Context.prototype.refresh = function() {\n    /*eslint-disable eqeqeq */\n    var isWindow = this.element == this.element.window\n    /*eslint-enable eqeqeq */\n    var contextOffset = this.adapter.offset()\n    var triggeredGroups = {}\n    var axes\n\n    this.handleScroll()\n    axes = {\n      horizontal: {\n        contextOffset: isWindow ? 0 : contextOffset.left,\n        contextScroll: isWindow ? 0 : this.oldScroll.x,\n        contextDimension: this.innerWidth(),\n        oldScroll: this.oldScroll.x,\n        forward: 'right',\n        backward: 'left',\n        offsetProp: 'left'\n      },\n      vertical: {\n        contextOffset: isWindow ? 0 : contextOffset.top,\n        contextScroll: isWindow ? 0 : this.oldScroll.y,\n        contextDimension: this.innerHeight(),\n        oldScroll: this.oldScroll.y,\n        forward: 'down',\n        backward: 'up',\n        offsetProp: 'top'\n      }\n    }\n\n    for (var axisKey in axes) {\n      var axis = axes[axisKey]\n      for (var waypointKey in this.waypoints[axisKey]) {\n        var waypoint = this.waypoints[axisKey][waypointKey]\n        var adjustment = waypoint.options.offset\n        var oldTriggerPoint = waypoint.triggerPoint\n        var elementOffset = 0\n        var freshWaypoint = oldTriggerPoint == null\n        var contextModifier, wasBeforeScroll, nowAfterScroll\n        var triggeredBackward, triggeredForward\n\n        if (waypoint.element !== waypoint.element.window) {\n          elementOffset = waypoint.adapter.offset()[axis.offsetProp]\n        }\n\n        if (typeof adjustment === 'function') {\n          adjustment = adjustment.apply(waypoint)\n        }\n        else if (typeof adjustment === 'string') {\n          adjustment = parseFloat(adjustment)\n          if (waypoint.options.offset.indexOf('%') > - 1) {\n            adjustment = Math.ceil(axis.contextDimension * adjustment / 100)\n          }\n        }\n\n        contextModifier = axis.contextScroll - axis.contextOffset\n        waypoint.triggerPoint = elementOffset + contextModifier - adjustment\n        wasBeforeScroll = oldTriggerPoint < axis.oldScroll\n        nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll\n        triggeredBackward = wasBeforeScroll && nowAfterScroll\n        triggeredForward = !wasBeforeScroll && !nowAfterScroll\n\n        if (!freshWaypoint && triggeredBackward) {\n          waypoint.queueTrigger(axis.backward)\n          triggeredGroups[waypoint.group.id] = waypoint.group\n        }\n        else if (!freshWaypoint && triggeredForward) {\n          waypoint.queueTrigger(axis.forward)\n          triggeredGroups[waypoint.group.id] = waypoint.group\n        }\n        else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {\n          waypoint.queueTrigger(axis.forward)\n          triggeredGroups[waypoint.group.id] = waypoint.group\n        }\n      }\n    }\n\n    for (var groupKey in triggeredGroups) {\n      triggeredGroups[groupKey].flushTriggers()\n    }\n\n    return this\n  }\n\n  /* Private */\n  Context.findOrCreateByElement = function(element) {\n    return Context.findByElement(element) || new Context(element)\n  }\n\n  /* Private */\n  Context.refreshAll = function() {\n    for (var contextId in contexts) {\n      contexts[contextId].refresh()\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/context-find-by-element */\n  Context.findByElement = function(element) {\n    return contexts[element.waypointContextKey]\n  }\n\n  window.onload = function() {\n    if (oldWindowLoad) {\n      oldWindowLoad()\n    }\n    Context.refreshAll()\n  }\n\n  Waypoint.requestAnimationFrame = function(callback) {\n    var requestFn = window.requestAnimationFrame ||\n      window.mozRequestAnimationFrame ||\n      window.webkitRequestAnimationFrame ||\n      requestAnimationFrameShim\n    requestFn.call(window, callback)\n  }\n  Waypoint.Context = Context\n}())\n;(function() {\n  'use strict'\n\n  function byTriggerPoint(a, b) {\n    return a.triggerPoint - b.triggerPoint\n  }\n\n  function byReverseTriggerPoint(a, b) {\n    return b.triggerPoint - a.triggerPoint\n  }\n\n  var groups = {\n    vertical: {},\n    horizontal: {}\n  }\n  var Waypoint = window.Waypoint\n\n  /* http://imakewebthings.com/waypoints/api/group */\n  function Group(options) {\n    this.name = options.name\n    this.axis = options.axis\n    this.id = this.name + '-' + this.axis\n    this.waypoints = []\n    this.clearTriggerQueues()\n    groups[this.axis][this.name] = this\n  }\n\n  /* Private */\n  Group.prototype.add = function(waypoint) {\n    this.waypoints.push(waypoint)\n  }\n\n  /* Private */\n  Group.prototype.clearTriggerQueues = function() {\n    this.triggerQueues = {\n      up: [],\n      down: [],\n      left: [],\n      right: []\n    }\n  }\n\n  /* Private */\n  Group.prototype.flushTriggers = function() {\n    for (var direction in this.triggerQueues) {\n      var waypoints = this.triggerQueues[direction]\n      var reverse = direction === 'up' || direction === 'left'\n      waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)\n      for (var i = 0, end = waypoints.length; i < end; i += 1) {\n        var waypoint = waypoints[i]\n        if (waypoint.options.continuous || i === waypoints.length - 1) {\n          waypoint.trigger([direction])\n        }\n      }\n    }\n    this.clearTriggerQueues()\n  }\n\n  /* Private */\n  Group.prototype.next = function(waypoint) {\n    this.waypoints.sort(byTriggerPoint)\n    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)\n    var isLast = index === this.waypoints.length - 1\n    return isLast ? null : this.waypoints[index + 1]\n  }\n\n  /* Private */\n  Group.prototype.previous = function(waypoint) {\n    this.waypoints.sort(byTriggerPoint)\n    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)\n    return index ? this.waypoints[index - 1] : null\n  }\n\n  /* Private */\n  Group.prototype.queueTrigger = function(waypoint, direction) {\n    this.triggerQueues[direction].push(waypoint)\n  }\n\n  /* Private */\n  Group.prototype.remove = function(waypoint) {\n    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)\n    if (index > -1) {\n      this.waypoints.splice(index, 1)\n    }\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/first */\n  Group.prototype.first = function() {\n    return this.waypoints[0]\n  }\n\n  /* Public */\n  /* http://imakewebthings.com/waypoints/api/last */\n  Group.prototype.last = function() {\n    return this.waypoints[this.waypoints.length - 1]\n  }\n\n  /* Private */\n  Group.findOrCreate = function(options) {\n    return groups[options.axis][options.name] || new Group(options)\n  }\n\n  Waypoint.Group = Group\n}())\n;(function() {\n  'use strict'\n\n  var $ = window.Zepto\n  var Waypoint = window.Waypoint\n\n  function ZeptoAdapter(element) {\n    this.element = element\n    this.$element = $(element)\n  }\n\n  $.each([\n    'off',\n    'on',\n    'scrollLeft',\n    'scrollTop'\n  ], function(i, method) {\n    ZeptoAdapter.prototype[method] = function() {\n      var args = Array.prototype.slice.call(arguments)\n      return this.$element[method].apply(this.$element, args)\n    }\n  })\n\n  ZeptoAdapter.prototype.offset = function() {\n    if (this.element !== this.element.window) {\n      return this.$element.offset()\n    }\n  }\n\n  // Adapted from https://gist.github.com/wheresrhys/5823198\n  $.each([\n    'width',\n    'height'\n  ], function(i, dimension) {\n    function createDimensionMethod($element, includeBorder) {\n      return function(includeMargin) {\n        var $element = this.$element\n        var size = $element[dimension]()\n        var sides = {\n          width: ['left', 'right'],\n          height: ['top', 'bottom']\n        }\n\n        $.each(sides[dimension], function(i, side) {\n          size += parseInt($element.css('padding-' + side), 10)\n          if (includeBorder) {\n            size += parseInt($element.css('border-' + side + '-width'), 10)\n          }\n          if (includeMargin) {\n            size += parseInt($element.css('margin-' + side), 10)\n          }\n        })\n        return size\n      }\n    }\n\n    var innerMethod = $.camelCase('inner-' + dimension)\n    var outerMethod = $.camelCase('outer-' + dimension)\n\n    ZeptoAdapter.prototype[innerMethod] = createDimensionMethod(false)\n    ZeptoAdapter.prototype[outerMethod] = createDimensionMethod(true)\n  })\n\n  $.each([\n    'extend',\n    'inArray'\n  ], function(i, method) {\n    ZeptoAdapter[method] = $[method]\n  })\n\n  ZeptoAdapter.isEmptyObject = function(obj) {\n    /* eslint no-unused-vars: 0 */\n    for (var name in obj) {\n      return false\n    }\n    return true\n  }\n\n  Waypoint.adapters.push({\n    name: 'zepto',\n    Adapter: ZeptoAdapter\n  })\n  Waypoint.Adapter = ZeptoAdapter\n}())\n;(function() {\n  'use strict'\n\n  var Waypoint = window.Waypoint\n\n  function createExtension(framework) {\n    return function() {\n      var waypoints = []\n      var overrides = arguments[0]\n\n      if (framework.isFunction(arguments[0])) {\n        overrides = framework.extend({}, arguments[1])\n        overrides.handler = arguments[0]\n      }\n\n      this.each(function() {\n        var options = framework.extend({}, overrides, {\n          element: this\n        })\n        if (typeof options.context === 'string') {\n          options.context = framework(this).closest(options.context)[0]\n        }\n        waypoints.push(new Waypoint(options))\n      })\n\n      return waypoints\n    }\n  }\n\n  if (window.jQuery) {\n    window.jQuery.fn.waypoint = createExtension(window.jQuery)\n  }\n  if (window.Zepto) {\n    window.Zepto.fn.waypoint = createExtension(window.Zepto)\n  }\n}())\n;"
  },
  {
    "path": "supervisord.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; Notes:\n;  - Shell expansion (\"~\" or \"$HOME\") is not supported.  Environment\n;    variables can be expanded using this syntax: \"%(ENV_HOME)s\".\n;  - Comments must have a leading space: \"a=b ;comment\" not \"a=b;comment\".\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;startsecs=1                   ; # of secs prog must stay up to be running (def. 1)\n;startretries=3                ; max # of serial start failures when starting (default 3)\n;autorestart=unexpected        ; when to restart if exited after running (def: unexpected)\n;exitcodes=0,2                 ; 'expected' exit codes used with autorestart (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;startsecs=1                   ; # of secs prog must stay up to be running (def. 1)\n;startretries=3                ; max # of serial start failures when starting (default 3)\n;autorestart=unexpected        ; autorestart if exited after running (def: unexpected)\n;exitcodes=0,2                 ; 'expected' exit codes used with autorestart (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=false         ; redirect_stderr=true is not allowed for eventlisteners\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=10     ; # 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[program:devops]\ncommand=uwsgi --ini /data/SimpletourDevops/uwsgi.ini\nstopsignal=QUIT\nautostart=true\nautorestart=true\nstdout_logfile=/data/SimpletourDevops/uwsgi_devops.log\nredirect_stderr=true\n\n[program:websocket]\ncommand=python run_eventlet.py\ndirectory=/data/SimpletourDevops\nstopsignal=QUIT\nautostart=true\nautorestart=true\nstdout_logfile=/data/SimpletourDevops/uwsgi_websocket.log\nredirect_stderr=true\n\n[program:celery]\ncommand=celery -A webapp.tasks worker   --loglevel=info\ndirectory=/data/SimpletourDevops\nstdout_logfile=/data/SimpletourDevops/celery.log\nredirect_stderr=true\nstopsignal=QUIT\nautostart=true\nautorestart=true\nuser=www\n\n\n\n[program:celerybeat]\ncommand=celery -A webapp.tasks beat --loglevel=info --pidfile=/tmp/celerybeat.pid  -s /tmp/celerybeat-schedule \ndirectory=/data/SimpletourDevops\nstdout_logfile=/tmp/celery_beat.log\nredirect_stderr=true\nstopsignal=QUIT\nautostart=true\nautorestart=true\nuser=www\n"
  },
  {
    "path": "templates/403.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"utf-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n        <meta name=\"description\" content=\"A fully featured admin theme which can be used to build CRM, CMS, etc.\">\n        <meta name=\"author\" content=\"www.divmb.com\">\n        <link rel=\"shortcut icon\" href=\"/static/assets/images/favicon_1.ico\">\n        <title>SimpletourDevops</title>\n        <link href=\"/static/assets/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/core.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/components.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/icons.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/pages.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/responsive.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <script src=\"/static/assets/js/modernizr.min.js\"></script>\n        \n    </head>\n    <body>\n    \t\n    \t<div class=\"account-pages\"></div>\n\t\t<div class=\"clearfix\"></div>\n\t\t\n        <div class=\"wrapper-page\">\n            <div class=\"ex-page-content text-center\">\n                <div class=\"text-error\"><span class=\"text-primary\">4</span><i class=\"ti-face-sad text-pink\"></i><span class=\"text-info\">3</span></div>\n                <h2>Forbidden</h2><br>\n                <p class=\"text-muted\">Sorry,您没有权限访问，请联系管理员！！谢谢</p>\n                <br>\n                <a class=\"btn btn-default waves-effect waves-light\" href=\"/\"> 返回首页</a>\n                \n            </div>\n        </div>\n\n    \t<script>\n            var resizefunc = [];\n        </script>\n\n        <!-- jQuery  -->\n        <script src=\"/static/assets/js/jquery.min.js\"></script>\n        <script src=\"/static/assets/js/bootstrap.min.js\"></script>\n        <script src=\"/static/assets/js/detect.js\"></script>\n        <script src=\"/static/assets/js/fastclick.js\"></script>\n        <script src=\"/static/ass/static/ets/js/jquery.slimscroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.blockUI.js\"></script>\n        <script src=\"/static/assets/js/waves.js\"></script>\n        <script src=\"/static/assets/js/wow.min.js\"></script>\n        <script src=\"/static/assets/js/jquery.nicescroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.scrollTo.min.js\"></script>\n        <script src=\"/static/assets/js/jquery.core.js\"></script>\n        <script src=\"/static/assets/js/jquery.app.js\"></script>\n\t\n\t</body>\n</html>"
  },
  {
    "path": "templates/404.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"utf-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n        <meta name=\"description\" content=\"A fully featured admin theme which can be used to build CRM, CMS, etc.\">\n        <meta name=\"author\" content=\"www.divmb.com\">\n\n        <link rel=\"shortcut icon\" href=\"/static/assets/images/favicon_1.ico\">\n\n        <title>SimpletourDevops</title>\n\n        <link href=\"/static/assets/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/core.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/components.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/icons.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/pages.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/responsive.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n        <script src=\"/static/assets/js/modernizr.min.js\"></script>\n        \n    </head>\n    <body>\n    \t\n    \t<div class=\"account-pages\"></div>\n\t\t<div class=\"clearfix\"></div>\n\t\t\n        <div class=\"wrapper-page\">\n            <div class=\"ex-page-content text-center\">\n                <div class=\"text-error\"><span class=\"text-primary\">4</span><i class=\"ti-face-sad text-pink\"></i><span class=\"text-info\">4</span></div>\n                <h2>Page not found</h2><br>\n                <p class=\"text-muted\">Sorry,该页面被管理员吃了！！！</p>\n                <p class=\"text-muted\">你不管嘛</p>\n                <br>\n                <a class=\"btn btn-default waves-effect waves-light\" href=\"/\"> 返回首页</a>\n            </div>\n        </div>\n\n        \n    \t<script>\n            var resizefunc = [];\n        </script>\n\n        <!-- jQuery  -->\n        <script src=\"/static/assets/js/jquery.min.js\"></script>\n        <script src=\"/static/assets/js/bootstrap.min.js\"></script>\n        <script src=\"/static/assets/js/detect.js\"></script>\n        <script src=\"/static/assets/js/fastclick.js\"></script>\n        <script src=\"/static/assets/js/jquery.slimscroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.blockUI.js\"></script>\n        <script src=\"/static/assets/js/waves.js\"></script>\n        <script src=\"/static/assets/js/wow.min.js\"></script>\n        <script src=\"/static/assets/js/jquery.nicescroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.scrollTo.min.js\"></script>\n\n\n        <script src=\"/static/assets/js/jquery.core.js\"></script>\n        <script src=\"/static/assets/js/jquery.app.js\"></script>\n\t</body>\n</html>"
  },
  {
    "path": "templates/500.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"utf-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n        <meta name=\"description\" content=\"A fully featured admin theme which can be used to build CRM, CMS, etc.\">\n        <meta name=\"author\" content=\"www.divmb.com\">\n\n        <link rel=\"shortcut icon\" href=\"/static/assets/images/favicon_1.ico\">\n\n        <title>SimpletourDevops</title>\n\n        <link href=\"/static/assets/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/core.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/components.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/icons.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/pages.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/responsive.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n        <script src=\"/static/assets/js/modernizr.min.js\"></script>\n        \n    </head>\n    <body>\n    \t\n    \t<div class=\"account-pages\"></div>\n\t\t<div class=\"clearfix\"></div>\n\t\t\n        <div class=\"wrapper-page\">\n            <div class=\"ex-page-content text-center\">\n                <div class=\"text-error\"><span class=\"text-primary\">5</span><i class=\"ti-face-sad text-pink\"></i><i class=\"ti-face-sad text-info\"></i></div>\n                <h2>Internal Server Error.</h2><br>\n                <p class=\"text-muted\">Sorry!!!服务器出现错误啦，快去找管理员 <a href=\"#\">support</a></p>\n                <br>\n                <a class=\"btn btn-default waves-effect waves-light\" href=\"/\"> Return Home</a>\n                \n            </div>\n        </div>\n\n        \n    \t<script>\n            var resizefunc = [];\n        </script>\n\n        <!-- jQuery  -->\n        <script src=\"/static/assets/js/jquery.min.js\"></script>\n        <script src=\"/static/assets/js/bootstrap.min.js\"></script>\n        <script src=\"/static/assets/js/detect.js\"></script>\n        <script src=\"/static/assets/js/fastclick.js\"></script>\n        <script src=\"/static/assets/js/jquery.slimscroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.blockUI.js\"></script>\n        <script src=\"/static/assets/js/waves.js\"></script>\n        <script src=\"/static/assets/js/wow.min.js\"></script>\n        <script src=\"/static/assets/js/jquery.nicescroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.scrollTo.min.js\"></script>\n        <script src=\"/static/assets/js/jquery.core.js\"></script>\n        <script src=\"/static/assets/js/jquery.app.js\"></script>\n\t</body>\n</html>"
  },
  {
    "path": "templates/base.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<meta name=\"description\" content=\"www.divmb.com creativity\">\n<meta name=\"author\" content=\"www.divmb.com\">\n<link rel=\"shortcut icon\" href=\"/static/assets/images/favicon_1.ico\">\n<title>SimpletourDevops</title>\n<!--Morris Chart CSS -->\n\n<link rel=\"stylesheet\" href=\"/static/assets/css/xterm.css\" />\n<link rel=\"stylesheet\" href=\"/static/assets/css/style.css\" />\n<script src=\"/static/assets/js/xterm.js\"></script>\n    <style>\n        #sidebar-menu ul ul a.hover {\n           color: #fff;\n            background-color: #5fbeaa;\n        }\n        #sidebar-menu ul ul a.hover:hover {\n           color: #fff;\n            background-color: #5fbeaa;\n        }\n    </style>\n{% include 'tempdir/head_css.html' %}\n\n{% include 'tempdir/head_script.html'%}\n\n</head>\n<body class=\"fixed-left\">\n\n<!-- Begin page -->\n<div id=\"wrapper\">\n  <!-- Top Bar Start -->\n  <div class=\"topbar\">\n    <!-- LOGO -->\n    <div class=\"topbar-left\">\n      <div class=\"text-center\"> <a href=\"/\" class=\"logo\"><i class=\"icon-magnet icon-c-logo\"></i><span>Simpletour运维系统</span></a> </div>\n    </div>\n    <!-- Button mobile view to collapse sidebar menu -->\n    <div class=\"navbar navbar-default\" role=\"navigation\">\n      <div class=\"container\">\n        <div class=\"\">\n          <div class=\"pull-left\">\n            <button class=\"button-menu-mobile open-left\"> <i class=\"ion-navicon\"></i> </button>\n            <span class=\"clearfix\"></span> </div>\n          <form role=\"search\" class=\"navbar-left app-search pull-left hidden-xs\">\n            <input type=\"text\" placeholder=\"搜索...\" class=\"form-control\">\n            <a href=\"\"><i class=\"fa fa-search\"></i></a>\n          </form>\n          <ul class=\"nav navbar-nav navbar-right pull-right\">\n            <li class=\"hidden-xs\"> <a href=\"#\" id=\"btn-fullscreen\" class=\"waves-effect waves-light\"><i class=\"icon-size-fullscreen\"></i></a> </li>\n            <li class=\"dropdown\"> <a href=\"\" class=\"dropdown-toggle profile\" data-toggle=\"dropdown\" aria-expanded=\"true\"><img src=\"/static/assets/images/users/avatar-1.jpg\" alt=\"user-img\" class=\"img-circle\"> </a>\n              <ul class=\"dropdown-menu\">\n                <li><a href=\"{% url 'Userinfo' %}\"><i class=\"ti-user m-r-5\"></i> 个人信息</a></li>\n                <li><a href=\"{% url 'SysrestUserpassword' usersession %}\"><i class=\"ti-settings m-r-5\"></i> 重置密码</a></li>\n                <li><a href=\"{% url 'Logout' %}\"><i class=\"ti-power-off m-r-5\"></i> 退出系统</a></li>\n              </ul>\n            </li>\n          </ul>\n        </div>\n        <!--/.nav-collapse -->\n      </div>\n    </div>  <!--首页导航菜单-->\n  </div>\n\n  <!-- ========== Left Sidebar Start ========== -->\n  <div class=\"left side-menu\">\n    <div class=\"sidebar-inner slimscrollleft\">\n      <!--- Divider -->\n      <div id=\"sidebar-menu\">\n        <ul>\n            {% if perms.webapp.system_index_view %}\n            <li> <a href=\"{% url 'index' %}\" class=\"waves-effect \"><i class=\"ti-home\"></i> <span> 系统首页 </span></a> </li>\n            {%endif%}\n            {% if perms.servermanager.assets_index_view %}\n                <li class=\"has_sub\" id=\"index\"> <a href=\"#\" class=\"waves-effect\"><i class=\"ti-menu\"></i> <span>资产管理</span> </a>\n                <ul class=\"list-unstyled\">\n                  <li><a href=\"{% url 'AssetsLists' 1  %}\">资产表管理</a></li>\n                  <li><a href=\"{% url 'ServerList' 1  %}\">服务器列表</a></li>\n                </ul>\n              </li>\n            {%endif%}\n            {%if perms.dockermanager.docker_index_view%}\n               <li class=\"has_sub\"> <a href=\"#\" class=\"waves-effect\"><i class=\"ti-server\"></i> <span> 容器管理 </span> </a>\n            <ul class=\"list-unstyled\">\n              <li><a href=\"{% url 'DockerHosts' %}\">主机列表</a></li>\n              <li><a href=\"{% url 'Dockercontainerlist' 1 %}\">容器列表</a></li>\n              <li><a href=\"{% url 'DockerImages' 1 %}\">镜像列表</a></li>\n            </ul>\n          </li>\n            {%endif%}\n\n          {%if perms.saltadmin.salt_index_view%}\n\n            <li class=\"has_sub\"> <a href=\"#\" class=\"waves-effect\"><i class=\"ti-pencil-alt\"></i><span> SALT管理 </span></a>\n              <ul class=\"list-unstyled\">\n                <li><a href=\"{% url 'SaltMasterList' %}\">Master管理</a></li>\n                <li><a href=\"{% url 'KeyList' %}\">keys管理</a></li>\n                <li><a href=\"{% url 'Minion_Status' %}\">minion状态</a></li>\n                <li><a href=\"{% url 'SoftInstall' %}\">软件部署</a></li>\n                <li><a href=\"{% url 'JobList' 1 %}\">Job管理</a></li>\n                <li><a href=\"{% url 'RemoteCmd' %}\">批量执行</a></li>\n              </ul>\n            </li>\n          {%endif%}\n        <!--\n          <li class=\"has_sub\"> <a href=\"#\" class=\"waves-effect\"><i class=\"ti-menu-alt\"></i><span> 域名管理 </span></a>\n            <ul class=\"list-unstyled\">\n              <li><a href=\"#\">域名列表</a></li>\n              <li><a href=\"#\">域名解析</a></li>\n              <li><a href=\"#\">变更记录</a></li>\n            </ul>\n          </li>-->\n\n          <!--\n          <li class=\"has_sub\"> <a href=\"#\" class=\"waves-effect\"><i class=\" ti-reload\"></i><span> 代码发布 </span></a>\n            <ul class=\"list-unstyled\">\n              <li><a href=\"#\">增量发布</a></li>\n              <li><a href=\"#\">全量发布</a></li>\n              <li><a href=\"#\">发布记录</a></li>\n            </ul>\n          </li>-->\n\n          <li > <a href=\"/admin\" class=\"waves-effect\"><i class=\" ti-desktop\"></i><span> 系统后台 </span></a>\n        </ul>\n        <div class=\"clearfix\"></div>\n      </div>\n      <div class=\"clearfix\"></div>\n    </div>\n  </div>   <!--菜单-->\n  <!-- ============================================================== -->\n\n\n\n  <div class=\"content-page\">\n    <!-- Start content -->\n\n    <div class=\"content\">\n       {% block content %}\n\n       {% endblock %}\n      <!-- container -->\n    </div>\n    <!-- content -->\n    <footer class=\"footer text-right\"> 2016 &copy; simpletourdevops 简途运维部 </footer>\n  </div>  <!--首页内容-->\n  <!-- ============================================================== -->\n  <!-- Right Sidebar\n  <div class=\"side-bar right-bar nicescroll\">\n    <h4 class=\"text-center\">Chat</h4>\n    <div class=\"contact-list nicescroll\">\n      <ul class=\"list-group contacts-list\">\n        <li class=\"list-group-item\"> <a href=\"#\">\n          <div class=\"avatar\"> <img src=\"/static/assets/images/users/avatar-1.jpg\" alt=\"\"> </div>\n          <span class=\"name\">Chadengle</span> <i class=\"fa fa-circle online\"></i> </a> <span class=\"clearfix\"></span> </li>\n        <li class=\"list-group-item\"> <a href=\"#\">\n          <div class=\"avatar\"> <img src=\"assets/images/users/avatar-2.jpg\" alt=\"\"> </div>\n          <span class=\"name\">Tomaslau</span> <i class=\"fa fa-circle online\"></i> </a> <span class=\"clearfix\"></span> </li>\n        <li class=\"list-group-item\"> <a href=\"#\">\n          <div class=\"avatar\"> <img src=\"assets/images/users/avatar-3.jpg\" alt=\"\"> </div>\n          <span class=\"name\">Stillnotdavid</span> <i class=\"fa fa-circle online\"></i> </a> <span class=\"clearfix\"></span> </li>\n        <li class=\"list-group-item\"> <a href=\"#\">\n          <div class=\"avatar\"> <img src=\"assets/images/users/avatar-4.jpg\" alt=\"\"> </div>\n          <span class=\"name\">Kurafire</span> <i class=\"fa fa-circle online\"></i> </a> <span class=\"clearfix\"></span> </li>\n        <li class=\"list-group-item\"> <a href=\"#\">\n          <div class=\"avatar\"> <img src=\"assets/images/users/avatar-5.jpg\" alt=\"\"> </div>\n          <span class=\"name\">Shahedk</span> <i class=\"fa fa-circle away\"></i> </a> <span class=\"clearfix\"></span> </li>\n        <li class=\"list-group-item\"> <a href=\"#\">\n          <div class=\"avatar\"> <img src=\"assets/images/users/avatar-6.jpg\" alt=\"\"> </div>\n          <span class=\"name\">Adhamdannaway</span> <i class=\"fa fa-circle away\"></i> </a> <span class=\"clearfix\"></span> </li>\n        <li class=\"list-group-item\"> <a href=\"#\">\n          <div class=\"avatar\"> <img src=\"assets/images/users/avatar-7.jpg\" alt=\"\"> </div>\n          <span class=\"name\">Ok</span> <i class=\"fa fa-circle away\"></i> </a> <span class=\"clearfix\"></span> </li>\n        <li class=\"list-group-item\"> <a href=\"#\">\n          <div class=\"avatar\"> <img src=\"assets/images/users/avatar-8.jpg\" alt=\"\"> </div>\n          <span class=\"name\">Arashasghari</span> <i class=\"fa fa-circle offline\"></i> </a> <span class=\"clearfix\"></span> </li>\n        <li class=\"list-group-item\"> <a href=\"#\">\n          <div class=\"avatar\"> <img src=\"assets/images/users/avatar-9.jpg\" alt=\"\"> </div>\n          <span class=\"name\">Joshaustin</span> <i class=\"fa fa-circle offline\"></i> </a> <span class=\"clearfix\"></span> </li>\n        <li class=\"list-group-item\"> <a href=\"#\">\n          <div class=\"avatar\"> <img src=\"assets/images/users/avatar-10.jpg\" alt=\"\"> </div>\n          <span class=\"name\">Sortino</span> <i class=\"fa fa-circle offline\"></i> </a> <span class=\"clearfix\"></span> </li>\n      </ul>\n    </div>\n  </div>-->\n</div>\n{% include  \"tempdir/foot_script.html\" %}\n\n<script>\n    $(document).ready(function() {\n        var pathname = document.location.pathname;\n\n        $('#sidebar-menu .list-unstyled a').each(function(k,value) {\n            if($(value).attr('href') == pathname) {\n                $(value).addClass('hover').parents('.has_sub').find('.waves-effect').addClass('subdrop').next('.list-unstyled').css('display','block');\n            }\n        })\n    })\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "templates/dockermanager/containers_list.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n\n<link href=\"/static/assets/plugins/datatables/jquery.dataTables.min.css\" rel=\"stylesheet\" type=\"text/css\">\n<link href=\"/static/assets/plugins/bootstrap-table/dist/bootstrap-table.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n\n<style>\n    .glyphicon.glyphicon-repeat{\n        visibility: hidden;\n        -moz-animation:rotate 1s infinite linear;\n        -webkit-animation:rotate 1s infinite linear;\n        animation:rotate 1s infinite linear;\n    }\n    @-moz-keyframes rotate{\n        0%{\n          -moz-transform:rotate(0deg);\n         }\n         100%{\n           -moz-transform:rotate(360deg);\n         }\n      }\n      @-webkit-keyframes rotate{\n        0%{\n          -webkit-transform:rotate(0deg);\n         }\n         100%{\n           -webkit-transform:rotate(360deg);\n         }\n      }\n      @keyframes rotate{\n        0%{\n          transform:rotate(0deg);\n         }\n         100%{\n           transform:rotate(360deg);\n         }\n      }\n</style>\n\n\n<div class=\"container\">\n   <!-- Page-Title -->\n    <div class=\"row \">\n            <div class=\"col-sm-12\">\n                <h4 class=\"page-title\">容器列表</h4>\n                <ol class=\"breadcrumb\">\n                    <li>\n                        <a href=\"#\">容器管理</a>\n                    </li>\n                    <li class=\"active\">\n                        <a href=\"{% url 'Dockercontainerlist' 1 %}\">容器列表</a>\n                    </li>\n                </ol>\n            </div>\n            <div class=\"row\">\n                <div class=\"col-sm-12\">\n                    <div class=\"card-box\">\n                        <div class=\"row\">\n                            <div class=\"col-sm-12\">\n                                <h4 class=\"m-t-0 header-title\"><b>Simpletour容器列表</b></h4>\n                                <p class=\"text-muted font-13\">\n                                    服务器详细情况请点击容器ID号\n                                </p>\n                            </div>\n                            <div>\n                                <div class=\"col-sm-4\">\n                                </div>\n                                <form method=\"get\" action=\"{% url 'DockercontainerSearch' 1 %}\">\n                                    <div class=\"col-sm-2\">\n\n                                     <label class=\"col-sm-3 control-label\">IP</label>\n                                            <div class=\"col-sm-8\">\n                                                <select class=\"form-control\" name=\"ipList\">\n                                                    <option value=\"\">--------选择--------</option>\n                                                    {% for ip in DockerHostData %}\n                                                    <option value=\"{{ip.hostip}}\">{{ip.hostip}}</option>\n                                                    {%endfor%}\n                                                </select>\n                                            </div>\n                                     </div>\n                                     <div class=\"col-sm-2\">\n                                     <label class=\"col-sm-3 control-label\">状态</label>\n                                            <div class=\"col-sm-8\">\n                                                <select class=\"form-control\" name=\"status\">\n                                                    <option value=\"\">--------选择--------</option>\n                                                    <option value=\"running\">running</option>\n                                                    <option value=\"Exited\">exited</option>\n                                                </select>\n                                            </div>\n                                     </div>\n                                    <div class=\"col-sm-4\">\n\n                                            <div class=\"input-group\">\n                                                <input type=\"text\" id=\"search\" name=\"search\" class=\"form-control\" placeholder=\"输入容器ID或容器名\">\n                                                <span class=\"input-group-btn\">\n                                                <button type=\"submit\" class=\"btn waves-effect waves-light btn-primary\"  ><i class=\"fa fa-search\"></i></button>\n                                                </span>\n                                            </div>\n\n                                     </div>\n                                </form>\n                            </div>\n                            <div class=\"col-sm-12\">\n                                <br>\n                                <div class=\"bootstrap-table\">\n                                    <div class=\"table-responsive\">\n                                        <table class=\"table-bordered\" data-page-size=\"5\" data-toggle=\"table\" >\n                                            <thead>\n                                                <tr>\n\n                                                    <th>容器ID</th>\n                                                    <th>容器名</th>\n                                                    <th>属主机IP</th>\n                                                    <th>状态</th>\n                                                    <th>镜像</th>\n                                                    <th>命令</th>\n                                                    <th>创建时间</th>\n                                                    <th>操 作</th>\n\n                                                </tr>\n                                            </thead>\n                                            <tbody>\n\n                                            {% for container in Containerdata %}\n                                                <tr>\n                                                    <td>{{container.containerID | slice:\"12\"}}</td>\n                                                    <td>{{container.Name|slice:\"40\"}}</td>\n                                                    <td>{{container.hostip}}</td>\n\n                                                    {% if  container.status == 'running' %}\n                                                        <td align=\"center\"><span class=\"status state_color_510\">running</span></td>\n                                                    {% elif 'Exited in container.status '%}\n                                                        <td align=\"center\"><span class=\"status state_color_610\">Exited </span></td>\n                                                    {%else%}\n                                                        <td align=\"center\"><span class=\"status state_color_610\">{{container.status}}</span></td>\n                                                    {%endif%}\n\n                                                    <td>{{container.image|slice:\"30\"}}</td>\n                                                    <td>{{container.command|slice:\"30\"}}</td>\n                                                    <td>{{container.Created|date:\"Y-m-d H:i:s\"}}</td>\n                                                    <td>\n                                                        {% if container.status == 'running' %}\n                                                            <button data-id=\"{{container.containerID}}\" id=\"stop\" data-type=\"stop\" class=\"btn btn-xs btn-danger change\">停止</button>\n\n                                                        {% else %}\n                                                            <button data-id=\"{{container.containerID}}\" id=\"start\" data-type=\"start\" class=\"btn btn-xs btn-info change\">启动</button>\n\n\n                                                        {% endif%}\n                                                            <button data-id=\"{{container.containerID}}\" id=\"restart\"  data-type=\"restart\" class=\"btn btn-xs btn-danger change\">重启</button>\n\n                                                        <a href=\"{% url 'webSocket' container.containerID %}\" class=\"btn btn-xs btn-info\">控制台</a>\n                                                        <a href=\"{% url 'DockerLogOutput' container.containerID %}\"   class=\"btn btn-xs btn-success\" >显示日志</a>\n                                                        <button data-id=\"{{container.containerID}}\" id=\"delete\"  data-type=\"delete\" class=\"btn btn-xs btn-danger change\">删除</button>\n                                                        <i data-id='status' class=\"glyphicon glyphicon-repeat\"></i>\n                                                    </td>\n                                                </tr>\n                                            {% endfor%}\n                                            </tbody>\n                                        </table>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n                     <div>\n                        <nav>\n                        <ul class=\"pagination\" >\n                            {{page}}\n                        </ul>\n                        </nav>\n                    </div>\n            </div>\n        </div>\n    </div>\n\n    </div>\n</div>\n\n\n<script>\n    var timer,$btn;\n    $(document).on('click','.change',function(e) {\n        $btn = $(this);\n        if($btn.hasClass('disabled')) return;\n        var dockerId = $btn.attr('data-id');\n        var type = $btn.attr('data-type');\n        $.ajax({\n            url:'/docker/container/' + type + '/'+dockerId,\n            beforeSend: function() {\n                $btn.addClass('disabled');\n                $btn.siblings('i').css('visibility','visible');\n            },\n            method:'GET',\n            dataType: 'json',\n            success:function(data){\n                var celeryId = data.celeryId;\n                timer = setInterval(function() {\n                    callback_status(type,celeryId,dockerId);\n                },1000);\n            },\n            error:function(){\n                $btn.siblings('i').css('visibility','hidden');\n                $btn.removeClass('disabled');\n            }\n        });\n\n    });\n\n\n    var callback_status = function(type,celeryId,dockerId) {\n\n        $.ajax({\n            url:'/docker/container/' + type + '/task/' + celeryId,\n            method:'GET',\n            dataType: 'json',\n            data:{\n                'containerid':dockerId,\n            },\n            success:function(data){\n                if(data.state == 'SUCCESS') {\n                    clearInterval(timer);\n                    if(data.result.type == 'start') {\n                        $btn.parents('tr').find('.status')\n                                .removeClass('state_color_610')\n                                .addClass('state_color_510')\n                                .text('running');\n                        $btn.removeClass('btn-info').addClass('btn-danger');\n                        $btn.text('停止');\n\n                    } else if(data.result.type == 'stop') {\n                        $btn.parents('tr').find('.status')\n                                .removeClass('state_color_510')\n                                .addClass('state_color_610')\n                                .text('Exited');\n                        $btn.removeClass('btn-danger').addClass('btn-info');\n                        $btn.text('启动');\n\n                    } else if(data.result.type == 'restart') {\n                        var oldValues = $btn.parents('tr').find('.status').text();\n                        if(oldValues == 'Exited'){\n                            $btn.parents('tr').find('.status')\n                                    .removeClass('state_color_610')\n                                    .addClass('state_color_510')\n                                    .text('running');\n                            $btn.removeClass('btn-info').addClass('btn-danger');\n                        } else {\n                            $btn.removeClass('btn-danger').addClass('btn-info');\n                        }\n                    }else if(data.result.type == 'delete'){\n                        $btn.parents('tr').remove();\n                    };\n                    $.Notification.autoHideNotify('success','top right','系统通知', data.result.resultInfo);\n                    $btn.siblings('i').css('visibility','hidden');\n                    $btn.removeClass('disabled');\n\n                } else if(data.state == 'FAILURE') {\n                    clearInterval(timer);\n                    $.Notification.autoHideNotify('error', 'top right', '系统通知', data.status);\n                    console.log(data.status);\n                    $btn.siblings('i').css('visibility','hidden');\n                    $btn.removeClass('disabled');\n                };\n            },\n            error:function(){\n\n            },\n        });\n    };\n</script>\n\n\n\n\n\n\n\n{% endblock %}"
  },
  {
    "path": "templates/dockermanager/dockerhosts_add.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n    <!-- Plugins css-->\n\n\n    <link href=\"/static/assets/plugins/bootstrap-select/dist/css/bootstrap-select.min.css\" rel=\"stylesheet\" />\n\n\n<div class=\"container\">\n        <div class=\"row \">\n                    <div class=\"col-sm-12\">\n                        <h4 class=\"page-title\">主机添加</h4>\n                        <ol class=\"breadcrumb\">\n                            <li>\n                                <a href=\"#\">容器管理</a>\n                            </li>\n                            <li class=\"active\">\n                                <a href=\"{% url 'DockerHosts' %}\">主机列表</a>\n                            </li>\n                        </ol>\n                    </div>\n\n            <form class=\"form-horizontal\" role=\"form\" method=\"POST\" action=\"{% url 'DockerHostAdd' %}\">\n                    {% csrf_token  %}\n                    <div class=\"row\">\n                        <div class=\"col-sm-6\">\n                            <div class=\"card-box\">\n                                <div class=\"row\">\n                                    <div class=\"col-md-12\">\n                                             <div class=\"form-group\">\n                                                <label class=\"col-md-3 control-label\">主机SN关联:</label>\n                                                <div class=\"col-md-6\">\n\n                                               <select class=\"selectpicker show-tick\" data-style=\"btn-white\" name=\"DockerServer\">\n                                                    {% for s in ServerData %}\n                                                            <option value=\"{{s.id}}\">{{s}}</option>\n                                                    {%endfor%}\n                                                </select>\n                                                </div>\n                                            </div>\n\n                                            <div class=\"form-group\">\n                                                <label class=\"col-md-3 control-label\" for=\"state-warning\">docker主机IP:</label>\n                                                <div class=\"col-md-6\">\n                                                     {{ data.dockerip}}\n\t\t\t\t\t\t\t\t                     {{ data.dockerip.errors}}\n\n                                                </div>\n                                            </div>\n\n                                            <div class=\"form-group\">\n                                                <label class=\"col-md-3 control-label\" for=\"state-danger\">docker主机port:</label>\n                                                <div class=\"col-md-6\">\n                                                    {{ data.dockerport}}\n\t\t\t\t\t\t\t\t                    {{ data.dockerport.errors}}\n                                                    <!--<input type=\"text\" id=\"state-danger\" name=\"state-danger\" class=\"form-control\" placeholder=\"...\">-->\n                                                </div>\n                                            </div>\n\n                                            <div class=\"form-group\">\n                                                <label class=\"col-sm-3 control-label\">主机状态: </label>\n                                                <div class=\"col-md-6\">\n                                                   {{data.ServerStatus}}\n                                                </div>\n\n                                                <!--\n\n\n                                                    <select class=\"selectpicker show-tick\" data-style=\"btn-white\">\n                                                         <option value=\"0\" >启用</option>\n                                                         <option value=\"1\" >禁用</option>\n                                                    </select>\n                                                </div>-->\n                                            </div>\n\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n\n                     <!-- 提交按钮 -->\n                    <div class=\"row\">\n                        <div class=\"col-sm-6\">\n                            <div class=\"form-group text-right\">\n                                <button type=\"submit\" class=\"btn btn-primary\">\n                                    提交\n                                </button>\n                            </div>\n                        </div>\n                    </div>\n            </form>\n         </div>\n</div>\n\n\n<script src=\"/static/assets/plugins/bootstrap-select/dist/js/bootstrap-select.min.js\" type=\"text/javascript\"></script>\n\n{% endblock %}\n"
  },
  {
    "path": "templates/dockermanager/dockerhosts_edit.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n    <!-- Plugins css-->\n\n\n    <link href=\"/static/assets/plugins/bootstrap-select/dist/css/bootstrap-select.min.css\" rel=\"stylesheet\" />\n\n\n<div class=\"container\">\n        <div class=\"row \">\n                    <div class=\"col-sm-12\">\n                        <h4 class=\"page-title\">主机修改</h4>\n                        <ol class=\"breadcrumb\">\n                            <li>\n                                <a href=\"#\">容器管理</a>\n                            </li>\n                            <li class=\"active\">\n                                <a href=\"{% url 'DockerHosts' %}\">主机列表</a>\n                            </li>\n                        </ol>\n                    </div>\n\n            <form class=\"form-horizontal\" role=\"form\" method=\"POST\" action=\"{% url 'DockerHostEdit' hostid %}\">\n                    {% csrf_token  %}\n                    <div class=\"row\">\n                        <div class=\"col-sm-6\">\n                            <div class=\"card-box\">\n                                <div class=\"row\">\n                                   <div class=\"col-md-12\">\n                                             <div class=\"form-group\">\n                                                <label class=\"col-md-3 control-label\">主机SN关联:</label>\n                                                <div class=\"col-md-6\">\n                                                   <select class=\"selectpicker show-tick bs-select-hidden\" data-style=\"btn-white\" name=\"DockerServer\">\n                                                       {% for i in ServerData %}\n                                                            {% if HostData.host.id == i.id%}\n                                                                <option value=\"{{i.id}}\" selected>{{i}}</option>\n                                                            {%else%}\n                                                                <option value=\"{{i.id}}\" >{{i}}</option>\n                                                            {%endif%}\n                                                       {%endfor%}\n                                                    </select>\n                                                </div>\n                                            </div>\n\n                                            <div class=\"form-group\">\n                                                <label class=\"col-md-3 control-label\" for=\"state-warning\">docker主机IP:</label>\n                                                <div class=\"col-md-6\">\n                                                     <input class=\"form-control\" id=\"id_dockerip\" name=\"dockerip\" value=\"{{HostData.hostip}}\" placeholder=\"宿主机IP\" type=\"text\">\n                                                </div>\n                                            </div>\n\n                                            <div class=\"form-group\">\n                                                <label class=\"col-md-3 control-label\" for=\"state-danger\">docker主机port:</label>\n                                                <div class=\"col-md-6\">\n                                                    <input class=\"form-control\" id=\"id_dockerport\" name=\"dockerport\" value=\"{{HostData.port}}\" placeholder=\"宿主机端口\" type=\"text\">\n                                                </div>\n                                            </div>\n\n                                            <div class=\"form-group\">\n                                                <label class=\"col-sm-3 control-label\">主机状态: </label>\n                                                <div class=\"col-md-6\">\n                                                   <select class=\"form-control\" id=\"id_ServerStatus\" name=\"ServerStatus\">\n                                                       {% if HostData.enabled == '0' %}\n                                                            <option value=\"0\" selected>禁用</option>\n                                                            <option value=\"1\">启用</option>\n                                                       {%else%}\n                                                            <option value=\"0\" >禁用</option>\n                                                            <option value=\"1\" selected>启用</option>\n                                                       {%endif%}\n                                                   </select>\n                                                </div>\n\n\n                                            </div>\n\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n\n                     <!-- 提交按钮 -->\n                    <div>\n                        <div class=\"col-sm-6\">\n                            <div class=\"form-group text-right\">\n                                <button type=\"submit\" class=\"btn btn-primary\">\n                                    修改\n                                </button>\n                            </div>\n                        </div>\n                    </div>\n            </form>\n         </div>\n</div>\n<!--\n<script>\n    jQuery(document).ready(function(){\n               $('button[type=submit]').click(function(e) {\n                    e.preventDefault();\n                     $.ajax({\n                        type: 'POST',\n                        url: '{% url \"DockerHostAdd\" %}',\n                        data: $('.form-horizontal').serialize(),\n                        success: function(data) {\n                           alert(data);\n                        },\n                        error: function() {},\n                    });\n\n               });\n    });\n</script>-->\n\n<script src=\"/static/assets/plugins/bootstrap-select/dist/js/bootstrap-select.min.js\" type=\"text/javascript\"></script>\n\n{% endblock %}\n"
  },
  {
    "path": "templates/dockermanager/dockerhosts_list.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n<link href=\"/static/assets/plugins/switchery/dist/switchery.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n\n<div class=\"container\">\n\n\t\t\t\t\t\t<!-- Page-Title -->\n\t\t\t\t\t\t<div class=\"row\">\n\t\t\t\t\t\t\t<div class=\"col-sm-12\">\n\t\t\t\t\t\t\t\t<h4 class=\"page-title\">容器管理</h4>\n\t\t\t\t\t\t\t\t<ol class=\"breadcrumb\">\n\t\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t\t<a href=\"{% url 'DockerHosts' %}\">容器管理</a>\n\t\t\t\t\t\t\t\t\t</li>\n\n\t\t\t\t\t\t\t\t\t<li class=\"active\">\n\t\t\t\t\t\t\t\t\t\t主机列表\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t</ol>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n                        <div class=\"row\">\n\t\t\t\t\t\t\t<div class=\"col-sm-10\">\n\t\t\t\t\t\t\t\t<div class=\"row\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-sm-12\">\n\t\t\t\t\t\t\t\t\t\t\t<a  href=\"{% url 'DockerHostAdd' %}\"><button class=\"btn btn-primary \" type=\"button\">添加宿主机</button></a>\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<br>\n\t\t\t\t\t\t\t\t<div class=\"card-box\">\n\n\t\t\t\t\t\t\t\t\t<div class=\"row\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"col-sm-12\">\n\t\t\t\t\t\t\t\t\t\t\t<h4 class=\"m-t-0 header-title\"><b>容器主机列表</b></h4>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"p-20\">\n\t\t\t\t\t\t\t\t\t\t\t\t<table class=\"table table-striped m-0\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th>#</th>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th>设备名</th>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th>主机名</th>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th>主机IP</th>\n                                                            <th>docker端口</th>\n                                                            <th>启用</th>\n                                                            <td>操作</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% for docker in Hostadata%}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th scope=\"row\" data-id=\"{{docker.id}}\">{{docker.id}}</th>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>{{docker.host.Assets.host_name}}</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>{{docker.host.hostname}}</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>{{docker.hostip}}\n                                                            </td>\n                                                            <td>{{docker.port}}</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% if docker.enabled == 1 %}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t    <input type=\"checkbox\" name=\"enableCheckbox\" checked  class=\"js-switch\" data-plugin=\"switchery\" data-color=\"#f05050\" data-size=\"small\"/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% else %}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input type=\"checkbox\" name=\"enableCheckbox\"  class=\"js-switch\"  data-plugin=\"switchery\" data-color=\"#f05050\" data-size=\"small\"/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{%endif%}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</td>\n                                                             <td>\n                                                                 <a  href=\"{% url 'DockerHostEdit' docker.id %}\" class=\"btn btn-xs btn-info\">修改</a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t <button  class=\"btn btn-xs btn-danger\" onclick=\"hostdelete({{docker.id}})\">删除</button>\n                                                             </td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% endfor%}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\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>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n                    </div>\n<script src=\"/static/assets/plugins/switchery/dist/switchery.min.js\"></script>\n\n<script>\n\t$(document).ready(function() {\n\t\t$('.switchery').click(function(e) {\n\t\t\tvar $this = $(this);\n\t\t\tvar checkboxValue = this.parentElement.querySelector('input').checked;\n\t\t\tvar id = $this.parent('td').siblings('th').attr('data-id');\n\t\t\tif($this.hasClass('disabled')) return;\n\t\t\t$this.addClass('disabled');\n\t\t\t$.ajax({\n\t\t\t\tmethod: 'POST',\n                dataType: 'json',\n\t\t\t\turl: '{%url 'DockerHosts' %}',\n\t\t\t\tdata: {\n\t\t\t\t\t'id': id,\n\t\t\t\t\t'checkboxValue': checkboxValue,\n\t\t\t\t\t'csrfmiddlewaretoken': '{{ csrf_token }}',\n\t\t\t\t},\n\t\t\t\tsuccess: function(data) {\n\t\t\t\t\tvar msginfo=data.msginfo;\n\t\t\t\t\tif(msginfo){\n\t\t\t\t\t\t$.Notification.autoHideNotify('success','top right','系统通知', msginfo);\n\t\t\t\t\t}\n\t\t\t\t\t$this.removeClass('disabled');\n\t\t\t\t},\n\t\t\t\terror: function() {\n\t\t\t\t\t$this.removeClass('disabled');\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t})\n\n\n\n\n</script>\n<script>\n\tfunction hostdelete(e){\n\t\t$.ajax({\n            method: \"GET\",\n            url:\"/docker/server/del/\" + e,\n            dataType: 'json',\n            success:function(result){\n                var msginfo=result.msginfo;\n                var msgerror=result.msgerror;\n                if(msginfo){\n                    $.Notification.autoHideNotify('success','top right','系统通知', msginfo);\n                    setTimeout(function() {\n                          location.href = '{% url 'DockerHosts'  %}';\n                     },2500);\n\n                }else{\n                    $.Notification.autoHideNotify('error', 'top right', '系统通知',msgerror);\n\n                }\n\n            },\n            error:function(e){\n                alert(e);\n\n            }\n\n        });\n\t}\n\n\n</script>\n{% endblock%}"
  },
  {
    "path": "templates/dockermanager/dockerhosts_logs.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n\n\n<div class=\"container\">\n\n\t\t\t<!-- Page-Title -->\n\t\t\t<div class=\"row\">\n\t\t\t\t<div class=\"col-sm-12\">\n\t\t\t\t\t<h4 class=\"page-title\">容器管理</h4>\n\t\t\t\t\t<ol class=\"breadcrumb\">\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<a href=\"{% url 'DockerHosts' %}\">容器管理</a>\n\t\t\t\t\t\t</li>\n\n\t\t\t\t\t\t<li class=\"active\">\n\t\t\t\t\t\t\t容器日志\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ol>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"row\">\n\t\t\t\t<div style=\"background-color:#000000;color:#FFFFFF;\" class=\"col-sm-12\" id=\"containerid\" data-target=\"{{containerid}}\">\n\t\t\t\t\t{% for lin in dockerlogsdata %}\n\t\t\t\t\t\t\t{{lin}}<br>\n\t\t\t\t\t{%endfor%}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n<script>\n/*第一次读取最新通知*/\n  setTimeout(function() {\n             Push();\n           },\n        200);\n      /*30轮询读取函数*/\n        setInterval(function() {\n\n            Push();\n\n    },\n        2000);\n\n/*请求函数的ajax*/\nfunction Push() {\n\ta=document.getElementById(\"containerid\");\n\tvar id = a.getAttribute('data-target');\n    $.ajax({\n        type: \"POST\",\n        url: \"/docker/container/logs/\" + id,\n        data:{\n\t\t\tcsrfmiddlewaretoken:'{{ csrf_token  }}',\n        },\n        beforeSend: function() {},\n        success: function(data) {\n        \tdocument.getElementById(\"containerid\").innerHTML='';\n\t\t\tfor (var i=0;i<JSON.parse(data).dockerlogsdata.length;i++){\n\t\t\t\tvar HtmlText=JSON.parse(data).dockerlogsdata[i] + '<br/>'\n    \t\t\tdocument.getElementById(\"containerid\").innerHTML+=(HtmlText);\n    \t\t}\n        },\n    });\n}\n\n</script>\n{% endblock%}"
  },
  {
    "path": "templates/dockermanager/images_list.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n\n<link href=\"/static/assets/plugins/datatables/jquery.dataTables.min.css\" rel=\"stylesheet\" type=\"text/css\">\n<link href=\"/static/assets/plugins/bootstrap-table/dist/bootstrap-table.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n\n<div class=\"container\">\n   <!-- Page-Title -->\n    <div class=\"row \">\n            <div class=\"col-sm-12\">\n                <h4 class=\"page-title\">镜像列表</h4>\n                <ol class=\"breadcrumb\">\n                    <li>\n                        <a href=\"#\">镜像管理</a>\n                    </li>\n                    <li class=\"active\">\n                        <a href=\"{% url 'DockerImages' 1 %}\">镜像列表</a>\n                    </li>\n                </ol>\n            </div>\n            <div class=\"row\">\n                <div class=\"col-sm-12\">\n                    <div class=\"card-box\">\n                        <div class=\"row\">\n                            <div class=\"col-sm-12\">\n                                <h4 class=\"m-t-0 header-title\"><b>Simpletour镜像列表</b></h4>\n                                <br>\n                                <div class=\"bootstrap-table\">\n                                    <div class=\"table-responsive\">\n                                        <table class=\"table-bordered\" data-page-size=\"5\" data-toggle=\"table\" >\n                                            <thead>\n                                                <tr>\n\n                                                    <th>镜像ID</th>\n                                                    <th>镜像名</th>\n                                                    <th>版本tag</th>\n                                                    <th>宿主机</th>\n                                                    <th>镜像大小</th>\n                                                    <th>操 作</th>\n                                                </tr>\n                                            </thead>\n                                            <tbody>\n\n                                            {% for image in Imagedata %}\n                                                <tr>\n\n                                                    <td>{{image.imagesId | slice:\"12\"}}</td>\n                                                    <td>{{image.repository}}</td>\n                                                    <td>{{image.tag}}</td>\n                                                    <td>{{image.imagehost}}</td>\n                                                    <td>{{image.size}}</td>\n                                                    <td>\n                                                        <a href=\"{% url 'DockerImageDelete' image.id %}\" class=\"btn btn-xs btn-danger\">删除</a>\n                                                    </td>\n                                                </tr>\n                                            {% endfor%}\n\n                                            </tbody>\n                                        </table>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n\n                    <div class=\"row\">\n                        <nav>\n                        <ul class=\"pagination\" >\n                            {{page}}\n                        </ul>\n                        </nav>\n                    </div>\n            </div>\n        </div>\n    </div>\n\n    </div>\n</div>\n\n\n{% endblock %}"
  },
  {
    "path": "templates/dockermanager/websocket.html",
    "content": "{% extends 'base.html' %}\n{% load staticfiles %}\n\n{% block content %}\n\n        <style>\n            body {\n                color: #111;\n            }\n\n            #terminal-container {\n                max-width: 800px;\n                margin: 0 auto;\n            }\n\n            #terminal-container a {\n                color: #fff;\n            }\n        </style>\n\n\n<div id=\"terminal-container\" data-id=\"{{containerId}}\" ></div>\n        <script>\n            container = document.getElementById('terminal-container');\n            var term = new Terminal(),\n                //url = 'ws://192.168.2.232:2375/containers/4d0c7ed3aa0d/attach/ws?logs=0&stream=1&stdin=1&stdout=1&stderr=1',\n                url = 'ws://192.168.4.223:8888/docker/getSocket/'+$('#terminal-container').attr('data-id')\n                socket = new WebSocket(url);\n\n            term.open(document.getElementById('terminal-container'));\n            term.on('data', function (data) {\n                socket.send(data);\n            });\n\n            socket.onmessage = function (e) {\n                term.write(e.data);\n            }\n        </script>\n\n{% endblock %}"
  },
  {
    "path": "templates/domainmanager/domain_list.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n\n<div class=\"container\">\n   <!-- Page-Title -->\n    <div class=\"row \">\n      <div class=\"col-sm-12\">\n                <h4 class=\"page-title\">域名列表</h4>\n                <ol class=\"breadcrumb\">\n                    <li>\n                        <a href=\"#\">域名管理</a>\n                    </li>\n                    <li class=\"active\">\n                        <a href=\"{% url 'SimpletourDomainLists'  %}\">域名列表</a>\n                    </li>\n                </ol>\n            </div>\n      <div class=\"col-sm-10\">\n            <div class=\"card-box\">\n                <div class=\"row\">\n                    <div class=\"col-lg-12\">\n                        <h4 class=\"m-t-0 header-title\"><b>域名列表</b></h4>\n                        <p class=\"text-muted font-13\">\n                            以下域名列表信息是通过Dnspod api 获取\n                        </p>\n\n                        <div class=\"p-20\">\n                            <div class=\"table-responsive\">\n                                <table class=\"table m-0\">\n                                    <thead>\n                                        <tr>\n                                            <th>域名ID</th>\n                                            <th>域名</th>\n                                            <th>状态</th>\n                                            <th>拥有者</th>\n\n                                            <th>解析记录</th>\n                                            <th>ttl</th>\n                                            <th>创建时间</th>\n                                        </tr>\n                                    </thead>\n\n                                    <tbody id=\"tableid\">\n\n                                    </tbody>\n                                </table>\n                            </div>\n                        </div>\n\n                    </div>\n\n                </div>\n            </div>\n      </div>\n    </div>\n</div>\n\n<script src=\"/static/assets/js/spin.js\"></script>\n\n<script>\n    var opts = {\n              lines: 11 // The number of lines to draw\n            , length: 2 // The length of each line\n            , width: 5 // The line thickness\n            , radius: 25 // The radius of the inner circle\n            , scale: 1 // Scales overall size of the spinner\n            , corners: 1 // Corner roundness (0..1)\n            , color: '#000' // #rgb or #rrggbb or array of colors\n            , opacity: 0.1 // Opacity of the lines\n            , rotate: 0 // The rotation offset\n            , direction: 1 // 1: clockwise, -1: counterclockwise\n            , speed: 1 // Rounds per second\n            , trail: 34 // Afterglow percentage\n            , fps: 20 // Frames per second when using setTimeout() as a fallback for CSS\n            , zIndex: 2e9 // The z-index (defaults to 2000000000)\n            , className: 'spinner' // The CSS class to assign to the spinner\n            , top: '48%' // Top position relative to parent\n            , left: '51%' // Left position relative to parent\n            , shadow: true // Whether to render a shadow\n            , hwaccel: false // Whether to use hardware acceleration\n            , position: 'absolute' // Element positioning\n            };\n\n        var spinner = new Spinner(opts);\n\n\n    $(function () {\n        var target = document.getElementById('tableid');\n        var spinner = new Spinner(opts).spin(target);\n        $.ajax({\n            dataType:'json',\n            method: 'get',\n            url: '/domain/dnspodapi/',\n\n\n            success: function (data) {\n                var tableHtml = '';\n                data.list_domain.forEach(function(domain) {\n                     tableHtml += '<tr>' +\n                        '<th scope=\"row\">'+ domain.id +'</th>' +\n                        '<td>'+ domain.name +'</td>' +\n                        '<td>'+ domain.status + '</td>' +\n                        '<td>'+ domain.owner+'</td>' +\n                        '<td><a href=\"/domain/record/search/'+ domain.id  + '\">' + domain.records+'</a></td>' +\n                        '<td>'+ domain.ttl+'</td>' +\n                        '<td>'+ domain.created_on+'</td>' +\n                    '</tr>';\n                })\n                $('tbody').append(tableHtml);\n                spinner.stop();\n\n            },\n            error: function (data) {\n                alert(data.responseText);\n                spinner.stop();\n\n            },\n            complete: function() {\n\n            }\n        })\n\n\n\n\n    })\n\n\n\n\n</script>\n{% endblock %}\n\n"
  },
  {
    "path": "templates/domainmanager/domain_records.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n<link href=\"/static/assets/plugins/datatables/jquery.dataTables.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n<div class=\"container\">\n   <!-- Page-Title -->\n    <div class=\"row \">\n      <div class=\"col-sm-12\">\n                <h4 class=\"page-title\">解析列表</h4>\n                <ol class=\"breadcrumb\">\n                    <li>\n                        <a href=\"#\">域名管理</a>\n                    </li>\n                    <li class=\"active\">\n                        <a href=\"{% url 'SimpletourDomainLists'  %}\">域名列表</a>\n                    </li>\n\n                </ol>\n            </div>\n      <div class=\"col-sm-10\">\n            <div class=\"card-box\">\n                <div class=\"row\">\n                    <div class=\"col-lg-12\">\n                        <h4 class=\"m-t-0 header-title\"><b>解析列表</b></h4>\n                        <p class=\"text-muted font-13\">\n                            以下域名列表信息是通过Dnspod api 获取\n                        </p>\n\n                    </div>\n\n                </div>\n\n                      <div class=\"row\">\n                            <div class=\"col-sm-12\">\n                                <div class=\"card-box\">\n                                    <table id=\"datatable\" class=\"table table-striped table-bordered\">\n                                            <thead>\n                                                <tr>\n                                                    <th>Name</th>\n                                                    <th>Position</th>\n                                                    <th>Office</th>\n                                                    <th>Age</th>\n                                                    <th>Start date</th>\n                                                    <th>Salary</th>\n                                                </tr>\n                                            </thead>\n\n\n                                            <tbody>\n                                                <tr>\n                                                    <td>Tiger Nixon</td>\n                                                    <td>System Architect</td>\n                                                    <td>Edinburgh</td>\n                                                    <td>61</td>\n                                                    <td>2011/04/25</td>\n                                                    <td>$320,800</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Garrett Winters</td>\n                                                    <td>Accountant</td>\n                                                    <td>Tokyo</td>\n                                                    <td>63</td>\n                                                    <td>2011/07/25</td>\n                                                    <td>$170,750</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Ashton Cox</td>\n                                                    <td>Junior Technical Author</td>\n                                                    <td>San Francisco</td>\n                                                    <td>66</td>\n                                                    <td>2009/01/12</td>\n                                                    <td>$86,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Cedric Kelly</td>\n                                                    <td>Senior Javascript Developer</td>\n                                                    <td>Edinburgh</td>\n                                                    <td>22</td>\n                                                    <td>2012/03/29</td>\n                                                    <td>$433,060</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Airi Satou</td>\n                                                    <td>Accountant</td>\n                                                    <td>Tokyo</td>\n                                                    <td>33</td>\n                                                    <td>2008/11/28</td>\n                                                    <td>$162,700</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Brielle Williamson</td>\n                                                    <td>Integration Specialist</td>\n                                                    <td>New York</td>\n                                                    <td>61</td>\n                                                    <td>2012/12/02</td>\n                                                    <td>$372,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Herrod Chandler</td>\n                                                    <td>Sales Assistant</td>\n                                                    <td>San Francisco</td>\n                                                    <td>59</td>\n                                                    <td>2012/08/06</td>\n                                                    <td>$137,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Rhona Davidson</td>\n                                                    <td>Integration Specialist</td>\n                                                    <td>Tokyo</td>\n                                                    <td>55</td>\n                                                    <td>2010/10/14</td>\n                                                    <td>$327,900</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Colleen Hurst</td>\n                                                    <td>Javascript Developer</td>\n                                                    <td>San Francisco</td>\n                                                    <td>39</td>\n                                                    <td>2009/09/15</td>\n                                                    <td>$205,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Sonya Frost</td>\n                                                    <td>Software Engineer</td>\n                                                    <td>Edinburgh</td>\n                                                    <td>23</td>\n                                                    <td>2008/12/13</td>\n                                                    <td>$103,600</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Jena Gaines</td>\n                                                    <td>Office Manager</td>\n                                                    <td>London</td>\n                                                    <td>30</td>\n                                                    <td>2008/12/19</td>\n                                                    <td>$90,560</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Quinn Flynn</td>\n                                                    <td>Support Lead</td>\n                                                    <td>Edinburgh</td>\n                                                    <td>22</td>\n                                                    <td>2013/03/03</td>\n                                                    <td>$342,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Charde Marshall</td>\n                                                    <td>Regional Director</td>\n                                                    <td>San Francisco</td>\n                                                    <td>36</td>\n                                                    <td>2008/10/16</td>\n                                                    <td>$470,600</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Haley Kennedy</td>\n                                                    <td>Senior Marketing Designer</td>\n                                                    <td>London</td>\n                                                    <td>43</td>\n                                                    <td>2012/12/18</td>\n                                                    <td>$313,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Tatyana Fitzpatrick</td>\n                                                    <td>Regional Director</td>\n                                                    <td>London</td>\n                                                    <td>19</td>\n                                                    <td>2010/03/17</td>\n                                                    <td>$385,750</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Michael Silva</td>\n                                                    <td>Marketing Designer</td>\n                                                    <td>London</td>\n                                                    <td>66</td>\n                                                    <td>2012/11/27</td>\n                                                    <td>$198,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Paul Byrd</td>\n                                                    <td>Chief Financial Officer (CFO)</td>\n                                                    <td>New York</td>\n                                                    <td>64</td>\n                                                    <td>2010/06/09</td>\n                                                    <td>$725,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Gloria Little</td>\n                                                    <td>Systems Administrator</td>\n                                                    <td>New York</td>\n                                                    <td>59</td>\n                                                    <td>2009/04/10</td>\n                                                    <td>$237,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Bradley Greer</td>\n                                                    <td>Software Engineer</td>\n                                                    <td>London</td>\n                                                    <td>41</td>\n                                                    <td>2012/10/13</td>\n                                                    <td>$132,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Dai Rios</td>\n                                                    <td>Personnel Lead</td>\n                                                    <td>Edinburgh</td>\n                                                    <td>35</td>\n                                                    <td>2012/09/26</td>\n                                                    <td>$217,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Jenette Caldwell</td>\n                                                    <td>Development Lead</td>\n                                                    <td>New York</td>\n                                                    <td>30</td>\n                                                    <td>2011/09/03</td>\n                                                    <td>$345,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Yuri Berry</td>\n                                                    <td>Chief Marketing Officer (CMO)</td>\n                                                    <td>New York</td>\n                                                    <td>40</td>\n                                                    <td>2009/06/25</td>\n                                                    <td>$675,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Caesar Vance</td>\n                                                    <td>Pre-Sales Support</td>\n                                                    <td>New York</td>\n                                                    <td>21</td>\n                                                    <td>2011/12/12</td>\n                                                    <td>$106,450</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Doris Wilder</td>\n                                                    <td>Sales Assistant</td>\n                                                    <td>Sidney</td>\n                                                    <td>23</td>\n                                                    <td>2010/09/20</td>\n                                                    <td>$85,600</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Angelica Ramos</td>\n                                                    <td>Chief Executive Officer (CEO)</td>\n                                                    <td>London</td>\n                                                    <td>47</td>\n                                                    <td>2009/10/09</td>\n                                                    <td>$1,200,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Gavin Joyce</td>\n                                                    <td>Developer</td>\n                                                    <td>Edinburgh</td>\n                                                    <td>42</td>\n                                                    <td>2010/12/22</td>\n                                                    <td>$92,575</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Jennifer Chang</td>\n                                                    <td>Regional Director</td>\n                                                    <td>Singapore</td>\n                                                    <td>28</td>\n                                                    <td>2010/11/14</td>\n                                                    <td>$357,650</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Brenden Wagner</td>\n                                                    <td>Software Engineer</td>\n                                                    <td>San Francisco</td>\n                                                    <td>28</td>\n                                                    <td>2011/06/07</td>\n                                                    <td>$206,850</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Fiona Green</td>\n                                                    <td>Chief Operating Officer (COO)</td>\n                                                    <td>San Francisco</td>\n                                                    <td>48</td>\n                                                    <td>2010/03/11</td>\n                                                    <td>$850,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Shou Itou</td>\n                                                    <td>Regional Marketing</td>\n                                                    <td>Tokyo</td>\n                                                    <td>20</td>\n                                                    <td>2011/08/14</td>\n                                                    <td>$163,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Michelle House</td>\n                                                    <td>Integration Specialist</td>\n                                                    <td>Sidney</td>\n                                                    <td>37</td>\n                                                    <td>2011/06/02</td>\n                                                    <td>$95,400</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Suki Burks</td>\n                                                    <td>Developer</td>\n                                                    <td>London</td>\n                                                    <td>53</td>\n                                                    <td>2009/10/22</td>\n                                                    <td>$114,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Prescott Bartlett</td>\n                                                    <td>Technical Author</td>\n                                                    <td>London</td>\n                                                    <td>27</td>\n                                                    <td>2011/05/07</td>\n                                                    <td>$145,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Gavin Cortez</td>\n                                                    <td>Team Leader</td>\n                                                    <td>San Francisco</td>\n                                                    <td>22</td>\n                                                    <td>2008/10/26</td>\n                                                    <td>$235,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Martena Mccray</td>\n                                                    <td>Post-Sales support</td>\n                                                    <td>Edinburgh</td>\n                                                    <td>46</td>\n                                                    <td>2011/03/09</td>\n                                                    <td>$324,050</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Unity Butler</td>\n                                                    <td>Marketing Designer</td>\n                                                    <td>San Francisco</td>\n                                                    <td>47</td>\n                                                    <td>2009/12/09</td>\n                                                    <td>$85,675</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Howard Hatfield</td>\n                                                    <td>Office Manager</td>\n                                                    <td>San Francisco</td>\n                                                    <td>51</td>\n                                                    <td>2008/12/16</td>\n                                                    <td>$164,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Hope Fuentes</td>\n                                                    <td>Secretary</td>\n                                                    <td>San Francisco</td>\n                                                    <td>41</td>\n                                                    <td>2010/02/12</td>\n                                                    <td>$109,850</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Vivian Harrell</td>\n                                                    <td>Financial Controller</td>\n                                                    <td>San Francisco</td>\n                                                    <td>62</td>\n                                                    <td>2009/02/14</td>\n                                                    <td>$452,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Timothy Mooney</td>\n                                                    <td>Office Manager</td>\n                                                    <td>London</td>\n                                                    <td>37</td>\n                                                    <td>2008/12/11</td>\n                                                    <td>$136,200</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Jackson Bradshaw</td>\n                                                    <td>Director</td>\n                                                    <td>New York</td>\n                                                    <td>65</td>\n                                                    <td>2008/09/26</td>\n                                                    <td>$645,750</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Olivia Liang</td>\n                                                    <td>Support Engineer</td>\n                                                    <td>Singapore</td>\n                                                    <td>64</td>\n                                                    <td>2011/02/03</td>\n                                                    <td>$234,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Bruno Nash</td>\n                                                    <td>Software Engineer</td>\n                                                    <td>London</td>\n                                                    <td>38</td>\n                                                    <td>2011/05/03</td>\n                                                    <td>$163,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Sakura Yamamoto</td>\n                                                    <td>Support Engineer</td>\n                                                    <td>Tokyo</td>\n                                                    <td>37</td>\n                                                    <td>2009/08/19</td>\n                                                    <td>$139,575</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Thor Walton</td>\n                                                    <td>Developer</td>\n                                                    <td>New York</td>\n                                                    <td>61</td>\n                                                    <td>2013/08/11</td>\n                                                    <td>$98,540</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Finn Camacho</td>\n                                                    <td>Support Engineer</td>\n                                                    <td>San Francisco</td>\n                                                    <td>47</td>\n                                                    <td>2009/07/07</td>\n                                                    <td>$87,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Serge Baldwin</td>\n                                                    <td>Data Coordinator</td>\n                                                    <td>Singapore</td>\n                                                    <td>64</td>\n                                                    <td>2012/04/09</td>\n                                                    <td>$138,575</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Zenaida Frank</td>\n                                                    <td>Software Engineer</td>\n                                                    <td>New York</td>\n                                                    <td>63</td>\n                                                    <td>2010/01/04</td>\n                                                    <td>$125,250</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Zorita Serrano</td>\n                                                    <td>Software Engineer</td>\n                                                    <td>San Francisco</td>\n                                                    <td>56</td>\n                                                    <td>2012/06/01</td>\n                                                    <td>$115,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Jennifer Acosta</td>\n                                                    <td>Junior Javascript Developer</td>\n                                                    <td>Edinburgh</td>\n                                                    <td>43</td>\n                                                    <td>2013/02/01</td>\n                                                    <td>$75,650</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Cara Stevens</td>\n                                                    <td>Sales Assistant</td>\n                                                    <td>New York</td>\n                                                    <td>46</td>\n                                                    <td>2011/12/06</td>\n                                                    <td>$145,600</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Hermione Butler</td>\n                                                    <td>Regional Director</td>\n                                                    <td>London</td>\n                                                    <td>47</td>\n                                                    <td>2011/03/21</td>\n                                                    <td>$356,250</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Lael Greer</td>\n                                                    <td>Systems Administrator</td>\n                                                    <td>London</td>\n                                                    <td>21</td>\n                                                    <td>2009/02/27</td>\n                                                    <td>$103,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Jonas Alexander</td>\n                                                    <td>Developer</td>\n                                                    <td>San Francisco</td>\n                                                    <td>30</td>\n                                                    <td>2010/07/14</td>\n                                                    <td>$86,500</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Shad Decker</td>\n                                                    <td>Regional Director</td>\n                                                    <td>Edinburgh</td>\n                                                    <td>51</td>\n                                                    <td>2008/11/13</td>\n                                                    <td>$183,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Michael Bruce</td>\n                                                    <td>Javascript Developer</td>\n                                                    <td>Singapore</td>\n                                                    <td>29</td>\n                                                    <td>2011/06/27</td>\n                                                    <td>$183,000</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>Donna Snider</td>\n                                                    <td>Customer Support</td>\n                                                    <td>New York</td>\n                                                    <td>27</td>\n                                                    <td>2011/01/25</td>\n                                                    <td>$112,000</td>\n                                                </tr>\n                                            </tbody>\n                                        </table>\n                                </div>\n                            </div>\n                        </div>\n\n\n\n\n            </div>\n      </div>\n    </div>\n</div>\n\n<script src=\"/static/assets/plugins/datatables/jquery.dataTables.min.js\"></script>\n<script src=\"/static/assets/plugins/datatables/dataTables.bootstrap.js\"></script>\n\n<script type=\"text/javascript\">\n            $(document).ready(function() {\n                $('#datatable').dataTable();\n            } );\n</script>\n\n<script>\n    var opts = {\n              lines: 11 // The number of lines to draw\n            , length: 2 // The length of each line\n            , width: 5 // The line thickness\n            , radius: 25 // The radius of the inner circle\n            , scale: 1 // Scales overall size of the spinner\n            , corners: 1 // Corner roundness (0..1)\n            , color: '#000' // #rgb or #rrggbb or array of colors\n            , opacity: 0.1 // Opacity of the lines\n            , rotate: 0 // The rotation offset\n            , direction: 1 // 1: clockwise, -1: counterclockwise\n            , speed: 1 // Rounds per second\n            , trail: 34 // Afterglow percentage\n            , fps: 20 // Frames per second when using setTimeout() as a fallback for CSS\n            , zIndex: 2e9 // The z-index (defaults to 2000000000)\n            , className: 'spinner' // The CSS class to assign to the spinner\n            , top: '48%' // Top position relative to parent\n            , left: '51%' // Left position relative to parent\n            , shadow: true // Whether to render a shadow\n            , hwaccel: false // Whether to use hardware acceleration\n            , position: 'absolute' // Element positioning\n            };\n\n    var spinner = new Spinner(opts);\n\n\n//    $(function () {\n//        var target = document.getElementById('tableid');\n//        var spinner = new Spinner(opts).spin(target);\n//        var domain_id = $('#tableid').attr('data-id');\n//        $.ajax({\n//            dataType:'json',\n//            method: 'get',\n//            url: '/domain/records/',\n//            data:{\n//                'domain_id': domain_id,\n//            },\n//\n//            success: function (data) {\n//                alert(data);\n//\n//                var tableHtml = '';\n//                data.forEach(function(domain) {\n//                     tableHtml += '<tr>' +\n//                        '<th scope=\"row\">'+ domain.name +'</th>' +\n//                        '<td>'+ domain.type +'</td>' +\n//                        '<td>'+ domain.line + '</td>' +\n//                        '<td>'+ domain.value+ '</td>' +\n//                        '<td>' + domain.weight+'</td>' +\n//                        '<td>'+ domain.mx+'</td>' +\n//                        '<td>'+ domain.ttl+'</td>' +\n//                        '<td>'+ domain.updated_on+'</td>' +\n//                    '</tr>';\n//                })\n//                $('tbody').append(tableHtml);\n//                spinner.stop();\n//\n//            },\n//            error: function (data) {\n//                alert(data.responseText);\n//                spinner.stop();\n//\n//            },\n//            complete: function() {\n//\n//            }\n//        })\n//\n//\n//\n//\n//    })\n\n\n\n\n</script>\n{% endblock %}\n\n"
  },
  {
    "path": "templates/saltadmin/key_list.html",
    "content": "{% extends 'base.html' %}\n\n\n{% block content %}\n\n\n<div class=\"container\">\n        <!-- Page-Title -->\n        <div class=\"row\">\n            <div class=\"col-sm-12\">\n                <h4 class=\"page-title\">SALT 管理</h4>\n                <ol class=\"breadcrumb\">\n                    <li>\n                        <a href=\"{% url 'SaltMasterList' %}\">SaltStack Master管理</a>\n                    </li>\n\n                    <li class=\"active\">\n                        SaltStack Master列表\n                    </li>\n                </ol>\n            </div>\n        </div>\n\n        <div class=\"row\">\n             <div class=\"col-sm-10\">\n                   <div class=\"card-box\">\n\n                        <div class=\"row\">\n                            <div class=\"col-sm-12\">\n                                <div class=\"panel-group\" id=\"accordion-test-2\">\n                                    <div class=\"panel panel-default\">\n                                        <div class=\"panel-heading\">\n                                            <h4 class=\"panel-title\">\n                                                <a data-toggle=\"collapse\" data-parent=\"#accordion-test-2\" href=\"#collapseOne-2\" aria-expanded=\"true\" class=\"\">\n                                                    已经接受的Key <span class=\"badge badge-warning\" style=\"margin-top: 0;background-color: #ffbd4a;\">{{Accepted.count}}</span>\n                                                </a>\n                                            </h4>\n                                        </div>\n\n                                        <div id=\"collapseOne-2\" class=\"panel-collapse collapse in\" >\n                                            <div class=\"panel-body\">\n                                                <table class=\"table\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<tr>\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th>Minion</th>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th>saltserver</th>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th>状态</th>\n                                                            <th>操作</th>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<tbody>\n                                                        {% for a in Accepted%}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<tr>\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>{{a.minion}}</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>{{a.saltserver}}</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>{{a.status}}</td>\n                                                            <td>\n\n                                                                <button  class=\"btn btn-xs btn-info\" onclick=\"Update('{{a.minion}}')\" data-toggle=\"modal\" data-target=\"#myModal\">修改</button>\n\n                                                            </td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</tr>\n                                                        {%endfor%}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t\t\t\t\t\t\t</table>\n                                            </div>\n                                        </div>\n                                    </div>\n                                    <div class=\"panel panel-default\">\n                                        <div class=\"panel-heading\">\n                                            <h4 class=\"panel-title\">\n                                                <a data-toggle=\"collapse\" data-parent=\"#accordion-test-2\" href=\"#collapseTwo-2\" class=\"collapsed\" aria-expanded=\"false\">\n                                                    未接受的Key <span class=\"badge badge-warning\" style=\"margin-top: 0;background-color: #34d3eb;\">{{Unaccepted.count}}</span>\n                                                </a>\n                                            </h4>\n                                        </div>\n                                        <div id=\"collapseTwo-2\" class=\"panel-collapse collapse\" aria-expanded=\"false\" style=\"height: 0px;\">\n                                            <div class=\"panel-body\">\n                                                 <table class=\"table\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<tr>\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th>Minion</th>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th>saltserver</th>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th>状态</th>\n                                                            <th>操作</th>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<tbody>\n                                                        {% for a in Unaccepted%}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<tr>\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>{{a.minion}}</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>{{a.saltserver}}</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>{{a.status}}</td>\n                                                            <td>\n                                                                <button  class=\"btn btn-xs btn-info\" onclick=\"Update('{{a.minion}}')\" data-toggle=\"modal\" data-target=\"#myModal\">修改</button>\n\n                                                            </td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</tr>\n                                                        {%endfor%}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t\t\t\t\t\t\t</table>\n                                            </div>\n                                        </div>\n                                    </div>\n\n                                    <div class=\"panel panel-default\">\n                                        <div class=\"panel-heading\">\n                                            <h4 class=\"panel-title\">\n                                                <a data-toggle=\"collapse\" data-parent=\"#accordion-test-2\" href=\"#collapseFive-2\" aria-expanded=\"false\" class=\"collapsed\" >\n                                                   已拒绝的Key <span class=\"badge badge-danger\" style=\"margin-top: 0;background-color: #f05050;\">{{Rejected.count}}</span>\n                                                </a>\n                                            </h4>\n                                        </div>\n\n                                        <div id=\"collapseFive-2\" class=\"panel-collapse collapse\" >\n                                            <div class=\"panel-body\">\n                                                <table class=\"table\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<tr>\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th>Minion</th>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th>saltserver</th>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<th>状态</th>\n                                                            <th>操作</th>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<tbody>\n                                                        {% for a in Rejected%}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<tr>\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>{{a.minion}}</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>{{a.saltserver}}</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>{{a.status}}</td>\n                                                            <td>\n                                                                <button  class=\"btn btn-xs btn-info\" onclick=\"Update('{{a.minion}}')\" data-toggle=\"modal\" data-target=\"#myModal\">修改</button>\n\n                                                            </td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</tr>\n                                                        {%endfor%}\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t\t\t\t\t\t\t</table>\n                                            </div>\n                                        </div>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n\n                       <div id=\"myModal\" class=\"modal fade \" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\" aria-hidden=\"true\" style=\"display: none; padding-right: 17px;\">\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\">×</button>\n                                        <h4 class=\"modal-title\" id=\"myModalLabel\">Key状态修改</h4>\n                                    </div>\n                                    <div class=\"modal-body\">\n                                        <div class=\"form-group\">\n                                            <label for=\"field-1\"  id=\"status\" class=\"control-label\">状态</label>\n                                            {{froms.status}}\n                                        </div>\n                                    </div>\n                                    <div class=\"modal-footer\">\n                                        <button type=\"button\" class=\"btn btn-default waves-effect\" data-dismiss=\"modal\">取消</button>\n                                        <button type=\"button\" class=\"btn btn-primary waves-effect waves-light\" onclick=\"keyChange()\">确认修改</button>\n                                    </div>\n                                </div><!-- /.modal-content -->\n                            </div><!-- /.modal-dialog -->\n                        </div>\n\n                   </div>\n              </div>\n        </div>\n   <script src=\"/static/assets/plugins/custombox/dist/custombox.min.js\"></script>\n    <script src=\"/static/assets/plugins/custombox/dist/legacy.min.js\"></script>\n    <script>\n        function Update(minion) {\n            var Selectminion =document.getElementById(\"myModal\");\n            Selectminion.setAttribute('data-minion',minion);\n        };\n\n        function keyChange(){\n            var nowStatus = $('#id_status').val();\n            var Selectminion =document.getElementById(\"myModal\");\n            $.ajax({\n                method: 'post',\n                url:'{% url 'KeyList' %}',\n                datatype: 'json',\n                data:{\n                    csrfmiddlewaretoken: '{{ csrf_token }}',\n                    status: nowStatus,\n                    minion: Selectminion.getAttribute('data-minion'),\n                },\n                success: function (data) {\n                    if(data == 'OK'){\n                        $('#myModal').modal('hide');\n                        location.href = '{% url 'KeyList' %}';\n                    }\n                },\n                error: function () {\n\n                }\n            });\n        }\n\n    </script>\n\n\n\n{% endblock %}"
  },
  {
    "path": "templates/saltadmin/minion_status.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n<div class=\"container\">\n\n        <!-- Page-Title -->\n        <div class=\"row\">\n            <div class=\"col-sm-12\">\n                <h4 class=\"page-title\">SALT 管理</h4>\n                <ol class=\"breadcrumb\">\n                    <li>\n                        <a href=\"{% url 'SaltMasterList' %}\">Minion 状态管理</a>\n                    </li>\n                    <li class=\"active\">\n                        SaltStack Minion Status 列表\n                    </li>\n                </ol>\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-10\">\n\n                <div class=\"card-box\">\n\n                    <div class=\"row\">\n                        <div class=\"col-sm-12\">\n                            <h4 class=\"m-t-0 header-title\"><b>Minion 列表</b></h4>\n                            <div class=\"p-20\">\n                                <table class=\"table table-striped m-0\">\n                                    <thead>\n                                        <tr>\n                                            <th>#</th>\n                                            <th>Minion</th>\n                                            <th>saltmaster</th>\n                                            <th>UP/Offline</th>\n                                            <th>grains信息</th>\n                                            <th>pillar信息</th>\n\n                                        </tr>\n                                    </thead>\n\n                                    <tbody>\n                                        {% for minion in SaltMinionData%}\n                                        <tr>\n                                            <th scope=\"row\" data-id=\"{{minion.id}}\">{{minion.id}}</th>\n                                            <td>{{minion.minion}}</td>\n                                            <td>{{minion.minion.saltserver}}</td>\n                                            <td>{{minion.minion_status}}</td>\n                                            <td><button class=\"btn btn-xs btn-info\" data-toggle=\"modal\" data-target=\".bs-example-modal-lg\" onclick=\"GetGrainsPillar({{minion.id}},'grains')\" >view</button></td>\n                                            <td><button class=\"btn btn-xs btn-info\" data-toggle=\"modal\" data-target=\".bs-example-modal-lg\" onclick=\"GetGrainsPillar({{minion.id}},'pillar')\" >view</button></td>\n\n                                        </tr>\n                                        {% endfor%}\n                                    </tbody>\n                                </table>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n</div>\n\n\n<div class=\"modal fade bs-example-modal-lg\" id=\"grains\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myLargeModalLabel\" aria-hidden=\"true\" style=\"display: none;\">\n    <div class=\"modal-dialog modal-lg\">\n        <div class=\"modal-content\">\n            <div class=\"modal-header\">\n                <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n                <h4 class=\"modal-title\" >Grains信息</h4>\n            </div>\n\n                <div class=\"modal-body\">\n                    <textarea style=\"OVERFLOW-Y: auto; color:#A6FFA6;  OVERFLOW-X:hidden;background-color: black;width:848px;height: 800px;\" id='grains_data'>None</textarea>\n\n                </div>\n        </div><!-- /.modal-content -->\n    </div><!-- /.modal-dialog -->\n</div><!-- /.modal -->\n\n\n<script src=\"/static/assets/js/json.js\"></script>\n\n<script>\n    function GetGrainsPillar(id,action) {\n        $('#grains').addClass('in').css('display','block');\n        $.getJSON(\"{% url 'SaltMinionGrains' %}\",{minion:id,action:action},function (result) {\n            data=JSON.stringify(result);\n            var grainsvar = document.getElementById('grains_data');\n            grainsvar.value= formatJson(data,true);\n        })\n    }\n\n</script>\n\n\n\n\n{% endblock%}"
  },
  {
    "path": "templates/saltadmin/salt_cmd.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n<link href=\"/static/assets/plugins/bootstrap-select/dist/css/bootstrap-select.min.css\" rel=\"stylesheet\" />\n<link href=\"/static/assets/plugins/select2/select2.css\" rel=\"stylesheet\" type=\"text/css\" />\n<link href=\"/static/assets/plugins/multiselect/css/multi-select.css\"  rel=\"stylesheet\" type=\"text/css\" />\n\n\n<div class=\"container\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <div class=\"card-box\">\n                <h4 class=\"m-t-0 header-title\"><b>批量执行</b></h4>\n                <p class=\"text-muted m-b-30 font-13\">\n                    <strong>可选择以下minion或minion组进行批量命令执行</strong>\n                </p>\n\n                <div class=\"row\">\n\n                   <div class=\"col-md-8\" >\n                        <form class=\"form-horizontal\" role=\"form\" >\n                            {% csrf_token  %}\n                            <div class=\"form-group\">\n                                <label class=\"col-sm-2 control-label\">Minion组</label>\n                                <div class=\"col-sm-10\">\n                                    <div class=\"col-sm-6\">\n                                        <select class=\"form-control\" id=\"minion_group\" name=\"minion_group\">\n                                            <option value=\"\">-----select------</option>\n                                            {% for group in GroupData %}\n                                            <option value=\"{{group.id}}\">{{group.groupname}}</option>\n                                            {% endfor %}\n                                        </select>\n                                    </div>\n                                </div>\n                            </div>\n                            <div class=\"form-group\">\n                                <label class=\"col-sm-2 control-label\">目标主机</label>\n                                <div class=\"col-sm-10\">\n\n                                    <div class=\"col-sm-6\" id=\"HOST\">\n                                          <select class=\"select2 select2-multiple\" multiple=\"multiple\" multiple data-placeholder=\"选择组中的minion\">\n\n                                          </select>\n                                    </div>\n                                </div>\n\n                            </div>\n                            <div class=\"form-group\">\n                                <label class=\"col-sm-2 control-label\">CMD命令</label>\n                                <div class=\"col-sm-10\">\n                                    <div class=\"col-sm-6\">\n                                            <textarea required=\"\" class=\"form-control\" name=\"cmd\" data-parsley-id=\"50\"></textarea>\n                                        </div>\n                                    </div>\n                            </div>\n\n                            <div class=\"form-group\">\n                                <div class=\"col-sm-offset-4 col-sm-8 m-t-15\">\n                                    <button type=\"button\" onclick=\"Exec()\" class=\"btn btn-primary\">\n                                        确认\n                                    </button>\n                                    <button type=\"reset\" class=\"btn btn-default m-l-5\">\n                                        重置\n                                    </button>\n                                </div>\n\t\t\t\t\t\t\t</div>\n                        </form>\n                    </div>\n\n                </div>\n            </div>\n        </div>\n    </div>\n\n     <div class=\"row\">\n         <div class=\"col-sm-12\">\n            <p><b>实时命令结果输出:</b></p>\n\n\t\t </div>\n        <div class=\"col-md-12\">\n            <div class=\"card-box\" id=\"cmd_result\" style=\"OVERFLOW-Y: auto; height:660px;color:#A6FFA6;  OVERFLOW-X:hidden;background-color: black;\">\n\n            </div>\n\n        </div>\n    </div>\n\n\n\n</div>\n\n\n<script src=\"/static/assets/js/json.js\"></script>\n<script type=\"text/javascript\" src=\"/static/assets/plugins/multiselect/js/jquery.multi-select.js\"></script>\n<script src=\"/static/assets/plugins/select2/select2.min.js\" type=\"text/javascript\"></script>\n<script src=\"/static/assets/plugins/bootstrap-select/dist/js/bootstrap-select.min.js\" type=\"text/javascript\"></script>\n\n\n<script>\n\n    var hosts = {{ groupall | safe}};\n\n    jQuery(document).ready(function(){\n        $(\".select2\").select2();\n\n        $('#minion_group').change(function() {\n            var $this = $(this);\n            var destinationHost = [];\n\n            hosts.forEach(function (host) {\n                if($this.val() == host.type) {\n                    destinationHost = host.list;\n                }\n            });\n            var optionsHtml = '';\n            destinationHost.forEach(function(host) {\n                optionsHtml += '<option value=\"'+host.id+'\">'+host.text+'</option>'\n            });\n            var selectHtml = '<select class=\"select2 select2-multiple\" name=\"minion\" multiple=\"multiple\" multiple data-placeholder=\"选择组中的minion\">' +\n                               optionsHtml + '</select>';\n            $('#HOST').html('');\n            $('#HOST').append(selectHtml);\n            $(\".select2\").select2();\n        });\n\n    });\n\n</script>\n\n\n<script>\n    var timer;\n    function Exec(){\n        if($('#minion_group').val() == ''){\n            alert(\"选择Minion组!!!!\");\n\n        };\n\n        $.ajax({\n            method: 'post',\n            dataType:'json',\n            data:$('.form-horizontal').serialize(),\n            url: \"{% url 'RemoteCmd' %}\",\n            success: function (data) {\n                var jid = data.jid;\n                var minion = data.minion;\n                var savelogid = data.savelogid;\n                document.getElementById(\"cmd_result\").innerHTML='命令正在执行......</br>';\n                //timer = setInterval(function() {\n                cmd_result(jid,minion,savelogid);\n                //},5000);\n            },\n            error: function () {\n\n            }\n        })\n    }\n\n    function cmd_result(jid,minion,savelogid) {\n        $.ajax({\n            method: 'get',\n            dataType: 'json',\n            data: {\n                'minion':minion,\n                'savelogid':savelogid,\n            },\n            url: \"/salt/cmdresult/\" + jid,\n            \n            success: function (data) {\n                console.log(data);\n\n                //clearInterval(timer);\n                //获取minion信息然后作遍历查询\n                var minions = data.minion.split(',')\n                var objresult = document.getElementById(\"cmd_result\");\n                for (var v=0;v<minions.length;v++){\n\n                    results_html ='</br>'+minions[v]+'</br>';\n                    results_html += new Array(80).join(\"#\") + '</br>';\n\n                    var result = data.resultdata[minions[v]];\n\n                    if (typeof(result) == 'undefined'){\n\n                        results_html += \"\\t\" + 'None';\n                        objresult.innerHTML += results_html;\n\n                    }else{\n                        var newResult = result.split('\\n');\n                        for (var i=0;i<newResult.length; i++){\n                            NewResult = newResult[i] + '</br>';\n                            results_html +=(NewResult.replace(/\\s+/g,\"\\t\\t\\t\"));\n                            //cmd_result.text= formatJson(data,true);\n                        };\n                        objresult.innerHTML += results_html;\n                    }\n\n                }\n            },\n            error: function () {\n            }\n        })\n\n    }\n\n\n</script>\n\n\n\n\n{% endblock %}"
  },
  {
    "path": "templates/saltadmin/saltjob_detail.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n<div class=\"container\">\n    <div class=\"row\">\n         <div class=\"col-sm-12\">\n            <p><b>Job 执行结果详细信息:</b></p>\n\n\t\t </div>\n        <div class=\"col-md-12\">\n            <div class=\"card-box\" id=\"result\" style=\"OVERFLOW-Y: auto; OVERFLOW-X:hidden;background-color: #1c1c1c;height: 600px\">\n\n            </div>\n        </div>\n    </div>\n</div>\n\n\n{% endblock %}"
  },
  {
    "path": "templates/saltadmin/saltjob_list.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n<div class=\"container\">\n\n        <!-- Page-Title -->\n        <div class=\"row\">\n            <div class=\"col-sm-12\">\n                <h4 class=\"page-title\">SALT 管理</h4>\n                <ol class=\"breadcrumb\">\n                    <li>\n                        <a href=\"{% url 'JobList'  1 %}\">Job 管理</a>\n                    </li>\n                    <li class=\"active\">\n                        SaltStack Jobs 列表\n                    </li>\n                </ol>\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-10\">\n                <div class=\"card-box\">\n                    <div class=\"row\">\n                        <div class=\"col-sm-12\">\n                            <h4 class=\"m-t-0 header-title\"><b>Jobs 列表</b></h4>\n\n                                <table class=\"table table-striped m-0\">\n                                    <thead>\n                                        <tr>\n\n                                            <th>jid</th>\n                                            <th>arg</th>\n                                            <th>执行模块</th>\n                                            <th>开始时间</th>\n                                            <th>target</th>\n                                            <th>用户</th>\n                                            <th>Master</th>\n                                        </tr>\n                                    </thead>\n                                    <tbody>\n                                        {% for i in SaltMaster_data %}\n                                        <tr>\n                                            <th scope=\"row\"><button class=\"btn btn-xs btn-info\" data-toggle=\"modal\" data-target=\".bs-example-modal-lg\" onclick=\"GetJobDetail('{{i.jid}}')\" >{{i.jid}}</button></th>\n                                            <td>\n                                                {{i.args}}\n                                            </td>\n                                            <td>{{i.function}}</td>\n                                            <td>{{i.startTime}}</td>\n                                            <td>\n                                                {{i.target}}\n                                            </td>\n                                            <td>{{i.user}}</td>\n                                            <td>{{i.saltserver}}</td>\n                                        </tr>\n                                        {% endfor %}\n                                    </tbody>\n                                </table>\n\n\n                                <nav>\n                                    <ul class=\"pagination\" >\n                                        {{page}}\n                                    </ul>\n                                </nav>\n\n\n\n\n                        </div>\n\n                    </div>\n                </div>\n            </div>\n        </div>\n\n\n<div class=\"modal fade bs-example-modal-lg\" id=\"jobDetail\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myLargeModalLabel\" aria-hidden=\"true\" style=\"display: none;\">\n    <div class=\"modal-dialog modal-lg\">\n        <div class=\"modal-content\">\n            <div class=\"modal-header\">\n                <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n                <h4 class=\"modal-title\" >Job信息</h4>\n            </div>\n\n                <div class=\"modal-body\">\n                    <textarea style=\"OVERFLOW-Y: auto; color:#A6FFA6;  OVERFLOW-X:hidden;background-color: black;width:848px;height: 800px;\" id='jobdata'>正在获取Job信息</textarea>\n\n                </div>\n        </div><!-- /.modal-content -->\n    </div><!-- /.modal-dialog -->\n</div><!-- /.modal -->\n    <script src=\"/static/assets/js/json.js\"></script>\n\n<script>\n    function GetJobDetail(id) {\n        $('#jobDetail').addClass('in').css('display','block');\n        $.getJSON(\"{% url 'jobdetail' %}\",{jid:id},function (result) {\n            data=JSON.stringify(result);\n            var jobvar = document.getElementById('jobdata');\n            jobvar.value= formatJson(data,true);\n        })\n    }\n</script>\n\n</div>\n{% endblock%}"
  },
  {
    "path": "templates/saltadmin/saltmaster_list.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n<div class=\"container\">\n\n        <!-- Page-Title -->\n        <div class=\"row\">\n            <div class=\"col-sm-12\">\n                <h4 class=\"page-title\">SALT 管理</h4>\n                <ol class=\"breadcrumb\">\n                    <li>\n                        <a href=\"{% url 'SaltMasterList' %}\">SaltStack Master管理</a>\n                    </li>\n\n                    <li class=\"active\">\n                        SaltStack Master列表\n                    </li>\n                </ol>\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-10\">\n                <div class=\"row\">\n                        <div class=\"col-sm-12\">\n                           <button class=\"btn btn-primary waves-effect waves-light\" data-toggle=\"modal\" data-target=\"#con-close-modal\">添加Master</button>\n                        </div>\n                    </div>\n                <br>\n                <div class=\"card-box\">\n\n                    <div class=\"row\">\n                        <div class=\"col-sm-12\">\n                            <h4 class=\"m-t-0 header-title\"><b>Master列表</b></h4>\n                            <div class=\"p-20\">\n                                <table class=\"table table-striped m-0\">\n                                    <thead>\n                                        <tr>\n                                            <th>#</th>\n                                            <th>url</th>\n                                            <th>用户名</th>\n                                            <th>角色</th>\n                                            <td>操作</td>\n                                        </tr>\n                                    </thead>\n                                    <tbody>\n                                        {% for salt in SaltMasterData%}\n                                        <tr>\n                                            <th scope=\"row\" data-id=\"{{salt.id}}\">{{salt.id}}</th>\n                                            <td>{{salt.url}}</td>\n                                            <td>{{salt.username}}</td>\n                                            <td>{{salt.role}}</td>\n                                             <td>\n                                                 <button    onclick=\"ModifyHost({{salt.id}})\" class=\"btn btn-xs btn-info\">修改</button>\n                                                 <button  class=\"btn btn-xs btn-danger\" onclick=\"DeleteMaster({{salt.id}})\" >删除</button>\n                                             </td>\n                                        </tr>\n                                        {% endfor%}\n                                    </tbody>\n                                </table>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n</div>\n\n\n <div id=\"con-close-modal\" class=\"modal fade\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\" aria-hidden=\"true\" style=\"display: none;\">\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\">×</button>\n                <h4 class=\"modal-title\">添加Master</h4>\n            </div>\n            <form role=\"form\" method=\"POST\">\n                {% csrf_token  %}\n            <div class=\"modal-body\">\n                <div class=\"row\">\n                    <div class=\"col-md-12\">\n                        <div class=\"form-group\">\n                            <label for=\"field-3\" class=\"control-label\">URL</label>\n                            {{form.url}}\n                            {{form.url.errors}}\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"row\">\n                        <div class=\"col-md-6\">\n                            <div class=\"form-group\">\n                                <label for=\"field-1\" class=\"control-label\">用户名</label>\n                                {{form.username}}\n                                {{form.username.errors}}\n                            </div>\n                        </div>\n\n                        <div class=\"col-md-6\">\n                            <div class=\"form-group\">\n                                <label for=\"field-2\" class=\"control-label\">密码</label>\n                               {{form.password}}\n                                {{form.password.errors}}\n                            </div>\n                        </div>\n                    </div>\n\n                <div class=\"row\">\n                    <div class=\"col-md-12\">\n                        <div class=\"form-group\">\n                            <label for=\"field-3\" class=\"control-label\">角色</label>\n                             {{form.role}}\n                             {{form.role.errors}}\n                        </div>\n                    </div>\n                </div>\n\n            </div>\n            <div class=\"modal-footer\">\n                <button type=\"button\" class=\"btn btn-default waves-effect\" data-dismiss=\"modal\">取消</button>\n                <button type=\"submit\"  class=\"btn btn-info waves-effect waves-light\">添加</button>\n            </div>\n            </form>\n        </div>\n    </div>\n</div><!-- /.modal -->\n\n\n<div id=\"con-update-modal\" class=\"modal fade\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\" aria-hidden=\"true\" style=\"display: none;\">\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\">×</button>\n                <h4 class=\"modal-title\">修改Master</h4>\n            </div>\n            <div class=\"modal-body\">\n\n                <div class=\"row\">\n                    <div class=\"col-md-12\">\n                        <div class=\"form-group\">\n                            <label for=\"field-3\" class=\"control-label\">URL</label>\n                            <input type=\"text\" class=\"form-control\" id=\"url\" value=\"\" placeholder=\"http://127.0.0.1\">\n                        </div>\n                    </div>\n                </div>\n                <div class=\"row\">\n                        <div class=\"col-md-6\">\n                            <div class=\"form-group\">\n                                <label for=\"field-1\" class=\"control-label\">用户名</label>\n                                <input type=\"text\" class=\"form-control\" id=\"username\" value=\"\" placeholder=\"username\">\n                            </div>\n                        </div>\n                        <div class=\"col-md-6\">\n                            <div class=\"form-group\">\n                                <label for=\"field-2\" class=\"control-label\">密码</label>\n                                <input type=\"password\" class=\"form-control\" id=\"password\" value=\"\" placeholder=\"password\">\n                            </div>\n                        </div>\n                    </div>\n                <div class=\"row\">\n                    <div class=\"col-md-12\">\n                        <div class=\"form-group\">\n                            <label for=\"field-3\" class=\"control-label\">角色</label>\n\n                           <select class=\"form-control\" id=\"role\" name=\"role\">\n                               {% for r in Role%}\n                                <option value=\"{{r.0}}\" selected=\"selected\">{{r.1}}</option>\n                               {% endfor %}\n                           </select>\n                        </div>\n                    </div>\n                </div>\n            </div>\n\n            <div class=\"modal-footer\">\n                <button type=\"button\" class=\"btn btn-default waves-effect\" data-dismiss=\"modal\">取消</button>\n                <button type=\"button\" class=\"btn btn-info waves-effect \" id=\"update\" data-aa=\"\" onclick=\"postMaster()\">修改</button>\n            </div>\n\n        </div>\n    </div>\n</div><!-- /.modal -->\n\n\n<script>\n    function DeleteMaster(e) {\n        var iddd = e;\n        $.ajax({\n            url: '/salt/master/delete/' + iddd,\n            type: 'get',\n            dataType:'json',\n            success: function (data) {\n\n                $.Notification.autoHideNotify('success','top right','系统通知', data.msginfo);\n                setTimeout(function() {\n                                   location.href = '{% url 'SaltMasterList'  %}';\n                              },2500);\n\n            },\n            error: function () {\n\n            },\n\n        })\n    }\n\n    function postMaster(){\n        $.ajax({\n            url: '/salt/master/change/' + id,\n            type: 'POST',\n            dataType: 'json',\n            data:{\n                csrfmiddlewaretoken: '{{ csrf_token }}',\n                url: document.getElementById('url').value,\n                username: document.getElementById('username').value,\n                password: document.getElementById('password').value,\n                role: document.getElementById('role').value,\n            },\n            success: function (data) {\n\n                $('#con-update-modal').modal('hide');\n                  setTimeout(function() {\n                                   location.href = '{% url 'SaltMasterList'  %}';\n                              },2500);\n            },\n            error: function () {\n\n            }\n\n        })\n    }\n    // 全局id\n    var id = '';\n    function ModifyHost(e) {\n        $.ajax({\n            url: '/salt/master/change/' + e,\n            type: 'GET',\n            dataType:'json',\n            success: function (data) {\n                document.getElementById('url').value = data.url;\n                document.getElementById('username').value = data.username;\n                document.getElementById('password').value = data.password;\n                document.getElementById('role').value = data.role;\n                id = e;\n                $('#con-update-modal').modal('show');\n                \n            },\n            error: function () {\n                \n            }\n\n        })\n\n    }\n</script>\n\n\n\n{% endblock%}"
  },
  {
    "path": "templates/saltadmin/saltmodule_deploy.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n<link href=\"/static/assets/plugins/bootstrap-select/dist/css/bootstrap-select.min.css\" rel=\"stylesheet\" />\n<link href=\"/static/assets/plugins/select2/select2.css\" rel=\"stylesheet\" type=\"text/css\" />\n<link href=\"/static/assets/plugins/multiselect/css/multi-select.css\"  rel=\"stylesheet\" type=\"text/css\" />\n\n<div class=\"container\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <div class=\"card-box\">\n                <h4 class=\"m-t-0 header-title\"><b>模块部署</b></h4>\n                <p class=\"text-muted m-b-30 font-13\">\n                    <strong>以下是可提供的saltstack sls 模块部署列表，部署结果实时展示</strong>\n                </p>\n\n                <div class=\"row\">\n\n                   <div class=\"col-md-8\" >\n                        <form class=\"form-horizontal\" role=\"form\" method=\"post\">\n                            {% csrf_token %}\n                            <div class=\"form-group\">\n                                <label class=\"col-sm-2 control-label\">Minion组</label>\n                                <div class=\"col-sm-10\">\n                                    <div class=\"col-sm-6\">\n                                        <select class=\"form-control\" id=\"minion_group\" name=\"minion_group\">\n                                            <option value=\"\">-----select------</option>\n                                            {% for group in GroupData %}\n                                            <option value=\"{{group.id}}\">{{group.groupname}}</option>\n                                            {% endfor %}\n                                        </select>\n                                    </div>\n                                </div>\n                            </div>\n                            <div class=\"form-group\">\n                                <label class=\"col-sm-2 control-label\">目标主机</label>\n                                <div class=\"col-sm-10\">\n\n                                    <div class=\"col-sm-6\" id=\"HOST\">\n                                          <select class=\"select2 select2-multiple\" multiple=\"multiple\" multiple data-placeholder=\"选择组中的minion\">\n\n                                          </select>\n                                    </div>\n                                </div>\n\n                            </div>\n                            <div class=\"form-group\">\n                                <label class=\"col-sm-2 control-label\">Saltenv</label>\n                                <div class=\"col-sm-10\">\n                                    <div class=\"col-sm-6\">\n                                        <input type=\"text\" class=\"form-control\" name=\"env\" placeholder=\"prod\" >\n                                    </div>\n                                </div>\n                            </div>\n                            <div class=\"form-group\">\n                                <label class=\"col-sm-2 control-label\">软件列表</label>\n                                <div class=\"col-sm-10\">\n                                    {% for i in SoftModuleData %}\n                                    <div class=\"col-sm-2\">\n                                        <div class=\"checkbox checkbox-pink\">\n                                            <input id=\"checkbox{{i.id}}\" name=\"software\" value=\"{{i.models_site}}\" type=\"checkbox\" data-parsley-multiple=\"groups\" data-parsley-mincheck=\"2\" data-parsley-id=\"69\">\n                                            <label for=\"checkbox{{i.id}}\"> {{i.name}} </label>\n                                        </div>\n                                    </div>\n                                    {% endfor %}\n                                </div>\n                            </div>\n                            <div class=\"form-group\">\n                                <div class=\"col-sm-offset-4 col-sm-8 m-t-15\">\n                                    <button type=\"button\" onclick=\"Exec()\" class=\"btn btn-primary\">\n                                        部署\n                                    </button>\n                                    <button type=\"reset\" class=\"btn btn-default m-l-5\">\n                                        重置\n                                    </button>\n                                </div>\n\t\t\t\t\t\t\t</div>\n                        </form>\n                    </div>\n\n                </div>\n            </div>\n        </div>\n    </div>\n\n     <div class=\"row\">\n         <div class=\"col-sm-12\">\n            <p><b>实时结果输出:</b></p>\n\t\t </div>\n        <div class=\"col-md-9\">\n            <div class=\"card-box\" id=\"result\" style=\"OVERFLOW-Y: auto;color: #00af00;  OVERFLOW-X:hidden;background-color: #1c1c1c;height: 600px\">\n\n            </div>\n        </div>\n\n          <div class=\"col-md-3\">\n            <div class=\"card-box\"  style=\"OVERFLOW-Y: auto;color: white;  OVERFLOW-X:hidden;background-color: #1c1c1c;height: 600px\">\n                <p>结果输出:</p>\n                <div id=\"success\" style=\"color: #00af00\">\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n\n\n<script type=\"text/javascript\" src=\"/static/assets/plugins/multiselect/js/jquery.multi-select.js\"></script>\n<script src=\"/static/assets/plugins/select2/select2.min.js\" type=\"text/javascript\"></script>\n<script src=\"/static/assets/plugins/bootstrap-select/dist/js/bootstrap-select.min.js\" type=\"text/javascript\"></script>\n\n\n<script>\n\n    var hosts = {{ groupall | safe}};\n\n    jQuery(document).ready(function(){\n        $(\".select2\").select2();\n\n        $('#minion_group').change(function() {\n            var $this = $(this);\n            var destinationHost = [];\n\n            hosts.forEach(function (host) {\n                if($this.val() == host.type) {\n                    destinationHost = host.list;\n                }\n            });\n            var optionsHtml = '';\n            destinationHost.forEach(function(host) {\n                optionsHtml += '<option value=\"'+host.id+'\">'+host.text+'</option>'\n            });\n            var selectHtml = '<select class=\"select2 select2-multiple\" name=\"minion\" multiple=\"multiple\" multiple data-placeholder=\"选择组中的minion\">' +\n                               optionsHtml + '</select>';\n            $('#HOST').html('');\n            $('#HOST').append(selectHtml);\n            $(\".select2\").select2();\n        });\n\n    });\n\n</script>\n\n<script>\n    var timer;\n    function Exec(){\n        if($('#minion_group').val() == ''){\n            alert(\"选择Minion组!!!!\");\n\n        };\n\n        $.ajax({\n            method: 'post',\n            dataType:'json',\n            data:$('.form-horizontal').serialize(),\n            url: \"{% url 'SoftInstall' %}\",\n            success: function (data) {\n                var jid = data.jid;\n                var minion = data.minion;\n                var savelogid = data.savelogid;\n                document.getElementById(\"result\").innerHTML='正在部署软件模块......</br>';\n                //timer = setInterval(function() {\n                cmd_result(jid,minion,savelogid);\n                //},5000);\n            },\n            error: function () {\n\n            }\n        })\n    }\n\n    function cmd_result(jid,minion,savelogid) {\n        $.ajax({\n            method: 'get',\n            dataType: 'json',\n            data: {\n                'minion':minion,\n                'savelogid':savelogid,\n            },\n            url: \"/salt/deployresult/\" + jid,\n\n            success: function (data) {\n                var dataHtml = '';\n                var ResultHtml= '';\n\n                data.resultdata.forEach(function(resultdata) {\n\n                    dataHtml += '<br/><br/>' + resultdata.url + ':<br/>';\n                    ResultHtml += '<br/>' + resultdata.url + ':<br/>';\n                    ResultHtml += new Array(50).join(\"-\") + '</br>';\n                    ResultHtml += 'Succeeded:' + resultdata.success + '<br/>';\n                    ResultHtml += '<p style=\"color: red;\">Failed:' + resultdata.error + '</p>';\n                    ResultHtml += new Array(50).join(\"-\") + '</br>';\n\n                    resultdata.result.forEach(function(result) {\n\n                        dataHtml += new Array(100).join(\"-\") + '</br>';\n\n                        if (result.Result== false){\n                            dataHtml += '<p style=\"color: red\">'\n\n                        }\n\n                        for(var k in result){\n\n                            if(k === 'Changes') {\n                                dataHtml += k + ':\\t' + JSON.stringify(result[k]) + '<br/>';\n                            } else {\n                                dataHtml += k + ':\\t' + result[k] + '<br/>';\n                            }\n\n                        }\n\n                        if (result.Result== false){\n                            dataHtml += '</p>'\n\n                        }\n\n                    });\n                });\n                $('#result').html(dataHtml);\n                $('#success').html(ResultHtml);\n\n\n//                dataResult.forEach(function(result) {\n//\n//                    resultHtml += '<p style=\"color: #2b542c;font-size: 18px\">' + result + ':</p>';\n//\n//                    data.resultdata[result].forEach(function(resultdata) {\n//\n//                        resultHtml += new Array(100).join(\"-\") + '</br>';\n//\n//                        for(var k in data.resultdata[result][resultdata]) {\n//\n//\n//                            resultHtml += '<p>' + k + ':\\t' + data.resultdata[result][resultdata][k] + '</p><br/>';\n//                        }\n//                    })\n//                });\n\n            },\n            error: function () {\n            }\n        })\n\n    }\n\n\n</script>\n\n{% endblock %}"
  },
  {
    "path": "templates/servermanager/assets_list.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n\n<link href=\"/static/assets/plugins/datatables/jquery.dataTables.min.css\" rel=\"stylesheet\" type=\"text/css\">\n<link href=\"/static/assets/plugins/bootstrap-table/dist/bootstrap-table.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n\n\n<div class=\"container\">\n   <!-- Page-Title -->\n    <div class=\"row \">\n            <div class=\"col-sm-12\">\n                <h4 class=\"page-title\">资产列表</h4>\n                <ol class=\"breadcrumb\">\n                    <li>\n                        <a href=\"#\">资产管理</a>\n                    </li>\n                    <li class=\"active\">\n                        <a href=\"{% url 'AssetsLists' 1 %}\">资产列表</a>\n                    </li>\n                </ol>\n            </div>\n            <div class=\"row\">\n                <div class=\"col-sm-12\">\n                    <div class=\"card-box\">\n                        <div class=\"row\">\n                            <div class=\"col-sm-12\">\n                                <h4 class=\"m-t-0 header-title\"><b>Simpletour资产列表</b></h4>\n                                <p class=\"text-muted font-13\">\n                                    资产详细情况请点击资产ID\n                                </p>\n                            </div>\n                            <div>\n                                <div class=\"col-sm-8\">\n                                </div>\n                                <div class=\"col-sm-4\">\n                                    <form method=\"post\" action=\"{% url 'AssetsLists' 1 %}\">\n                                        {% csrf_token  %}\n                                        <div class=\"input-group\">\n                                            <input type=\"text\" id=\"search\" name=\"search\" class=\"form-control\" placeholder=\"输入资产编号或设备名\">\n                                            <span class=\"input-group-btn\">\n                                            <button type=\"submit\" class=\"btn waves-effect waves-light btn-primary\"  ><i class=\"fa fa-search\"></i></button>\n                                            </span>\n                                        </div>\n                                    </form>\n                                 </div>\n                            </div>\n                            <div class=\"col-sm-12\">\n                                <br>\n                                <div class=\"bootstrap-table\">\n                                    <div class=\"table-responsive\">\n                                        <table class=\"table-bordered\" data-page-size=\"5\" data-toggle=\"table\" >\n                                            <thead>\n                                                <tr>\n                                                    <th>资产编号</th>\n                                                    <th>设备名</th>\n                                                    <th>IDC</th>\n                                                    <th>设备类型</th>\n                                                    <th>业务名</th>\n                                                    <th>设备状态</th>\n                                                    <th data-sortable=\"true\">资产价格(￥)</th>\n                                                    <th>购买时间</th>\n                                                    <th>操作</th>\n                                                </tr>\n                                            </thead>\n                                            <tbody>\n\n                                            {% for asset in Assetsdata %}\n                                                <tr>\n                                                    <td><a href=\"{% url 'AssetsDetail' asset.id %}\">{{asset.device_number}}</a></td>\n                                                    <td>{{asset.host_name}}</td>\n                                                    <td>{{asset.IDC}}</td>\n                                                    <td>{{asset.device_type}}</td>\n                                                    <td>{{asset.business}}</td>\n                                                    {% for i in asset.status_choice %}\n                                                        {% if asset.status == i.0 %}\n                                                                <td>{{i.1}}</td>\n                                                        {%endif%}\n                                                    {%endfor%}\n                                                    <td>{{asset.price}}</td>\n                                                    <td>{{asset.buy_time}}</td>\n\n                                                    <td>\n                                                        <button  class=\"btn btn-xs btn-primary\" onclick=\"Assets_delete({{asset.id}})\">删除</button>\n                                                        <a  href=\"{% url 'ChangeAsset' asset.id %}\" class=\"btn btn-xs btn-info\">修改</a>\n                                                    </td>\n                                                </tr>\n                                            {% endfor%}\n                                            </tbody>\n                                        </table>\n                                        <nav>\n                                            <ul class=\"pagination\" >\n                                                {{page}}\n                                            </ul>\n                                        </nav>\n                                    </div>\n                                </div>\n\n                            </div>\n                        </div>\n\n\n            </div>\n        </div>\n    </div>\n    </div>\n</div>\n\n<script type=\"text/javascript\">\n    function Assets_delete(assetid){\n        $.ajax({\n            method: \"GET\",\n            url:\"/server/assets/delete/\" + assetid,\n            dataType: 'json',\n            success:function(result){\n                var msginfo=result.msginfo;\n                var msgerror=result.msgerror;\n                if(msginfo){\n                    $.Notification.autoHideNotify('success','top right','系统通知', msginfo);\n                    setTimeout(function() {\n                          location.href = '{% url 'AssetsLists' 1 %}';\n                     },2500);\n\n                }else{\n                    $.Notification.autoHideNotify('error', 'top right', '系统通知',msgerror);\n\n                }\n\n            },\n            error:function(e){\n                alert(e);\n\n            }\n\n        });\n    }\n\n\n    function search(){\n        var searchdata = document.getElementById(\"search\").value;\n        $.ajax({\n            method:'POST',\n            url:\"{% url 'AssetsLists' 1 %}\",\n            dataType: 'json',\n            data:{\n               searchdata:searchdata,\n               csrfmiddlewaretoken:'{{ csrf_token  }}',\n            },\n            success:function(result){\n                location.reload();\n            },\n            error:function(){\n            }\n        });\n    }\n\n\n</script>\n\n\n{% endblock %}"
  },
  {
    "path": "templates/servermanager/assetschange.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n    <!-- Plugins css-->\n    <link href=\"/static/assets/plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\">\n    <link href=\"/static/assets/plugins/bootstrap-select/dist/css/bootstrap-select.min.css\" rel=\"stylesheet\" />\n    <link href=\"/static/assets/plugins/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.css\" rel=\"stylesheet\" />\n    <link href=\"/static/assets/plugins/summernote/dist/summernote.css\" rel=\"stylesheet\" />\n\n    <div class=\"container\">\n        <!-- Page-Title -->\n        <div class=\"row\">\n            <div class=\"col-sm-12\">\n                <h4 class=\"page-title\">资产管理</h4>\n                <ol class=\"breadcrumb\">\n                    <li>\n                        <a href=\"#\">资产管理</a>\n                    </li>\n                    <li>\n                        <a href=\"#\">资产表管理</a>\n                    </li>\n                    <li class=\"active\">\n                        资产修改\n                    </li>\n                </ol>\n            </div>\n        </div>\n\n        <form class=\"form-horizontal\" role=\"form\">\n\n            {% csrf_token  %}\n            <!-- 基本信息 -->\n            <div class=\"row\">\n                <div class=\"col-sm-8\">\n                    <div class=\"card-box\">\n                        <h4 class=\"m-t-0 header-title\"><b>基本信息：</b></h4>\n                        <div class=\"row\">\n                            <div class=\"col-md-6\">\n                                <div class=\"form-group\">\n                                    <label class=\"col-md-3 control-label\">资产编号</label>\n                                    <div class=\"col-md-9\">\n                                        <input type=\"text\" class=\"form-control\" name=\"device_number\" value=\"{{AssetsData.device_number}}\">\n                                    </div>\n                                </div>\n                                <div class=\"form-group\">\n                                    <label class=\"col-md-3 control-label\">IDC</label>\n                                    <div class=\"col-md-9\">\n                                        <select class=\"selectpicker show-tick\" data-style=\"btn-white\" name=\"idc\">\n                                            {% for idc in IdcData%}\n                                                {% if AssetsData.IDC.id == idc.id %}\n                                                    <option value=\"{{idc.id}}\" selected>{{idc.idc_name}}</option>\n                                                {%else%}\n                                                    <option value=\"{{idc.id}}\" >{{idc.idc_name}}</option>\n                                                {%endif%}\n                                            {% endfor%}\n                                        </select>\n                                    </div>\n                                </div>\n\n                                <div class=\"form-group\">\n                                    <label class=\"col-md-3 control-label\">业务名</label>\n                                    <div class=\"col-md-9\">\n                                        <select class=\"selectpicker show-tick\" data-style=\"btn-white\" name=\"business\">\n                                            {% for bus in BusinessData%}\n                                                {% if AssetsData.business.id == bus.id %}\n                                                    <option value=\"{{bus.id}}\" selected>{{bus.name}}</option>\n                                                {%else%}\n                                                    <option value=\"{{bus.id}}\">{{bus.name}}</option>\n                                                {%endif%}\n                                            {% endfor%}\n                                        </select>\n                                    </div>\n                                </div>\n                                <div class=\"form-group\">\n                                    <label class=\"col-md-3 control-label\">资产状态</label>\n                                    <div class=\"col-md-9\">\n                                        <select class=\"selectpicker show-tick\" data-style=\"btn-white\" name=\"status\">\n                                            {% for status in AssetsData.status_choice%}\n                                                {% if AssetsData.status == status.0 %}\n                                                    <option value=\"{{status.0}}\" selected>{{status.1}}</option>\n                                                {%else%}\n                                                    <option value=\"{{status.0}}\">{{status.1}}</option>\n                                                {%endif%}\n                                            {%endfor%}\n                                        </select>\n                                    </div>\n                                </div>\n                            </div>\n\n                            <div class=\"col-md-6\">\n                                <div class=\"form-group\">\n                                    <label class=\"col-md-2 control-label\">设备名</label>\n                                    <div class=\"col-md-10\">\n                                        <input type=\"text\" class=\"form-control\" name=\"host_name\" value=\"{{AssetsData.host_name}}\">\n                                    </div>\n                                </div>\n                                <div class=\"form-group\">\n                                    <label class=\"col-md-2 control-label\">设备类型</label>\n                                    <div class=\"col-md-10\">\n                                        <select class=\"selectpicker show-tick\" data-style=\"btn-white\" name=\"device_type\">\n                                            {% for type in DeviceTypeData%}\n                                                {% if AssetsData.device_type.id == type.id %}\n                                                    <option value=\"{{type.id}}\" selected>{{type.name}}</option>\n                                                {%else%}\n                                                    <option value=\"{{type.id}}\">{{type.name}}</option>\n                                                {%endif%}\n                                            {%endfor%}\n                                        </select>\n                                    </div>\n                                </div>\n\n                                <div class=\"form-group\">\n                                    <label class=\"col-sm-2 control-label\">购买方式</label>\n                                    <div class=\"col-md-10\">\n                                        <select class=\"selectpicker show-tick\" data-style=\"btn-white\" name=\"buy_type\">\n                                            {% for buy in AssetsData.buy_type_choice%}\n                                                {%if AssetsData.buy_type == buy.0 %}\n                                                    <option value=\"{{buy.0}}\" selected>{{buy.1}}</option>\n                                                {%else%}\n                                                    <option value=\"{{buy.0}}\">{{buy.1}}</option>\n                                                {%endif%}\n                                            {%endfor%}\n                                        </select>\n                                    </div>\n                                </div>\n\n                                <div class=\"form-group\">\n                                    <label class=\"col-sm-2 control-label\">购买价格</label>\n                                    <div class=\"col-md-10\">\n                                        <input type=\"text\" class=\"form-control\"  name=\"price\" value=\"{{AssetsData.price}}\">\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n\n            <!-- 其它信息： -->\n            <div class=\"row\">\n                <div class=\"col-sm-8\">\n                    <div class=\"card-box\">\n                        <h4 class=\"m-t-0 header-title\"><b>其它信息：</b></h4>\n                        <div class=\"row\">\n                            <div class=\"col-md-6\">\n                                <div class=\"form-group\">\n                                    <label class=\"col-md-3 control-label\">保修期</label>\n                                    <div class=\"col-md-9\">\n                                        <input type=\"text\" class=\"form-control\" value=\"{{AssetsData.Warranty}}\" name=\"Warranty\">\n                                    </div>\n                                </div>\n                             \t<div class=\"form-group\">\n                                <label class=\"control-label col-sm-3\">购买时间</label>\n                                <div class=\"col-sm-9\">\n                                    <div class=\"input-group\">\n                                        <input type=\"text\" class=\"form-control\" placeholder=\"yyyy/mm/dd\" value=\"{{AssetsData.buy_time}}\" name=\"buytime\" id=\"datepicker-autoclose\">\n                                        <span class=\"input-group-addon bg-custom b-0 text-white\"><i class=\"icon-calender\"></i></span>\n                                    </div><!-- input-group -->\n                                </div>\n                            </div>\n                                <div class=\"form-group\">\n                                    <label class=\"col-md-3 control-label\">使用时间范围</label>\n                                    <div class=\"col-sm-9\">\n                                        <div class=\"input-daterange input-group\" id=\"date-range\">\n                                            <input type=\"text\" class=\"form-control\" value=\"{{AssetsData.suse_time| date:'Y-m-d'}}\" name=\"start\">\n                                            <span class=\"input-group-addon bg-custom b-0 text-white\">至</span>\n                                            <input type=\"text\" class=\"form-control\"  value=\"{{AssetsData.euse_time|date:'Y-m-d'}}\" name=\"end\">\n                                        </div>\n                                    </div>\n                                </div>\n                                <div class=\"form-group\">\n                                    <label class=\"col-md-3 control-label\">管理员邮箱</label>\n                                    <div class=\"col-md-9\">\n                                        <select class=\"selectpicker show-tick\" data-style=\"btn-white\" name=\"admin\">\n                                            {% for user in AdminUser%}\n                                                {% if AssetsData.admin.id == user.id %}\n                                                    <option value=\"{{user.id}}\" selected>{{user}}</option>\n                                                {%else%}\n                                                    <option value=\"{{user.id}}\">{{user}}</option>\n                                                {%endif%}\n                                            {%endfor%}\n                                        </select>\n                                    </div>\n                                </div>\n\n\n                                  <div class=\"form-group\">\n                                    <label class=\"col-md-3 control-label\">提供商</label>\n                                    <div class=\"col-md-9\">\n                                        <select class=\"selectpicker show-tick\" data-style=\"btn-white\" name=\"provider\">\n                                            {% for pr in ProviderData %}\n                                                {% if AssetsData.provider.id == pr.id %}\n                                                    <option value=\"{{pr.id}}\" selected>{{pr}}</option>\n                                                {%else%}\n                                                    <option value=\"{{pr.id}}\">{{pr}}</option>\n                                                {%endif%}\n                                            {%endfor%}\n                                        </select>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n\n            <!-- 文本域 -->\n            <div class=\"row\">\n                <div class=\"col-sm-8\">\n                    <div class=\"card-box\">\n                        <h4 class=\"m-b-30 m-t-0 header-title\"><b>备注</b></h4>\n                        <div class=\"summernote\">\n                            <h4></h4>\n                        </div>\n                    </div>\n                </div>\n            </div>\n\n            <!-- 提交按钮 -->\n            <div class=\"row\">\n                <div class=\"col-sm-8\">\n                    <div class=\"form-group text-right\">\n                        <button type=\"submit\" class=\"btn btn-primary\" >\n                            提交\n                        </button>\n                    </div>\n                </div>\n            </div>\n\n        </form>\n\n    </div> <!-- container -->\n\n\n\n<script type=\"text/javascript\" src=\"/static/assets/plugins/multiselect/js/jquery.multi-select.js\"></script>\n<script src=\"/static/assets/plugins/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js\"></script>\n<script src=\"/static/assets/plugins/bootstrap-select/dist/js/bootstrap-select.min.js\" type=\"text/javascript\"></script>\n<script src=\"/static/assets/plugins/summernote/dist/summernote.min.js\"></script>\n<script>\n    jQuery(document).ready(function() {\n        $('.selectpicker').selectpicker();\n\n        // Date Picker\n        jQuery('#datepicker').datepicker();\n        jQuery('#datepicker-autoclose').datepicker({\n            format: \"yyyy-mm-dd\",\n            autoclose: true,\n            todayHighlight: true\n        });\n        jQuery('#datepicker-inline').datepicker();\n        jQuery('#datepicker-multiple-date').datepicker({\n            format: \"mm/dd/yyyy\",\n            clearBtn: true,\n            multidate: true,\n            multidateSeparator: \",\"\n        });\n\n        jQuery('#date-range').datepicker({\n            format: \"yyyy-mm-dd\",\n            toggleActive: true\n\n        });\n\n        // 文本域初始化\n        jQuery(document).ready(function(){\n\n            $('.summernote').summernote({\n                height: 300,                 // set editor height\n                minHeight: null,             // set minimum height of editor\n                maxHeight: null,             // set maximum height of editor\n                focus: false ,                // set focus to editable area after initializing summernote\n\n            });\n\n            $('.inline-editor').summernote({\n                airMode: true\n            });\n\n\n            $('.summernote').code('{{AssetsData.description}}');\n\n            $('button[type=submit]').click(function(e) {\n                e.preventDefault();\n                var $this = $(this);\n\n                if(!$this.hasClass('disabled')) {\n\n                    var sHTML = $('.summernote').code();\n                    if($('input[name=summernote]').length) {\n                        $('input[name=summernote]').val(sHTML);\n                    } else {\n                        $('.form-horizontal').append('<input type=\"hidden\" name=\"summernote\" value=\"' + sHTML + '\" />');\n                    }\n\n                    $.ajax({\n                        method: 'POST',\n                        dataType: 'json',\n                        url: '{% url \"ChangeAsset\" AssetsData.id %}',\n                        data: $('.form-horizontal').serialize(),\n                        success: function(data) {\n                            var msginfo = data.msginfo;\n                            if(msginfo){\n                              $.Notification.autoHideNotify('success','top right','系统通知', msginfo);\n                              setTimeout(function() {\n                                   location.href = '{% url 'AssetsLists'  1 %}';\n                              },2500);\n                            }else{\n\n                            }\n                        },\n                        error: function() {},\n                        complete: function() {\n                            $this.removeClass('disabled');\n                        }\n                    })\n                }\n            });\n\n        });\n\n\n    });\n\n</script>\n\n{% endblock %}\n\n"
  },
  {
    "path": "templates/servermanager/assetsdetail.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n<div class=\"container\">\n<div class=\"row\">\n\n\n\n     <div class=\"col-sm-12\">\n                <h4 class=\"page-title\">资产列表</h4>\n                <ol class=\"breadcrumb\">\n                    <li>\n                        <a href=\"#\">资产管理</a>\n                    </li>\n                    <li class=\"active\">\n                        <a href=\"{% url 'AssetsDetail' Assetsdata.id  %}\">资产详情</a>\n                    </li>\n                </ol>\n            </div>\n             <div class=\"col-sm-10\">\n                <div class=\"card-box\">\n                    <h4 class=\"m-t-0 header-title\"><b>资产详情:</b></h4>\n                    <br>\n                    <div class=\"row\">\n                        <div class=\"col-md-10\">\n                                <div >\n                                    <label class=\"col-md-2 control-label\">资产编号</label>\n                                    <div class=\"col-md-4\">\n                                        <p>{{Assetsdata.device_number}}</p>\n                                    </div>\n                                </div>\n                                <div >\n                                    <label class=\"col-md-2 control-label\" >设备名</label>\n                                    <div class=\"col-md-4\">\n                                         <p>{{Assetsdata.host_name}}</p>\n                                    </div>\n                                </div>\n                                <div >\n                                    <label class=\"col-md-2 control-label\">IDC</label>\n                                    <div class=\"col-md-4\">\n                                        <p>{{Assetsdata.IDC}}</p>\n                                    </div>\n                                </div>\n                                <div>\n                                    <label class=\"col-md-2 control-label\">设备类型</label>\n                                    <div class=\"col-md-4\">\n                                        <p>{{Assetsdata.device_type}}</p>\n                                    </div>\n                                </div>\n                                <div >\n                                    <label class=\"col-md-2 control-label\">业务名</label>\n                                    <div class=\"col-md-4\">\n                                        <p>{{Assetsdata.business}}</p>\n                                    </div>\n                                </div>\n                                <div >\n                                    <label class=\"col-md-2 control-label\">设备状态</label>\n                                    <div class=\"col-md-4\">\n                                        <p>{{Assetsdata.buy_type}}</p>\n                                    </div>\n                                </div>\n                                <div >\n                                    <label class=\"col-md-2 control-label\">资产价格</label>\n                                    <div class=\"col-md-4\">\n                                         <p>{{Assetsdata.price}}</p>\n                                    </div>\n                                </div>\n                                <div >\n                                    <label class=\"col-md-2 control-label\">购买时间</label>\n                                    <div class=\"col-md-4\">\n                                        <p>{{Assetsdata.buy_time}}</p>\n                                    </div>\n                                </div>\n                                <div>\n                                    <label class=\"col-md-2 control-label\">保修期(月)</label>\n                                    <div class=\"col-md-4\">\n                                        <p>{{Assetsdata.Warranty}}</p>\n                                    </div>\n                                </div>\n                                <div>\n                                    <label class=\"col-md-2 control-label\">开始使用时间</label>\n                                    <div class=\"col-md-4\">\n\n                                        <p>{{Assetsdata.suse_time | date:\"Y-m-d\"}}</p>\n                                    </div>\n                                </div>\n                               <div>\n                                    <label class=\"col-md-2 control-label\">截至使用时间</label>\n                                    <div class=\"col-md-4\">\n                                        <p>{{Assetsdata.euse_time | date:\"Y-m-d\"}}</p>\n                                    </div>\n                                </div>\n\n                                 <div >\n                                    <label class=\"col-md-2 control-label\">资产备注</label>\n                                    <div class=\"col-md-4\">\n                                        <p>{{Assetsdata.description}}</p>\n                                    </div>\n                                </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n    </div>\n    </div>\n\n{% endblock %}"
  },
  {
    "path": "templates/servermanager/hosts.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title></title>\n</head>\n<body>\n\n<h1>Hosts</h1>\n\n</body>\n</html>"
  },
  {
    "path": "templates/servermanager/servers_change.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n    <!-- Plugins css-->\n    <link href=\"/static/assets/plugins/bootstrap-tagsinput/dist/bootstrap-tagsinput.css\" rel=\"stylesheet\" />\n    <link href=\"/static/assets/plugins/switchery/dist/switchery.min.css\" rel=\"stylesheet\" />\n    <link href=\"/static/assets/plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css\" rel=\"stylesheet\">\n    <link href=\"/static/assets/plugins/select2/select2.css\" rel=\"stylesheet\" type=\"text/css\" />\n    <link href=\"/static/assets/plugins/multiselect/css/multi-select.css\"  rel=\"stylesheet\" type=\"text/css\" />\n    <link href=\"/static/assets/plugins/bootstrap-select/dist/css/bootstrap-select.min.css\" rel=\"stylesheet\" />\n    <link href=\"/static/assets/plugins/summernote/dist/summernote.css\" rel=\"stylesheet\" />\n\n\n    <div class=\"container\">\n                <!-- Page-Title -->\n                <div class=\"row\">\n                    <div class=\"col-sm-12\">\n                        <h4 class=\"page-title\">服务器修改</h4>\n                        <ol class=\"breadcrumb\">\n                            <li>\n                                <a href=\"#\">资产管理</a>\n                            </li>\n                            <li>\n                                <a href=\"{% url 'ServerList' 1 %}\">服务器列表</a>\n                            </li>\n                            <li class=\"active\">\n                                服务器修改\n                            </li>\n                        </ol>\n                    </div>\n                </div>\n\n                <form class=\"form-horizontal\" role=\"form\">\n                    {% csrf_token  %}\n\n                    <div class=\"row\">\n                        <div class=\"col-sm-8\">\n                            <div class=\"card-box\">\n                                <h4 class=\"m-t-0 header-title\"><b>基本信息:</b></h4>\n                                <div class=\"row\">\n                                    <div class=\"col-md-6\">\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">选择关联资产:</label>\n                                            <div class=\"col-md-9\">\n                                                <select class=\"selectpicker show-tick\" data-style=\"btn-white\" name=\"Assets\">\n                                                    {% for asset in AssetsData%}\n                                                        {% if ServerData.Assets.id == asset.id %}\n                                                            <option value=\"{{asset.id}}\" selected>{{asset.host_name}}</option>\n                                                        {% else %}\n                                                            <option value=\"{{asset.id}}\">{{asset.host_name}}</option>\n                                                        {% endif %}\n                                                    {%endfor%}\n                                                </select>\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">服务器SN:</label>\n                                            <div class=\"col-md-9\">\n                                                <input type=\"text\" class=\"form-control\" value=\"{{ServerData.sn}}\" name=\"sn\">\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">主机名:</label>\n                                            <div class=\"col-sm-9\">\n                                                <input type=\"text\" class=\"form-control\" value=\"{{ServerData.hostname}}\" name=\"hostname\">\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">厂商:</label>\n                                            <div class=\"col-md-9\">\n                                                <input type=\"text\" class=\"form-control\" value=\"{{ServerData.Firm}}\" name=\"firm\">\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">saltstack ID:</label>\n                                            <div class=\"col-md-9\">\n                                                <input type=\"text\" class=\"form-control\" value=\"{{ServerData.saltid}}\" name=\"saltid\">\n                                            </div>\n                                        </div>\n                                    </div>\n                                     <div class=\"col-md-6\">\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">内存:</label>\n                                            <div class=\"col-md-9\">\n                                                <input type=\"text\" class=\"form-control\" value=\"{{ServerData.mem}}\" name=\"mem\">\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                                <label class=\"col-md-3 control-label\">Swap:</label>\n                                            <div class=\"col-sm-9\">\n                                                <input type=\"text\" class=\"form-control\" value=\"{{ServerData.swap}}\" name=\"swap\">\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">系统平台:</label>\n                                            <div class=\"col-md-9\">\n                                                <input type=\"text\" class=\"form-control\" value=\"{{ServerData.platform}}\" name=\"platform\">\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">系统:</label>\n                                            <div class=\"col-md-9\">\n                                                <input type=\"text\" class=\"form-control\" value=\"{{ServerData.system}}\" name=\"system\">\n                                            </div>\n                                        </div>\n                                         <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">系统版本:</label>\n                                            <div class=\"col-md-9\">\n                                                <input type=\"text\" class=\"form-control\" value=\"{{ServerData.version}}\" name=\"version\">\n                                            </div>\n                                        </div>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n\n                    <div class=\"row\">\n                        <div class=\"col-sm-8\">\n                            <div class=\"card-box\">\n                                <h4 class=\"m-t-0 header-title\"><b>硬件信息：</b></h4>\n                                <div class=\"row\">\n                                    <div class=\"col-md-6\">\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">CPU关联:</label>\n                                            <div class=\"col-md-9\">\n                                                <select class=\"selectpicker show-tick\" data-style=\"btn-white\" name=\"CPU\">\n                                                    {% for cpu in CpuData %}\n                                                        {% if ServerData.cpu.id == cpu.id %}\n                                                            <option value=\"{{cpu.id}}\" selected>{{cpu.model}}</option>\n                                                        {%else%}\n                                                            <option value=\"{{cpu.id}}\">{{cpu.model}}</option>\n                                                        {% endif %}\n                                                    {%endfor%}\n                                                </select>\n                                            </div>\n                                        </div>\n\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">CPU个数:</label>\n                                            <div class=\"col-md-9\">\n                                                <input type=\"text\" class=\"form-control\" value=\"{{ServerData.cpu_count}}\" name=\"cpu_count\">\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">CPU核数:</label>\n                                            <div class=\"col-sm-9\">\n                                                <input type=\"text\" class=\"form-control\" value=\"{{ServerData.cpu_core_count}}\" name=\"cpu_core_count\">\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">网卡列表:</label>\n                                            <div class=\"col-sm-9\">\n                                                <select multiple=\"multiple\" class=\"multi-select\" id=\"my_multi_select1\" name=\"nic\" data-plugin=\"multiselect\">\n                                                    {% for i in NicData %}\n                                                        {% if i in   ServerData.nic.all %}\n                                                            <option value=\"{{i.id}}\" selected>{{i.ip}}</option>\n                                                        {% else %}\n                                                            <option value=\"{{i.id}}\" >{{i.ip}}</option>\n                                                        {%endif%}\n                                                    {%endfor%}\n                                                </select>\n                                            </div>\n                                        </div>\n\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">硬盘列表:</label>\n                                            <div class=\"col-md-9\">\n                                                <select multiple=\"multiple\" class=\"multi-select\" id=\"my_multi_select2\" name=\"disk\" data-plugin=\"multiselect\">\n                                                    {% for i in DiskData %}\n                                                        {% if i in   ServerData.disk.all %}\n                                                            <option value=\"{{i.id}}\" selected>{{i.parent_sn}}</option>\n                                                        {% else %}\n                                                            <option value=\"{{i.id}}\" >{{i.parent_sn}}</option>\n                                                        {%endif%}\n                                                    {%endfor%}\n                                                </select>\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">安装软件列表:</label>\n                                            <div class=\"col-sm-9\">\n                                                <select multiple=\"multiple\" class=\"multi-select\" id=\"my_multi_select3\" name=\"software\" data-plugin=\"multiselect\">\n                                                    {% for i in SoftwareData %}\n                                                        {% if i in   ServerData.software.all %}\n                                                            <option value=\"{{i.id}}\" selected>{{i.name}}</option>\n                                                        {% else %}\n                                                            <option value=\"{{i.id}}\" >{{i.name}}</option>\n                                                        {%endif%}\n                                                    {%endfor%}\n                                                </select>\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">RAID级别:</label>\n                                            <div class=\"col-md-9\">\n                                                <input type=\"text\" class=\"form-control\" value=\"{{ServerData.raid}}\" name=\"raid\">\n                                            </div>\n                                        </div>\n\n                                        <div class=\"form-group\">\n                                            <label class=\"col-md-3 control-label\">添加方式</label>\n                                            <div class=\"col-md-9\">\n                                                <select class=\"selectpicker show-tick\" data-style=\"btn-white\" name=\"addtype\">\n                                                    {% for i in ServerData.add_type_choice %}\n                                                        {% if ServerData.addtype == i.0 %}\n                                                            <option value=\"{{i.0}}\" selected>{{i.1}}</option>\n                                                        {%else%}\n                                                            <option value=\"{{i.0}}\">{{i.1}}</option>\n                                                        {%endif%}\n                                                    {%endfor%}\n                                                </select>\n                                            </div>\n                                        </div>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n\n                    <!-- 提交按钮 -->\n                    <div class=\"row\">\n                        <div class=\"col-sm-8\">\n                            <div class=\"form-group text-right\">\n                                <button type=\"submit\" class=\"btn btn-primary\">\n                                    提交\n                                </button>\n                            </div>\n                        </div>\n                    </div>\n\n                </form>\n\n            </div> <!-- container -->\n\n\n<script type=\"text/javascript\" src=\"/static/assets/plugins/multiselect/js/jquery.multi-select.js\"></script>\n<script src=\"/static/assets/plugins/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js\"></script>\n<script src=\"/static/assets/plugins/select2/select2.min.js\" type=\"text/javascript\"></script>\n<script type=\"text/javascript\" src=\"/static/assets/plugins/multiselect/js/jquery.multi-select.js\"></script>\n<script src=\"/static/assets/plugins/bootstrap-select/dist/js/bootstrap-select.min.js\" type=\"text/javascript\"></script>\n\n<script>\n    jQuery(document).ready(function() {\n        // Select2\n        $(\".select2\").select2();\n        $(\".select2-limiting\").select2({\n            maximumSelectionLength: 2\n        });\n        $('.selectpicker').selectpicker();\n        $('button[type=submit]').click(function(e) {\n            e.preventDefault();\n            $.ajax({\n                        type: 'POST',\n                        url: '{% url \"ChangeServer\" ServerData.id %}',\n                        data: $('.form-horizontal').serialize(),\n                        success: function(data) {\n                            $.Notification.autoHideNotify('success','top right','系统通知', '服务器信息修改成功');\n                            setTimeout(function() {\n                                   location.href = '{% url 'ServerList'  1 %}';\n                              },2500);\n                        },\n                        error: function() {},\n\n            });\n        });\n\n    })\n\n</script>\n\n{%endblock%}\n"
  },
  {
    "path": "templates/servermanager/servers_detail.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n<div class=\"container\">\n\n                <!-- Page-Title -->\n                <div class=\"row\">\n                    <div class=\"col-sm-12\">\n                        <h4 class=\"page-title\">服务器详情</h4>\n                        <ol class=\"breadcrumb\">\n                            <li><a href=\"#\">资产管理</a></li>\n                            <li><a href=\"{% url 'ServerList' 1 %}\">服务器列表</a></li>\n                            <li class=\"active\">服务器详情</li>\n                        </ol>\n\n                    </div>\n                </div>\n\n\n                <!-- 基本信息 -->\n                <div class=\"row\">\n                    <div class=\"col-sm-8\">\n                        <div class=\"card-box\">\n                            <h4 class=\"m-t-0 header-title\"><b>基本信息：</b></h4>\n                            <div class=\"row\">\n                                <div class=\"col-md-6\">\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">ID</label>\n                                        <div class=\"col-md-9\">\n                                            <p>{{ServerData.id}}</p>\n                                        </div>\n                                    </div>\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">服务器SN：</label>\n                                        <div class=\"col-md-9\">\n                                            <p>{{ServerData.sn}}</p>\n                                        </div>\n                                    </div>\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">资产编号：</label>\n                                        <div class=\"col-md-9\">\n                                            <p>{{ServerData.Assets.device_number}}</p>\n                                        </div>\n                                    </div>\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">主机名:</label>\n                                        <div class=\"col-md-9\">\n                                            <p>{{ServerData.hostname}}</p>\n                                        </div>\n                                    </div>\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">IDC:</label>\n                                        <div class=\"col-md-9\">\n                                            <p>{{ServerData.Assets.IDC}}</p>\n                                        </div>\n                                    </div>\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">厂商:</label>\n                                        <div class=\"col-md-9\">\n                                            <p>{{ServerData.Firm}}</p>\n                                        </div>\n                                    </div>\n\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">业务：</label>\n                                        <div class=\"col-md-9\">\n                                            <p>{{ServerData.Assets.business}}</p>\n                                        </div>\n                                    </div>\n\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">SaltstackID：</label>\n                                        <div class=\"col-md-9\">\n                                            <p>{{ServerData.saltid}}</p>\n                                        </div>\n                                    </div>\n                                </div>\n\n                                <div class=\"col-sm-3 col-lg-3 text-center\">\n                                    <div class=\"p-20\">\n                                        <input class=\"knob\" data-width=\"150\" data-height=\"150\" data-cursor=true data-fgColor=\"#fb6d9d\" value=\"{{ServerData.cpu_count}}\"/>\n                                        <h5 class=\"font-600 text-muted\">CPU核数</h5>\n                                    </div>\n                                </div>\n                                 <div class=\"col-sm-3 col-lg-3 text-center\">\n                                    <div class=\"p-20\">\n                                        <input class=\"knob\" data-width=\"150\" data-height=\"150\" data-cursor=true data-fgColor=\"#fb6d9d\" value=\"{{ServerData.nic.count}}\"/>\n                                        <h5 class=\"font-600 text-muted\">网卡数</h5>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n\n                <!-- 硬件信息 -->\n                <div class=\"row\">\n                    <div class=\"col-sm-8\">\n                        <div class=\"card-box\">\n                            <h4 class=\"m-t-0 header-title\"><b>硬件信息：</b></h4>\n                            <div class=\"row\">\n                                <div class=\"col-md-6\">\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">物理CPU</label>\n                                        <div class=\"col-md-9\">\n                                            <p>{{ServerData.cpu_count}}</p>\n                                        </div>\n                                    </div>\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">CPU核数：</label>\n                                        <div class=\"col-md-9\">\n                                            <p>{{ServerData.cpu_core_count}}</p>\n                                        </div>\n                                    </div>\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">内存：</label>\n                                        <div class=\"col-md-9\">\n                                            <p>{{ServerData.mem}}</p>\n                                        </div>\n                                    </div>\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">swap空间:</label>\n                                        <div class=\"col-md-9\">\n                                            <p>{{ServerData.swap}}</p>\n                                        </div>\n                                    </div>\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">操作系统:</label>\n                                        <div class=\"col-md-9\">\n                                            <p>{{ServerData.system}}</p>\n                                        </div>\n                                    </div>\n                                    <div class=\"row\">\n                                        <label class=\"col-md-3 control-label\">网卡IP列表:</label>\n                                        <div class=\"col-md-9\">\n                                            {%for i in ServerData.nic.all%}\n                                                    <p>{{i.ip}}</p>\n                                            {%endfor%}\n                                        </div>\n                                    </div>\n                                </div>\n\n                                <div class=\"col-md-3\">\n                                          <canvas id=\"doughnut1\" height=\"200\"></canvas>\n                                </div>\n\n                                <div class=\"col-md-3\">\n                                          <canvas id=\"doughnut2\" height=\"200\"></canvas>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"row\">\n                    <div class=\"col-lg-8\">\n                        <ul class=\"nav nav-tabs tabs\">\n                            <li class=\"active tab\">\n                                <a href=\"#home-2\" data-toggle=\"tab\" aria-expanded=\"false\">\n                                    <span class=\"visible-xs\"><i class=\"fa fa-home\"></i></span>\n                                    <span class=\"hidden-xs\">CPU信息</span>\n                                </a>\n                            </li>\n                            <li class=\"tab\">\n                                <a href=\"#profile-2\" data-toggle=\"tab\" aria-expanded=\"false\">\n                                    <span class=\"visible-xs\"><i class=\"fa fa-user\"></i></span>\n                                    <span class=\"hidden-xs\">内存</span>\n                                </a>\n                            </li>\n                            <li class=\"tab\">\n                                <a href=\"#messages-2\" data-toggle=\"tab\" aria-expanded=\"true\">\n                                    <span class=\"visible-xs\"><i class=\"fa fa-envelope-o\"></i></span>\n                                    <span class=\"hidden-xs\">硬盘</span>\n                                </a>\n                            </li>\n                            <li class=\"tab\">\n                                <a href=\"#settings-2\" data-toggle=\"tab\" aria-expanded=\"false\">\n                                    <span class=\"visible-xs\"><i class=\"fa fa-cog\"></i></span>\n                                    <span class=\"hidden-xs\">网卡</span>\n                                </a>\n                            </li>\n                            <li class=\"tab\">\n                                <a href=\"#soft-2\" data-toggle=\"tab\" aria-expanded=\"false\">\n                                    <span class=\"visible-xs\"><i class=\"fa fa-soft\"></i></span>\n                                    <span class=\"hidden-xs\">软件</span>\n                                </a>\n                            </li>\n                        </ul>\n                        <div class=\"tab-content\">\n                            <div class=\"tab-pane active\" id=\"home-2\">\n                                <div class=\"row\">\n                                    <label class=\"col-md-2 control-label\">uuid:</label>\n                                    <div class=\"col-md-10\">\n                                        <p>{{ServerData.cpu.uuid}}</p>\n                                    </div>\n                                </div>\n                                <div class=\"row\">\n                                    <label class=\"col-md-2 control-label\">CPU型号:</label>\n                                    <div class=\"col-md-4\">\n                                        <p>{{ServerData.cpu.model}}</p>\n                                    </div>\n                                    <label class=\"col-md-2 control-label\">CPU Mhz:</label>\n                                    <div class=\"col-md-2\">\n                                        <p>{{ServerData.cpu.cpu_mhz}}</p>\n                                    </div>\n                                </div>\n                                <div class=\"row\">\n                                    <label class=\"col-md-2 control-label\">CPU架构:</label>\n                                    <div class=\"col-md-2\">\n                                        <p>{{ServerData.cpu.Architecture}}</p>\n                                    </div>\n                                    <label class=\"col-md-2 control-label\">生产商:</label>\n                                    <div class=\"col-md-2\">\n                                        <p>{{ServerData.cpu.Vendor}}</p>\n                                    </div>\n                                     <label class=\"col-md-2 control-label\">Thread:</label>\n                                    <div class=\"col-md-2\">\n                                        <p>{{ServerData.cpu.Thread}}</p>\n                                    </div>\n                                </div>\n                                <div class=\"row\">\n                                    <label class=\"col-md-2 control-label\">1级缓存:</label>\n                                    <div class=\"col-md-2\">\n                                        <p>{{ServerData.cpu.L1cache}}</p>\n                                    </div>\n                                    <label class=\"col-md-2 control-label\">2级缓存:</label>\n                                    <div class=\"col-md-2\">\n                                        <p>{{ServerData.cpu.L2cache}}</p>\n                                    </div>\n                                    <label class=\"col-md-2 control-label\">3级缓存:</label>\n                                    <div class=\"col-md-2\">\n                                        <p>{{ServerData.cpu.L3cache}}</p>\n                                    </div>\n                                </div>\n                            </div>\n                            <div class=\"tab-pane\" id=\"profile-2\">\n                                <div class=\"row\">\n                                    <label class=\"col-md-2 control-label\">容量:</label>\n                                    <div class=\"col-md-4\">\n                                        <p>{{ServerData.mem}}</p>\n                                    </div>\n                                </div>\n                                <div class=\"row\">\n                                    <label class=\"col-md-2 control-label\">SWAP容量:</label>\n                                    <div class=\"col-md-4\">\n                                        <p>{{ServerData.swap}}</p>\n                                    </div>\n                                </div>\n                            </div>\n\n                            <div class=\"tab-pane\" id=\"messages-2\">\n                                <div class=\"row\">\n                                    <div class=\"col-lg-12\">\n                                        <div class=\"p-1\">\n                                            <table class=\"table m-0\">\n\n                                                <thead>\n                                                <tr>\n                                                    <th>硬盘名</th>\n                                                    <th>容量</th>\n                                                    <th>UUID号</th>\n                                                    <th>硬盘类型</th>\n                                                </tr>\n                                                </thead>\n                                                <tbody>\n                                                {% for i in ServerData.disk.all %}\n                                                    <tr>\n                                                        <th scope=\"row\">{{i.name}}</th>\n                                                        <td>{{i.capacity}}</td>\n                                                        <td>{{i.uuid}}</td>\n                                                        <td>{{i.disk_type}}</td>\n                                                    </tr>\n                                                {%endfor%}\n                                                </tbody>\n                                            </table>\n                                        </div>\n\n                                    </div>\n                                </div>\n                            </div>\n                            <div class=\"tab-pane\" id=\"settings-2\">\n                                <div class=\"row\">\n                                    <div class=\"col-lg-12\">\n                                        <div class=\"p-1\">\n                                            <table class=\"table m-0\">\n\n                                                <thead>\n                                                <tr>\n                                                    <th>网卡名</th>\n                                                    <th>IP</th>\n                                                    <th>mac</th>\n                                                    <th>netmask</th>\n                                                    <th>状态</th>\n                                                </tr>\n                                                </thead>\n                                                <tbody>\n                                                {%for i in ServerData.nic.all %}\n                                                    <tr>\n                                                        <th scope=\"row\">{{i.name}}</th>\n                                                        <td>{{i.ip}}</td>\n                                                        <td>{{i.mac}}</td>\n                                                        <td>{{i.netmask}}</td>\n                                                        {% if i.nicstatus %}\n                                                            <td>UP</td>\n                                                        {%else%}\n                                                            <td>DOWN</td>\n                                                        {%endif%}\n                                                    </tr>\n                                                {%endfor%}\n                                                </tbody>\n                                            </table>\n                                        </div>\n                                    </div>\n                                </div>\n                            </div>\n                            <div class=\"tab-pane\" id=\"soft-2\">\n                                <div class=\"row\">\n                                    <div class=\"col-lg-12\">\n                                        <div class=\"p-1\">\n                                            <table class=\"table m-0\">\n\n                                                <thead>\n                                                <tr>\n                                                    <th>软件名</th>\n                                                    <th>版本</th>\n                                                    <th>序列号</th>\n                                                </tr>\n                                                </thead>\n                                                <tbody>\n                                                {%for i in ServerData.software.all %}\n                                                <tr>\n                                                    <th scope=\"row\">{{i.name}}</th>\n                                                    <td>{{i.version}}</td>\n                                                    <td>{{i.license}}</td>\n                                                </tr>\n                                                {%endfor%}\n                                                </tbody>\n                                            </table>\n                                        </div>\n\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n                <!-- end row -->\n            </div> <!-- container -->\n\n <!-- EASY PIE CHART JS -->\n<script src=\"/static/assets/plugins/jquery.easy-pie-chart/dist/easypiechart.min.js\"></script>\n<script src=\"/static/assets/plugins/jquery.easy-pie-chart/dist/jquery.easypiechart.min.js\"></script>\n<script src=\"/static/assets/pages/easy-pie-chart.init.js\"></script>\n\n<!--\n<script src=\"/static/assets/plugins/flot-chart/jquery.flot.js\"></script>\n<script src=\"/static/assets/plugins/flot-chart/jquery.flot.tooltip.min.js\"></script>\n<script src=\"/static/assets/plugins/flot-chart/jquery.flot.resize.js\"></script>\n\n<script src=\"/static/assets/plugins/flot-chart/jquery.flot.pie.js\"></script>\n\n<script>\n\n       $(function(){\n            var data = [\n                { label: \"sda\",  data: 500, },\n                { label: \"sdb\",  data: 300,},\n                { label: \"sdc\",  data: 100,},\n            ];\n\n            $.plot($(\"#pie-chart-container\"), data, {\n                series: {\n                          pie: {\n                                   show: true, //显示饼图\n                                   //innerRadius: 0.5,\n                         }\n                },\n                legend: {\n                            show: false, //不显示图例\n                },\n                grid : {\n                        hoverable : true,\n\n                },\n                colors: [\"#5fbeaa\",\"#ebeff2\",\"#34d3eb\",],\n                tooltip: true,\n                tooltipOpts: {\n                    content: \"%p, %s\", // show percentages, rounding to 2 decimal places\n                    shifts: {\n                        x: 20,\n                        y: 0\n                    },\n                    defaultTheme: false\n                },\n            });\n       });\n</script>-->\n\n<script src=\"/static/assets/plugins/Chart.js/Chart.min.js\"></script>\n<script>\nvar memdata = [\n            {\n                value: {{ServerData.mem}},\n                color: \"#5fbeaa\",\n                highlight: \"#5fbeaa\",\n                label: \"内存容量\"\n            }, {\n                value: {{ServerData.swap}},\n                color: \"#5d9cec\",\n                highlight: \"#5d9cec\",\n                label: \"Swap容量\"\n            },\n        ]\n\n\n\n\nvar diskdata = {{Diskhtml|safe}}\n\n\n\nvar myPie = new Chart(document.getElementById(\"doughnut1\").getContext(\"2d\")).Doughnut(memdata);\nvar myPie = new Chart(document.getElementById(\"doughnut2\").getContext(\"2d\")).Pie(diskdata);\n\n</script>\n\n\n\n\n{% endblock %}"
  },
  {
    "path": "templates/servermanager/servers_list.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n\n<link href=\"/static/assets/plugins/datatables/jquery.dataTables.min.css\" rel=\"stylesheet\" type=\"text/css\">\n<link href=\"/static/assets/plugins/bootstrap-table/dist/bootstrap-table.min.css\" rel=\"stylesheet\" type=\"text/css\">\n<style>\n    .glyphicon.glyphicon-repeat{\n        visibility: hidden;\n        -moz-animation:rotate 1s infinite linear;\n        -webkit-animation:rotate 1s infinite linear;\n        animation:rotate 1s infinite linear;\n    }\n    @-moz-keyframes rotate{\n        0%{\n          -moz-transform:rotate(0deg);\n         }\n         100%{\n           -moz-transform:rotate(360deg);\n         }\n      }\n      @-webkit-keyframes rotate{\n        0%{\n          -webkit-transform:rotate(0deg);\n         }\n         100%{\n           -webkit-transform:rotate(360deg);\n         }\n      }\n      @keyframes rotate{\n        0%{\n          transform:rotate(0deg);\n         }\n         100%{\n           transform:rotate(360deg);\n         }\n      }\n</style>\n\n\n<div class=\"container\">\n   <!-- Page-Title -->\n    <div class=\"row \">\n            <div class=\"col-sm-12\">\n                <h4 class=\"page-title\">服务器列表</h4>\n                <ol class=\"breadcrumb\">\n                    <li>\n                        <a href=\"#\">资产管理</a>\n                    </li>\n                    <li class=\"active\">\n                        <a href=\"{% url 'ServerList' 1 %}\">服务器列表</a>\n                    </li>\n                </ol>\n            </div>\n            <div class=\"row\">\n                <div class=\"col-sm-12\">\n                    <div class=\"card-box\">\n                        <div class=\"row\">\n                            <div class=\"col-sm-12\">\n                                <h4 class=\"m-t-0 header-title\"><b>Simpletour服务器列表</b></h4>\n                                <p class=\"text-muted font-13\">\n                                    服务器详细情况请点击主机SN号\n                                </p>\n                            </div>\n\n                                <div>\n                                <div class=\"col-sm-8\">\n                                </div>\n                                <div class=\"col-sm-4\">\n                                    <form method=\"post\" action=\"{% url 'ServerList' 1 %}\">\n                                        {% csrf_token  %}\n                                        <div class=\"input-group\">\n                                            <input type=\"text\" id=\"search\" name=\"search\" class=\"form-control\" placeholder=\"输入SN编号\\设备名\\主机名\">\n                                            <span class=\"input-group-btn\">\n                                            <button type=\"submit\" class=\"btn waves-effect waves-light btn-primary\"  ><i class=\"fa fa-search\"></i></button>\n                                            </span>\n                                        </div>\n                                    </form>\n                                 </div>\n                            </div>\n\n                            <div class=\"col-sm-12\">\n                                <br>\n\n                                <div class=\"bootstrap-table\">\n                                    <div class=\"table-responsive\">\n                                        <table class=\"table-bordered\" data-page-size=\"5\" data-toggle=\"table\" >\n                                            <thead>\n                                                <tr>\n                                                    <th>服务器SN</th>\n                                                    <th>设备名</th>\n                                                    <th>主机名</th>\n                                                    <th>IDC</th>\n                                                    <th>CPU核数</th>\n                                                    <th>IP列表</th>\n                                                    <th>购买价格</th>\n                                                    <th>硬盘</th>\n                                                    <th>网卡个数</th>\n                                                    <th>添加方式</th>\n                                                    <th>最近更新</th>\n                                                    <th>操 作</th>\n                                                </tr>\n                                            </thead>\n                                            <tbody id=\"tb1\">\n\n                                            {% for server in Serverdata %}\n                                                <tr>\n                                                    <td class=\"sn\"><a href=\"{% url 'ServerDetail' server.id %}\">{{server.sn}}</a></td>\n                                                    <td>{{server.Assets.host_name}}</td>\n                                                    <td class=\"hostName\">{{server.hostname}}</td>\n                                                    <td>{{server.Assets.IDC}}</td>\n                                                    <td class=\"cpu\">{{server.cpu_core_count}}</td>\n                                                    <td class=\"nic\">{%for i in server.nic.all%}\n                                                            {{i.ip}}<br>\n                                                        {%endfor%}\n                                                    </td>\n\n                                                    <td>{{server.Assets.price}}</td>\n                                                    <td class=\"disk\">\n                                                    {% for i in server.disk.all %}\n                                                            {{i.name}}\n                                                    {%endfor%}\n\n                                                    </td>\n                                                    <td>\n                                                        {{server.nic.count}}\n                                                    </td>\n\n                                                    {% for i in server.add_type_choice %}\n                                                        {% if server.addtype == i.0 %}\n                                                                <td>{{i.1}}</td>\n                                                        {%endif%}\n                                                    {%endfor%}\n                                                    <td class=\"updateTime\">{{server.update_time|date:'Y-m-d H:i'}}</td>\n                                                    <td>\n                                                        <a href=\"{% url 'DeleteServer' server.id %}\" class=\"btn btn-xs btn-primary\">删除</a>\n                                                        <a href=\"{% url 'ChangeServer' server.id %}\" class=\"btn btn-xs btn-info\">修改</a>\n                                                        <button  class=\"btn btn-xs btn-danger\" data-id=\"{{server.id}}\">资产更新</button>\n                                                        <i class=\"glyphicon glyphicon-repeat\"></i>\n                                                    </td>\n                                                </tr>\n                                            {% endfor%}\n                                            </tbody>\n                                        </table>\n                                              <nav>\n                                                <ul class=\"pagination\" >\n                                                    {{page}}\n                                                </ul>\n                                                </nav>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n\n\n\n\n            </div>\n        </div>\n    </div>\n\n    </div>\n</div>\n\n<script>\n    var timer,$btn;\n    $('.bootstrap-table').on('click','.btn.btn-xs',function(e) {\n        $btn = $(this);\n        if($btn.hasClass('disabled')) return;\n        var serverId = $btn.attr('data-id');\n        $.ajax({\n            url:'/server/servers/update/' + serverId,\n            beforeSend: function() {\n                $btn.addClass('disabled');\n                $btn.next('.glyphicon').css('visibility','visible');\n            },\n            method:'GET',\n            dataType: 'json',\n            success:function(data){\n                var celeryId = data.celeryId;\n                timer = setInterval(function() {\n                    callback_status(celeryId);\n                },1000);\n            },\n            error:function(){\n                $btn.next('.glyphicon').css('visibility','hidden');\n                $btn.removeClass('disabled');\n            }\n        });\n\n    });\n\n    var update_info = function(result) {\n        $btn.parents('tr').find('.sn a').text(result.sn);\n        $btn.parents('tr').find('.hostName').text(result.hostname);\n        $btn.parents('tr').find('.cpu').text(result.cpu);\n\n        var nicHtml = \"\";\n        for(var i = 0; i < result.nic.length; i++) {\n            if((i + 1) == result.nic.length) {\n                nicHtml += result.nic[i]\n            } else {\n                nicHtml += result.nic[i] + '<br/>';\n            }\n        };\n        $btn.parents('tr').find('.nic').html(nicHtml);\n\n        var diskHtml = \"\";\n        for(var j = 0; j < result.disk.length; j++) {\n            if((j + 1) == result.disk.length) {\n                diskHtml += result.disk[j]\n            } else {\n                diskHtml += result.disk[j] + '<br>';\n            }\n        };\n        $btn.parents('tr').find('.disk').html(diskHtml);\n        $btn.parents('tr').find('.updateTime').text(result.last_update);\n\n    }\n\n    var callback_status = function(celeryId) {\n        $.ajax({\n            url:'/server/servers/task/' + celeryId,\n            method:'GET',\n            dataType: 'json',\n            success:function(data){\n                if(data.state == 'SUCCESS') {\n                    clearInterval(timer);\n                    update_info(data.result);\n                    $.Notification.autoHideNotify('success','top right','系统通知', '资产状态已更新!!!!');\n                    $btn.next('.glyphicon').css('visibility','hidden');\n                    $btn.removeClass('disabled');\n\n                } else if(data.state == 'FAILURE') {\n                    clearInterval(timer);\n                    $.Notification.autoHideNotify('error', 'top right', '系统通知',\"资产更新失败!!!\");\n                    console.log(data.status);\n                    $btn.next('.glyphicon').css('visibility','hidden');\n                    $btn.removeClass('disabled');\n                };\n            },\n            error:function(){\n\n            },\n        });\n    };\n</script>\n\n\n{% endblock %}"
  },
  {
    "path": "templates/tempdir/foot_script.html",
    "content": "\n<script src=\"/static/assets/plugins/peity/jquery.peity.min.js\"></script>\n<script src=\"/static/assets/plugins/datatables/jquery.dataTables.min.js\"></script>\n<script src=\"/static/assets/plugins/datatables/dataTables.bootstrap.js\"></script>\n<script src=\"/static/assets/plugins/bootstrap-table/dist/bootstrap-table.min.js\"></script>\n<!-- jQuery  -->\n<script src=\"/static/assets/plugins/waypoints/lib/jquery.waypoints.js\"></script>\n<script src=\"/static/assets/plugins/counterup/jquery.counterup.min.js\"></script>\n<script src=\"/static/assets/plugins/raphael/raphael-min.js\"></script>\n<script src=\"/static/assets/plugins/jquery-knob/jquery.knob.js\"></script>\n<script src=\"/static/assets/pages/jquery.bs-table.js\"></script>\n\n<script src=\"/static/assets/plugins/notifyjs/dist/notify.min.js\"></script>\n<script src=\"/static/assets/plugins/notifications/notify-metro.js\"></script>\n\n\n<script src=\"/static/assets/js/jquery.core.js\"></script>\n<script src=\"/static/assets/js/jquery.app.js\"></script>\n\n<script type=\"text/javascript\">\njQuery(document).ready(function($) {\n    $('.counter').counterUp({\n        delay: 100,\n        time: 1200\n    });\n\n    $(\".knob\").knob();\n\n});\n</script>\n\n\n\n"
  },
  {
    "path": "templates/tempdir/head_css.html",
    "content": "\n<link href=\"/static/assets/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n<link href=\"/static/assets/css/core.css\" rel=\"stylesheet\" type=\"text/css\" />\n<link href=\"/static/assets/css/components.css\" rel=\"stylesheet\" type=\"text/css\" />\n<link href=\"/static/assets/css/icons.css\" rel=\"stylesheet\" type=\"text/css\" />\n<link href=\"/static/assets/css/pages.css\" rel=\"stylesheet\" type=\"text/css\" />\n<link href=\"/static/assets/css/responsive.css\" rel=\"stylesheet\" type=\"text/css\" />\n<link href=\"/static/assets/css/statusecho.css\" rel=\"stylesheet\" type=\"text/css\" />"
  },
  {
    "path": "templates/tempdir/head_script.html",
    "content": "<script src=\"/static/assets/js/modernizr.min.js\"></script>\n<script>\n\tvar resizefunc = [];\n</script>\n<!-- jQuery  -->\n<script src=\"/static/assets/js/jquery.min.js\"></script>\n<script src=\"/static/assets/js/bootstrap.min.js\"></script>\n<script src=\"/static/assets/js/detect.js\"></script>\n<script src=\"/static/assets/js/fastclick.js\"></script>\n<script src=\"/static/assets/js/jquery.slimscroll.js\"></script>\n<script src=\"/static/assets/js/jquery.blockUI.js\"></script>\n<script src=\"/static/assets/js/waves.js\"></script>\n<script src=\"/static/assets/js/wow.min.js\"></script>\n<script src=\"/static/assets/js/jquery.nicescroll.js\"></script>\n<script src=\"/static/assets/js/jquery.scrollTo.min.js\"></script>\n\n"
  },
  {
    "path": "templates/webapp/index.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n<div class=\"container\">\n        <!-- Page-Title -->\n        <div class=\"row\">\n          <div class=\"col-sm-12\">\n            <h4 class=\"page-title\">系统首页</h4>\n            <p class=\"text-muted page-title-alt\">欢迎进入SimpletourDevops运维系统!</p>\n          </div>\n        </div>\n        <div class=\"row\">\n          <div class=\"col-md-6 col-lg-3\">\n            <div class=\"widget-bg-color-icon card-box fadeInDown animated\">\n              <div class=\"bg-icon bg-icon-info pull-left\"> <i class=\"md md-attach-money text-info\"></i> </div>\n              <div class=\"text-right\">\n                <h3 class=\"text-dark\"><b class=\"counter\">{{priceData.price__sum}}</b></h3>\n                <p class=\"text-muted\">资产总价</p>\n              </div>\n              <div class=\"clearfix\"></div>\n            </div>\n          </div>\n          <div class=\"col-md-6 col-lg-3\">\n            <div class=\"widget-bg-color-icon card-box\">\n              <div class=\"bg-icon bg-icon-pink pull-left\"> <i class=\"md  md-view-headline text-pink\"></i> </div>\n              <div class=\"text-right\">\n                <h3 class=\"text-dark\"><b class=\"counter\">{{ServersCount}}</b></h3>\n                <p class=\"text-muted\">服务器统计</p>\n              </div>\n              <div class=\"clearfix\"></div>\n            </div>\n          </div>\n          <div class=\"col-md-6 col-lg-3\">\n            <div class=\"widget-bg-color-icon card-box\">\n              <div class=\"bg-icon bg-icon-purple pull-left\"> <i class=\"md  md-view-module text-purple\"></i> </div>\n              <div class=\"text-right\">\n                <h3 class=\"text-dark\"><b class=\"counter\">{{DockerContainerCount}}</b></h3>\n                <p class=\"text-muted\">容器统计</p>\n              </div>\n              <div class=\"clearfix\"></div>\n            </div>\n          </div>\n          <div class=\"col-md-6 col-lg-3\">\n            <div class=\"widget-bg-color-icon card-box\">\n              <div class=\"bg-icon bg-icon-success pull-left\"> <i class=\"md md-remove-red-eye text-success\"></i> </div>\n              <div class=\"text-right\">\n                <h3 class=\"text-dark\"><b class=\"counter\">{{DockerImageCount}}</b></h3>\n                <p class=\"text-muted\">镜像统计</p>\n              </div>\n              <div class=\"clearfix\"></div>\n            </div>\n          </div>\n        </div>\n        <div class=\"row\">\n          <div class=\"col-lg-8\">\n           <div class=\"portlet\">\n              <div class=\"portlet-heading portlet-default\">\n                      <h3 class=\"portlet-title text-dark\">\n                          用户最近执行操作\n                      </h3>\n                      <div class=\"portlet-widgets\">\n                          <a href=\"javascript:;\" data-toggle=\"reload\"><i class=\"ion-refresh\"></i></a>\n                          <span class=\"divider\"></span>\n                          <a data-toggle=\"collapse\" data-parent=\"#accordion1\" href=\"#bg-default\"><i class=\"ion-minus-round\"></i></a>\n                          <span class=\"divider\"></span>\n                          <a href=\"#\" data-toggle=\"remove\"><i class=\"ion-close-round\"></i></a>\n                      </div>\n                      <div class=\"clearfix\"></div>\n                  </div>\n\n              <div class=\"portlet-body\">\n                  <table class=\"table table-striped m-0\">\n                      <thead>\n                          <tr>\n                              <th>#</th>\n                              <th>执行人</th>\n                              <th>时间</th>\n                              <th>操作</th>\n                          </tr>\n                      </thead>\n                      <tbody>\n                        {% for i in Opdata%}\n                          <tr>\n                              <th scope=\"row\">{{i.id}}</th>\n                              <td>{{i.Opuser}}</td>\n                              <td>{{i.Optime|date:\"Y-m-d H:i:s\"}}</td>\n                              <td>{{i.Opaction}}</td>\n                          </tr>\n                        {%endfor%}\n                      </tbody>\n                  </table>\n              </div>\n            </div>\n          </div>\n          <div class=\"col-lg-4\">\n              <div class=\"portlet\">\n                  <div class=\"portlet-heading portlet-default\">\n                      <h3 class=\"portlet-title text-dark\">\n                          用户基本信息\n                      </h3>\n                      <div class=\"portlet-widgets\">\n                          <a href=\"javascript:;\" data-toggle=\"reload\"><i class=\"ion-refresh\"></i></a>\n                          <span class=\"divider\"></span>\n                          <a data-toggle=\"collapse\" data-parent=\"#accordion1\" href=\"#bg-default\"><i class=\"ion-minus-round\"></i></a>\n                          <span class=\"divider\"></span>\n                          <a href=\"#\" data-toggle=\"remove\"><i class=\"ion-close-round\"></i></a>\n                      </div>\n                      <div class=\"clearfix\"></div>\n                  </div>\n                  <div class=\"portlet-body\">\n                        <div>\n                            <div class=\"text-left\">\n                                <table class=\"table\">\n                                    <tbody><tr>\n                                        <td class=\"text-navy\">ID</td>\n                                        <td>{{UserData.id}}</td>\n                                    </tr>\n                                    <tr>\n                                        <td class=\"text-navy\">用户名</td>\n                                        <td>{{UserData.username}}</td>\n                                    </tr>\n                                    <tr>\n                                        <td class=\"text-navy\">姓名</td>\n                                        <td>{{UserData.name}}</td>\n                                    </tr>\n                                    <tr>\n                                        <td class=\"text-navy\">邮箱</td>\n                                        <td>{{UserData.email}}</td>\n                                    </tr>\n                                    <tr>\n                                        <td class=\"text-navy\">QQ</td>\n\n                                        <td>{{UserData.QQ}}</td>\n\n                                    </tr>\n                                    <tr>\n                                        <td class=\"text-navy\">联系方式</td>\n                                        <td>{{UserData.phone}}</td>\n                                    </tr>\n                                    <tr>\n                                        <td class=\"text-navy\">激活</td>\n                                        {% if UserData.is_active %}\n                                            <td class=\"glyphicon glyphicon-ok\"></td>\n                                        {% else%}\n                                            <td class=\"glyphicon glyphicon-remove\"></td>\n                                        {%endif%}\n                                    </tr>\n                                    <tr>\n                                        <td class=\"text-navy\">添加日期</td>\n                                        <td>{{UserData.date_joined|date:\"Y-m-d H:i:s\"}}</td>\n                                    </tr>\n                                    <tr>\n                                        <td class=\"text-navy\">最后登录</td>\n                                        <td>{{UserData.last_login|date:\"Y-m-d H:i:s\"}}</td>\n                                    </tr>\n                                    <tr>\n                                        <td class=\"text-navy\">所在用户组</td>\n                                        <td>\n                                             <table class=\"table\">\n                                                 {% for g in UserData.groups.all %}\n                                                    <tr>\n                                                        <td>{{g}}</td>\n                                                    </tr>\n                                                 {% endfor %}\n                                             </table>\n                                        </td>\n                                    </tr>\n\n                                    <tr>\n                                        <td class=\"text-navy\">部门</td>\n                                        <td>{{UserData.department.name}}</td>\n                                    </tr>\n\n                                </tbody></table>\n                            </div>\n                        </div>\n                  </div>\n              </div>\n          </div>\n        </div>\n        <!-- end row -->\n\n\n      </div>\n\n\n{% endblock %}\n\n"
  },
  {
    "path": "templates/webapp/login.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"utf-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n        <meta name=\"description\" content=\"simpletourDevops\">\n        <meta name=\"author\" content=\"www.roddypy.com\">\n\n        <link rel=\"shortcut icon\" href=\"/static/assets/images/favicon_1.ico\">\n\n        <title>SimpletourDevops</title>\n\n        <link href=\"/static/assets/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/core.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/components.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/icons.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/pages.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/responsive.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n        <!-- HTML5 Shiv and Respond.js IE8 support of HTML5 elements and media queries -->\n        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n        <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js\"></script>\n        <![endif]-->\n\n        <script src=\"/static/assets/js/modernizr.min.js\"></script>\n        \n    </head>\n    <body>\n\n\n\n\n\n        <div class=\"account-pages\"></div>\n        <div class=\"clearfix\"></div>\n        <div class=\"wrapper-page\">\n        \t<div class=\" card-box\">\n            <div class=\"panel-heading\"> \n                <h3 class=\"text-center\"> Simpletour <strong class=\"text-custom\">Devops</strong> </h3>\n            </div> \n\n\n            <div class=\"panel-body\">\n            <form class=\"form-horizontal m-t-20\" role=\"form\">\n\n                {% csrf_token  %}\n                <div class=\"form-group \">\n                    <div class=\"col-xs-12\">\n                        {{data.username}}\n\n                    </div>\n                </div>\n\n                <div class=\"form-group\">\n                    <div class=\"col-xs-12\">\n                         {{data.password}}\n                    </div>\n                </div>\n\n                <div class=\"form-group \">\n                    <div class=\"col-xs-12\">\n                        <div class=\"checkbox checkbox-primary\">\n                            <input id=\"checkbox-signup\" type=\"checkbox\">\n                            <label for=\"checkbox-signup\">\n                                记住我\n                            </label>\n                        </div>\n                    </div>\n                </div>\n                \n                <div class=\"form-group text-center m-t-40\">\n                    <div class=\"col-xs-12\">\n                        <button class=\"btn btn-pink btn-block text-uppercase waves-effect waves-light\" type=\"submit\">登录</button>\n                    </div>\n                </div>\n\n                <div class=\"form-group m-t-30 m-b-0\">\n                    <div class=\"col-sm-12\">\n                        <a href=\"{% url 'SendResetEmail' %}\" class=\"text-dark\"><i class=\"fa fa-lock m-r-5\"></i>忘记密码</a>\n                        <a href=\"{% url 'Register' %}\" class=\"text-primary m-l-5\"><b>立即注册</b></a>\n                    </div>\n                </div>\n            </form>\n            </div>\n                </div>\n        </div>\n\n    \t<script>\n            var resizefunc = [];\n        </script>\n        <!-- jQuery  -->\n        <script src=\"/static/assets/js/jquery.min.js\"></script>\n        <script src=\"/static/assets/js/bootstrap.min.js\"></script>\n        <script src=\"/static/assets/js/detect.js\"></script>\n        <script src=\"/static/assets/js/fastclick.js\"></script>\n        <script src=\"/static/assets/js/jquery.slimscroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.blockUI.js\"></script>\n        <script src=\"/static/assets/js/waves.js\"></script>\n        <script src=\"/static/assets/js/wow.min.js\"></script>\n        <script src=\"/static/assets/js/jquery.nicescroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.scrollTo.min.js\"></script>\n\n        <script src=\"/static/assets/plugins/notifyjs/dist/notify.min.js\"></script>\n        <script src=\"/static/assets/plugins/notifications/notify-metro.js\"></script>\n\n        <script src=\"/static/assets/js/jquery.core.js\"></script>\n        <script src=\"/static/assets/js/jquery.app.js\"></script>\n\n        <!--导入通知插件JS -->\n\n         <script type=\"text/javascript\">\n         jQuery(document).ready(function(){\n              $('button[type=submit]').click(function(e) {\n                    e.preventDefault();\n                    $.ajax({\n                        type: \"post\",\n                        dataType:'json',\n                        data:$('.form-horizontal').serialize(),\n                        url: \"{% url 'Login' %}\",\n                        success: function(result){\n                             var msgerror=result.msgerror;\n                             if(msgerror){\n                                 $.Notification.autoHideNotify('error', 'top right', '系统通知',msgerror);\n                             }else{\n                               setTimeout(function() {\n                                            location.href = '{% url 'index' %}';\n                                 },500);\n\n                             }\n                        },\n                    });\n               });\n          });\n        </script>\n\t\n\t</body>\n</html>"
  },
  {
    "path": "templates/webapp/register.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\t\t<meta name=\"description\" content=\"simpletourDevops\">\n\t\t<meta name=\"author\" content=\"www.roddypy.com\">\n\n\t\t<link rel=\"shortcut icon\" href=\"/static/assets/images/favicon_1.ico\">\n\n\t\t<title>SimpletourDevops</title>\n\n\t\t<link href=\"/static/assets/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/core.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/components.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/icons.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/pages.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/responsive.css\" rel=\"stylesheet\" type=\"text/css\" />\n\t\t<link href=\"/static/assets/plugins/sweetalert/dist/sweetalert.css\" rel=\"stylesheet\" type=\"text/css\">\n\n        <!-- HTML5 Shiv and Respond.js IE8 support of HTML5 elements and media queries -->\n        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n        <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js\"></script>\n        <![endif]-->\n\n        <script src=\"/static/assets/js/modernizr.min.js\"></script>\n\n\t</head>\n\t<body>\n\t\t<div class=\"account-pages\"></div>\n\t\t<div class=\"clearfix\"></div>\n\t\t<div class=\"wrapper-page\">\n\t\t\t<div class=\" card-box\">\n\t\t\t\t<div class=\"panel-heading\">\n\t\t\t\t\t<h3 class=\"text-center\"> Simpletour <strong class=\"text-custom\">Devops</strong> </h3>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t<form class=\"form-horizontal m-t-20\" method=\"post\" action=\"{% url 'Register' %}\">\n\n\t\t\t\t\t\t{% csrf_token  %}\n\n\t\t\t\t\t\t<div class=\"form-group \">\n\t\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t\t{{ data.email}}\n\t\t\t\t\t\t\t\t{{ data.email.errors}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n\n\t\t\t\t\t\t<div class=\"form-group \">\n\t\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t\t{{ data.username}}\n\t\t\t\t\t\t\t\t{{ data.username.errors}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div class=\"form-group \">\n\t\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t\t{{ data.password1}}\n\t\t\t\t\t\t\t\t{{ data.password1.errors}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t\t{{ data.password2}}\n\t\t\t\t\t\t\t\t{{ data.password2.errors}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{% for e in regerror %}\n\t\t\t\t\t\t\t{{e}}\n\n\t\t\t\t\t\t{% endfor%}\n\n\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t\t<div class=\"checkbox checkbox-primary\">\n\t\t\t\t\t\t\t\t\t<input id=\"checkbox-signup\" type=\"checkbox\" checked=\"checked\">\n\t\t\t\t\t\t\t\t\t<label for=\"checkbox-signup\">我同意 <a  href=\"#\" data-toggle=\"modal\" data-target=\"#myModal\">请阅读相关说明</a></label>\n\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</div>\n\n\t\t\t\t\t\t<div class=\"form-group text-center m-t-40\">\n\t\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t\t<button class=\"btn btn-pink btn-block text-uppercase waves-effect waves-light\"  type=\"submit\">\n\t\t\t\t\t\t\t\t\t注册\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</form>\n\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"row\">\n\t\t\t\t<div class=\"col-sm-12 text-center\">\n\t\t\t\t\t<p>\n\t\t\t\t\t\t是否已经注册?<a href=\"{%  url 'Login' %}\" class=\"text-primary m-l-5\"><b>登录</b></a>\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div id=\"myModal\" class=\"modal fade\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\" aria-hidden=\"true\" style=\"display: none;\">\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\">×</button>\n                                                    <h4 class=\"modal-title\" id=\"myModalLabel\">用户注册说明</h4>\n                                                </div>\n                                                <div class=\"modal-body\">\n\n                                                    <h4>用户注册需知</h4>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<p>1.您确认，在您成为我们的用户之前已充分阅读、理解并接受本协议的全部内容，一旦您使用本服务，即表示您同意遵循本协议之所有约定。</p>\n                                                    <p>2.本系统为SimpleTour自动化运维系统，注册人不能对本系统相关资源信息进行泄漏</p>\n                                                    <p>3.系统注册用户名为注册人邮箱地址，请牢记使用</p>\n                                                    <p>4.注册人权限需要运维人员进行权限开通方可使用.</p>\n\n                                                </div>\n                                                <div class=\"modal-footer\">\n                                                    <button type=\"button\" class=\"btn btn-default waves-effect\" data-dismiss=\"modal\">关闭</button>\n\n                                                </div>\n                                            </div><!-- /.modal-content -->\n                                        </div><!-- /.modal-dialog -->\n                                    </div>\n\n\t\t<script>\n\t\t\tvar resizefunc = [];\n\t\t</script>\n\n\t\t<script type=\"text/javascript\">\n\n\t\t\tfunction register(){\n\n\t\t\t\tvar username = $(\"#id_username\").val();\n\t\t\t\tvar email = $(\"#id_email\").val();\n\t\t\t\tvar password1 = $(\"#id_password1\");\n\t\t\t\tvar password2 = $(\"#id_password2\");\n\n\t\t\t\talert(username);\n\n\t\t\t\t$.ajax({\n\t\t\t\t\ttype: 'post',\n\t\t\t\t\tdataType:'json',\n\t\t\t\t\tdata:{\n                        username: username,\n                        email: email,\n                        password1: password1,\n                        password2: password2,\n                        csrfmiddlewaretoken:'{{ csrf_token  }}',\n                       },\n\t\t\t\t\turl: \"{% url 'Register' %}\",\n\t\t\t\t\tsuccess: function(result){\n\t\t\t\t\t\talert(OK);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t</script>\n\n\t\t<!-- jQuery  -->\n        <script src=\"/static/assets/js/jquery.min.js\"></script>\n        <script src=\"/static/assets/js/bootstrap.min.js\"></script>\n        <script src=\"/static/assets/js/detect.js\"></script>\n        <script src=\"/static/assets/js/fastclick.js\"></script>\n        <script src=\"/static/assets/js/jquery.slimscroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.blockUI.js\"></script>\n        <script src=\"/static/assets/js/waves.js\"></script>\n        <script src=\"/static/assets/js/wow.min.js\"></script>\n        <script src=\"/static/assets/js/jquery.nicescroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.scrollTo.min.js\"></script>\n        <script src=\"/static/assets/js/jquery.core.js\"></script>\n        <script src=\"/static/assets/js/jquery.app.js\"></script>\n\t    <script src=\"/static/assets/plugins/sweetalert/dist/sweetalert.min.js\"></script>\n\t    <script src=\"/static/assets/pages/jquery.sweet-alert.init.js\"></script>\n\n\t</body>\n</html>"
  },
  {
    "path": "templates/webapp/resetpass.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\t\t<meta name=\"description\" content=\"simpletourDevops\">\n\t\t<meta name=\"author\" content=\"www.roddypy.com\">\n\n\t\t<link rel=\"shortcut icon\" href=\"/static/assets/images/favicon_1.ico\">\n\n\t\t<title>SimpletourDevops</title>\n\n\t\t<link href=\"/static/assets/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/core.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/components.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/icons.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/pages.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/responsive.css\" rel=\"stylesheet\" type=\"text/css\" />\n\t\t<link href=\"/static/assets/plugins/sweetalert/dist/sweetalert.css\" rel=\"stylesheet\" type=\"text/css\">\n\n        <!-- HTML5 Shiv and Respond.js IE8 support of HTML5 elements and media queries -->\n        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n        <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js\"></script>\n        <![endif]-->\n\n        <script src=\"/static/assets/js/modernizr.min.js\"></script>\n\n\t</head>\n\t<body>\n\t\t<div class=\"account-pages\"></div>\n\t\t<div class=\"clearfix\"></div>\n\t\t<div class=\"wrapper-page\">\n\t\t\t<div class=\" card-box\">\n\t\t\t\t<div class=\"panel-heading\">\n\t\t\t\t\t<h3 class=\"text-center\"> Simpletour <strong class=\"text-custom\">Devops</strong> </h3>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t<form class=\"form-horizontal m-t-20\"  role=\"form\" >\n\n\t\t\t\t\t\t{% csrf_token  %}\n\n\t\t\t\t\t\t<div class=\"form-group \">\n\t\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t\t{{ data.password1}}\n\t\t\t\t\t\t\t\t{{ data.password1.errors}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t\t{{ data.password2}}\n\t\t\t\t\t\t\t\t{{ data.password2.errors}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div class=\"form-group text-center m-t-40\">\n\t\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t\t<button class=\"btn btn-pink btn-block text-uppercase waves-effect waves-light\"  type=\"submit\">\n\t\t\t\t\t\t\t\t\t确认重置\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<a class=\"btn btn-pink btn-block text-uppercase waves-effect waves-light\" href=\"{% url 'SendResetEmail' %}\" >重发邮件<a>\n\t\t\t\t\t</form>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\n\t\t<script>\n\t\t\tvar resizefunc = [];\n\t\t</script>\n\n\n\t\t<!-- jQuery  -->\n        <script src=\"/static/assets/js/jquery.min.js\"></script>\n        <script src=\"/static/assets/js/bootstrap.min.js\"></script>\n        <script src=\"/static/assets/js/detect.js\"></script>\n        <script src=\"/static/assets/js/fastclick.js\"></script>\n        <script src=\"/static/assets/js/jquery.slimscroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.blockUI.js\"></script>\n        <script src=\"/static/assets/js/waves.js\"></script>\n        <script src=\"/static/assets/js/wow.min.js\"></script>\n        <script src=\"/static/assets/js/jquery.nicescroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.scrollTo.min.js\"></script>\n\n\t\t<script src=\"/static/assets/plugins/notifyjs/dist/notify.min.js\"></script>\n        <script src=\"/static/assets/plugins/notifications/notify-metro.js\"></script>\n\n\n        <script src=\"/static/assets/js/jquery.core.js\"></script>\n        <script src=\"/static/assets/js/jquery.app.js\"></script>\n\t    <script src=\"/static/assets/plugins/sweetalert/dist/sweetalert.min.js\"></script>\n\t    <script src=\"/static/assets/pages/jquery.sweet-alert.init.js\"></script>\n\n\t\t<script>\n\t\t\tjQuery(document).ready(function(){\n\t\t\t\t  $('button[type=submit]').click(function(e) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t$.ajax({\n\t\t\t\t\t\t\ttype: \"post\",\n\t\t\t\t\t\t\tdataType:'json',\n\t\t\t\t\t\t\tdata:$('.form-horizontal').serialize(),\n\t\t\t\t\t\t\turl: \"{% url 'ResetPassword' token%}\",\n\t\t\t\t\t\t\tsuccess: function(result){\n\t\t\t\t\t\t\t\t var msgerror=result.msgerror;\n\t\t\t\t\t\t\t\t var msginfo=result.msginfo;\n\n\t\t\t\t\t\t\t\t if(msgerror){\n\t\t\t\t\t\t\t\t\t $.Notification.autoHideNotify('error', 'top right', '系统通知',msgerror);\n\t\t\t\t\t\t\t\t }else{\n\t\t\t\t\t\t\t\t \t $.Notification.autoHideNotify('success','top right','系统通知',msginfo );\n\t\t\t\t\t\t\t\t     setTimeout(function() {\n\t\t\t\t\t\t\t\t\t\t\t\tlocation.href = '{% url 'Login' %}';\n\t\t\t\t\t\t\t\t\t },2500);\n\t\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t   });\n\t\t\t  });\n\n\n\n\t\t</script>\n\n\t</body>\n</html>"
  },
  {
    "path": "templates/webapp/sendresetpw.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\t\t<meta name=\"description\" content=\"A fully featured admin theme which can be used to build CRM, CMS, etc.\">\n\t\t<meta name=\"author\" content=\"www.divmb.com\">\n\n\t\t<link rel=\"shortcut icon\" href=\"/static/images/favicon_1.ico\">\n\n\t\t<title>SimpletourDevops</title>\n\n\t\t<link href=\"/static/assets/css/bootstrap.min.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/core.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/components.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/icons.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/pages.css\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"/static/assets/css/responsive.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n        <!-- HTML5 Shiv and Respond.js IE8 support of HTML5 elements and media queries -->\n        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n        <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js\"></script>\n        <![endif]-->\n\n        <script src=\"/static/assets/js/modernizr.min.js\"></script>\n\n\t</head>\n\t<body>\n\n\t\t<div class=\"account-pages\"></div>\n\t\t<div class=\"clearfix\"></div>\n\t\t<div class=\"wrapper-page\">\n\t\t\t<div class=\" card-box\">\n\t\t\t\t<div class=\"panel-heading\">\n\t\t\t\t\t<h3 class=\"text-center\"> 找回帐号密码 </h3>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"panel-body\">\n\t\t\t\t\t<form  class=\"form-horizontal text-center\" role=\"form\" >\n\t\t\t\t\t\t<div class=\"alert alert-info alert-dismissable\">\n\t\t\t\t\t\t\t<button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t×\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t请输入您注册时的Email地址!\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{% csrf_token %}\n\t\t\t\t\t\t<div class=\"form-group m-b-0\">\n\t\t\t\t\t\t\t<div class=\"input-group\">\n\t\t\t\t\t\t\t\t<input type=\"email\" class=\"form-control\" name=\"email\" placeholder=\"输入邮箱\" required=\"\">\n\t\t\t\t\t\t\t\t<span class=\"input-group-btn\">\n\t\t\t\t\t\t\t\t\t<button type=\"submit\" class=\"btn btn-pink w-sm waves-effect waves-light\" >\n\t\t\t\t\t\t\t\t\t\t重置\n\t\t\t\t\t\t\t\t\t</button> \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</div>\n\t\t\t\t\t</form>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\n\n\t\t</div>\n\n\t\t<script>\n\t\t\tvar resizefunc = [];\n\t\t</script>\n\n\t\t<!-- jQuery  -->\n        <script src=\"/static/assets/js/jquery.min.js\"></script>\n        <script src=\"/static/assets/js/bootstrap.min.js\"></script>\n        <script src=\"/static/assets/js/detect.js\"></script>\n        <script src=\"/static/assets/js/fastclick.js\"></script>\n        <script src=\"/static/assets/js/jquery.slimscroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.blockUI.js\"></script>\n        <script src=\"/static/assets/js/waves.js\"></script>\n        <script src=\"/static/assets/js/wow.min.js\"></script>\n        <script src=\"/static/assets/js/jquery.nicescroll.js\"></script>\n        <script src=\"/static/assets/js/jquery.scrollTo.min.js\"></script>\n\n\t\t<script src=\"/static/assets/plugins/notifyjs/dist/notify.min.js\"></script>\n        <script src=\"/static/assets/plugins/notifications/notify-metro.js\"></script>\n\n\n        <script src=\"/static/assets/js/jquery.core.js\"></script>\n        <script src=\"/static/assets/js/jquery.app.js\"></script>\n\t\t<script>\n\t\t\tjQuery(document).ready(function(){\n\t\t\t\t  $('button[type=submit]').click(function(e) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t$.ajax({\n\t\t\t\t\t\t\ttype: \"post\",\n\t\t\t\t\t\t\tdataType:'json',\n\t\t\t\t\t\t\tdata:$('.form-horizontal').serialize(),\n\t\t\t\t\t\t\turl: \"{% url 'SendResetEmail' %}\",\n\t\t\t\t\t\t\tsuccess: function(result){\n\t\t\t\t\t\t\t\t var msgerror=result.msgerror;\n\t\t\t\t\t\t\t\t var msginfo=result.msginfo;\n\t\t\t\t\t\t\t\t if(msgerror){\n\t\t\t\t\t\t\t\t\t $.Notification.autoHideNotify('error', 'top right', '系统通知',msgerror);\n\t\t\t\t\t\t\t\t }else{\n\t\t\t\t\t\t\t\t \t $.Notification.autoHideNotify('success','top right','系统通知',msginfo );\n\t\t\t\t\t\t\t\t     setTimeout(function() {\n\t\t\t\t\t\t\t\t\t\t\t\tlocation.href = '{% url 'Login' %}';\n\t\t\t\t\t\t\t\t\t },2500);\n\n\t\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t   });\n\t\t\t  });\n\n\n\n\t\t</script>\n\n\n\t</body>\n</html>"
  },
  {
    "path": "templates/webapp/sysrestuserpassword.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n<div class=\"panel-body\">\n\t\t\t\t\t<div class=\"row\" >\n\t\t\t\t\t\t<div class=\"col-lg-4\" >\n\t\t\t\t\t<form class=\"form-horizontal m-t-20\"  method=\"post\" action=\"{% url 'SysrestUserpassword' id %}\">\n\n\t\t\t\t\t\t{% csrf_token  %}\n\n\t\t\t\t\t\t<div class=\"form-group \">\n\t\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t\t{{ data.password1}}\n\t\t\t\t\t\t\t\t{{ data.password1.errors}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t\t{{ data.password2}}\n\t\t\t\t\t\t\t\t{{ data.password2.errors}}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div class=\"form-group text-center m-t-40\">\n\t\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t\t<button class=\"btn btn-pink btn-block text-uppercase waves-effect waves-light\"  type=\"submit\">\n\t\t\t\t\t\t\t\t\t确认重置\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</form>\n\t\t\t\t</div>\n\t\t\t\t</div>\n\t</div>\n\n{% endblock %}\n\n"
  },
  {
    "path": "templates/webapp/userinfo.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n<link href=\"/static/assets/plugins/select2/select2.css\" rel=\"stylesheet\" type=\"text/css\">\n<link href=\"/static/assets/plugins/bootstrap-select/dist/css/bootstrap-select.min.css\" rel=\"stylesheet\">\n\n<div class=\"container\">\n   <!-- Page-Title -->\n        <div class=\"row\">\n            <div class=\"col-sm-12\">\n                <h4 class=\"page-title\">个人信息</h4>\n                <ol class=\"breadcrumb\">\n                    <li>\n                        <a href=\"#\">用户设置</a>\n                    </li>\n                    <li class=\"active\">\n                        <a href=\"{% url 'Userinfo' %}\">个人信息</a>\n                    </li>\n                </ol>\n            </div>\n        </div>\n        <div class=\"col-md-8\">\n            <div class=\"card-box\">\n                <h4 class=\"m-t-0 header-title\"><b>个人信息</b></h4>\n                <br>\n                <div class=\"grid-structure\">\n                    <div class=\"row\">\n                        <div class=\"col-md-4\">\n                            <div class=\"about-info-p\">\n                                <strong>姓名:</strong>\n                                <br>\n                                <p class=\"text-muted\">{{Userdata.name}}</p>\n                            </div>\n                            <div class=\"about-info-p\">\n                                <strong>用户名:</strong>\n                                <br>\n                                <p class=\"text-muted\">{{Userdata.username}}</p>\n                            </div>\n                            <div class=\"about-info-p\">\n                                <strong>联系方式:</strong>\n                                <br>\n                                <p class=\"text-muted\">{{Userdata.phone}}</p>\n                            </div>\n                            <div class=\"about-info-p\">\n                                <strong>邮箱地址:</strong>\n                                <br>\n                                <p class=\"text-muted\">{{Userdata.email}}</p>\n                            </div>\n                            <div class=\"about-info-p\">\n                                <strong>Q Q:</strong>\n                                <br>\n                                <p class=\"text-muted\">{{Userdata.QQ}}</p>\n                            </div>\n                        </div>\n                        <div class=\"col-md-4\">\n                            <div class=\"about-info-p\">\n                                <strong>创建时间:</strong>\n                                <br>\n                                <p class=\"text-muted\">{{Userdata.date_joined | date:\"Y-m-d H:i\"}}</p>\n                            </div>\n                            <div class=\"about-info-p\">\n                                <strong>最后登录:</strong>\n                                <br>\n                                <p class=\"text-muted\">{{Userdata.last_login | date:\"Y-m-d H:i\"}}</p>\n                            </div>\n                            <div class=\"about-info-p\">\n                                <strong>用户状态:</strong>\n                                <br>\n                                {% if Userdata.is_active %}\n                                    <p class=\"text-muted\">激活</p>\n                                {% else %}\n                                    <p class=\"text-muted\">禁用</p>\n                                {% endif%}\n                            </div>\n                            <div class=\"about-info-p\">\n                                <strong>年龄:</strong>\n                                <br>\n                                <p class=\"text-muted\">{{Userdata.age}}</p>\n                            </div>\n                            <div class=\"about-info-p\">\n                                <strong>部门:</strong>\n                                <br>\n                                <p class=\"text-muted\">{{Userdata.department}}</p>\n                            </div>\n\n                             <div class=\"about-info-p\">\n                                <strong>用户组:</strong>\n                                <br>\n                                 {% for i in Userdata.groups.all %}\n                                    <p class=\"text-muted\">{{i.name}}</p>\n                                 {% endfor %}\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n</div>\n\n<script src=\"/static/assets/plugins/bootstrap-select/dist/js/bootstrap-select.min.js\" type=\"text/javascript\"></script>\n<script src=\"/static/assets/plugins/select2/select2.min.js\" type=\"text/javascript\"></script>\n\n{% endblock %}\n"
  },
  {
    "path": "uwsgi.ini",
    "content": "[uwsgi]\nsocket = 0.0.0.0:8098\nchmod-socket = 666\npy-autoreload=3\nchdir=/data/SimpletourDevops/\nmodule=SimpletourDevops.wsgi\nuid=www\ngit=www\nmaster = true         \nworkers = 1\nreload-mercy = 10     \nenable-threads=true\nvacuum = true         \nmax-requests = 1000   \nlimit-as = 512\nbuffer-size = 30000\npidfile = /var/run/uwsgi_devops.pid    \n\n\n"
  },
  {
    "path": "webapp/Extends/PageList.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\n\nfrom django.utils.safestring import mark_safe\n\ndef Page(page,url,all_pages_count,search=str('')):\n    '''\n    :param page:当前页\n    :param all_pages_count:总页数\n    :return:分页后的html字符串\n    '''\n    page_html=[]\n    print search\n    a_html = '''<li><a href=\"%s/1%s\">首页</a></li>''' %(url,str(search))\n    page_html.append(a_html)\n    if page>1:\n        a_html = '''<li><a href=\"%s/%d%s\">上一页</a></li>'''%(url,page-1,str(search))\n    else:\n        a_html = '''<li class=\"disabled\"><a href=\"#\">上一页</a></li>'''\n    page_html.append(a_html)\n    #11个页码\n    if all_pages_count<11:\n        begain=0\n        end=all_pages_count\n    #总页数大于11\n    else:\n        if page<6:\n            begain=0\n            end =12\n        else:\n            if page+6>all_pages_count:\n                begain=page-5\n                end = all_pages_count\n            else:\n                begain=page -5\n                end =page+5\n\n    for i in range(begain,end):\n        if page == i+1:\n            a_html='''<li class=\"page-number active\"><a href=\"%s/%d%s\">%d</a></li>'''%(url,i+1,str(search),i+1)\n        else:\n            a_html='''<li><a href=\"%s/%d%s\">%d</a></li>'''%(url,i+1,str(search),i+1)\n        page_html.append(a_html)\n    if page<all_pages_count:\n        a_html = '''<li><a href=\"%s/%d%s\">下一页</a></li>'''%(url,page+1,str(search))\n    else:\n        a_html = '''<li class=\"disabled\"><a href=\"#\">下一页</a></li>'''\n\n    page_html.append(a_html)\n    a_html = '''<li><a href=\"%s/%d%s\">尾页</a></li>'''%(url,all_pages_count,str(search))\n    page_html.append(a_html)\n    page = mark_safe(' '.join(page_html))\n    return  page\n\ndef PageCount(page):\n    per_item = 15\n    page =int(page)\n    start = (page-1)*per_item\n    end = page*per_item\n    return page,start,end,per_item\n\n"
  },
  {
    "path": "webapp/Extends/__init__.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\n"
  },
  {
    "path": "webapp/__init__.py",
    "content": ""
  },
  {
    "path": "webapp/admin.py",
    "content": "#coding:utf8\nfrom django.contrib import admin\nfrom django.contrib.admin import models\nfrom django import forms\nfrom webapp.models import *\nfrom django.forms import ModelForm,TextInput,Textarea\nfrom django.contrib.auth.admin import UserAdmin  # 从django继承\nfrom django.contrib.auth.forms import UserCreationForm, UserChangeForm # admin中涉及到的两个表单\n\nadmin.AdminSite.site_header ='管理系统后台'\nadmin.AdminSite.site_title = '运维后台'\n\n\n\n\n#以下代码曲东同学分享，博客地址http://www.cnblogs.com/caseast/p/5909987.html\nclass MyUserCreationForm(UserCreationForm):  # 增加用户表单重新定义，继承自UserCreationForm\n    def __init__(self, *args, **kwargs):\n        super(MyUserCreationForm, self).__init__(*args, **kwargs)\n        self.fields['email'].required = True\n        self.fields['name'].required = True\n\nclass MyUserChangeForm(UserChangeForm):  # 编辑用户表单重新定义，继承自UserChangeForm\n    def __init__(self, *args, **kwargs):\n        super(MyUserChangeForm, self).__init__(*args, **kwargs)\n        self.fields['email'].required = True\n        self.fields['name'].required = True\n\n\n\nclass CustomUserAdmin(UserAdmin):\n    def __init__(self, *args, **kwargs):\n        super(CustomUserAdmin, self).__init__(*args, **kwargs)\n        self.list_display = ('username', 'name', 'email', 'is_staff', 'is_superuser','phone')\n        self.search_fields = ('username', 'email', 'name')\n        self.form = MyUserChangeForm\n        self.add_form = MyUserCreationForm\n\n\n    def changelist_view(self, request, extra_context=None):\n        if not request.user.is_superuser:\n            self.fieldsets = ((None, {'fields': ('username', 'password',)}),\n                              (('Personal info'), {'fields': ('name', 'email','phone')}),\n                              (('Permissions'), {'fields': ('is_active', 'is_staff', 'groups')}),\n                              (('Important dates'), {'fields': ('last_login', 'date_joined')}),\n                              )\n            self.add_fieldsets = ((None, {'classes': ('wide',),\n                                          'fields': ('username', 'name', 'password1', 'password2', 'email', 'is_active',\n                                                     'is_staff', 'groups','phone'),\n                                          }),\n                                  )\n        else:\n            self.fieldsets = (((u'登录信息'), {'fields': ('username', 'password',)}),\n                              ((u'用户信息'), {'fields': ('name', 'email', 'phone')}),\n                              ((u'用户权限'), {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups')}),\n                              ((u'加入时间'), {'fields': ('last_login', 'date_joined')}),\n                              )\n            self.add_fieldsets = ((None, {'classes': ('wide',),\n                                          'fields': ('username', 'name', 'password1', 'password2', 'email', 'phone','QQ', 'age','department', 'is_active',\n                                                     'is_staff', 'is_superuser', 'groups',),\n                                          }),\n                                  )\n\n        return super(CustomUserAdmin, self).changelist_view(request, extra_context)\n\n\n\n# Register your models here.\nclass UserAdmin(admin.ModelAdmin):\n    list_display = ('name','phone', 'email','department','is_staff',  'is_superuser')\n    search_fields = ('name','email','username')\n    list_filter = ('department','is_active','groups')\n\n\nclass LoginHistory(admin.ModelAdmin):\n    list_display = ('user','user_ip','login_time','logout_time','request_method','request_url')\n\n\n#admin.site.register(Suser,CustomUserAdmin)\nadmin.site.register(Suser,CustomUserAdmin)\nadmin.site.register(Department)\nadmin.site.register(History_Login,LoginHistory)\n\n\n\n"
  },
  {
    "path": "webapp/apps.py",
    "content": "from __future__ import unicode_literals\n\nfrom django.apps import AppConfig\n\n\nclass WebappConfig(AppConfig):\n    name = 'webapp'\n\n\n"
  },
  {
    "path": "webapp/forms.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\n\nfrom django import forms\n\n\nclass SimpleLogin(forms.Form):\n    username = forms.EmailField(label='email',\n                                error_messages={'required': u'请输入用户名', 'invalid':u'Email格式错误'},\n                                widget=forms.EmailInput(attrs={'class': 'form-control',\n                                                               'placeholder': '邮 箱',\n                                                               }),\n                                )\n    password = forms.CharField(label='password',\n                               widget=forms.PasswordInput(attrs={'class':'form-control',\n                                                                 'placeholder': '密  码',\n                                                                 }))\n\nclass Register(forms.Form):\n\n    email = forms.EmailField(label='email',\n                                error_messages={'required': u'请输入Email', 'invalid':u'Email格式错误'},\n                                widget=forms.EmailInput(attrs={'class': 'form-control',\n                                                               'placeholder': '邮 箱',\n                                                               }),\n                                )\n\n    username = forms.CharField(label='username',\n                                error_messages={'required': u'请输入用户名', 'invalid':u'用户名格式错误'},\n                                widget=forms.TextInput(attrs={'class': 'form-control',\n                                                               'placeholder': '用户名',\n                                                               }),\n                                )\n\n    password1 = forms.CharField(label='password1',\n                               widget=forms.PasswordInput(attrs={'class':'form-control',\n                                                                 'placeholder': '密  码',\n                                                                 }))\n\n    password2 = forms.CharField(label='password2',\n                               widget=forms.PasswordInput(attrs={'class':'form-control',\n                                                                 'placeholder': '再次输入密码',\n                                                                 }))\n\n    def pwd_validate(self,pwd1,pwd2):\n        return pwd1==pwd2\n\n\nclass ResetPassword(forms.Form):\n\n\n    password1 = forms.CharField(label='password1',\n                               widget=forms.PasswordInput(attrs={'class':'form-control',\n                                                                 'placeholder': '密  码',\n                                                                 }))\n\n    password2 = forms.CharField(label='password2',\n                               widget=forms.PasswordInput(attrs={'class':'form-control',\n                                                                 'placeholder': '再次输入密码',\n                                                                 }))\n\n    def pwd_validate(self,pwd1,pwd2):\n        return pwd1==pwd2\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "webapp/migrations/__init__.py",
    "content": ""
  },
  {
    "path": "webapp/models.py",
    "content": "# -*- coding: utf-8 -*-\nfrom __future__ import unicode_literals\nfrom django.db import models\nfrom django.contrib.auth.models import AbstractBaseUser,BaseUserManager,PermissionsMixin\nfrom django.utils import six, timezone\n\nclass Department(models.Model):\n    name = models.CharField(max_length=64, unique=True)\n    def __unicode__(self):\n        return self.name\n\n    class Meta:\n        verbose_name = u'部门管理'\n        verbose_name_plural = u\"部门管理\"\n        permissions = (\n            (\"webapp_department_view\", u\"Can view %s\" % verbose_name),\n        )\n\nclass MyUserManager(BaseUserManager):\n    def create_user(self, email, username, password=None):\n        \"\"\"\n        Creates and saves a User with the given email, date of\n        birth and password.\n        \"\"\"\n        if not email:\n            raise ValueError('Users must have an email address')\n\n        user = self.model(\n            email=self.normalize_email(email),\n            username=username,\n        )\n\n        user.set_password(password)\n        user.is_active = False\n        user.save(using=self._db)\n        return user\n\n    def create_superuser(self, email, username, password):\n        \"\"\"\n        Creates and saves a superuser with the given email, date of\n        birth and password.\n        \"\"\"\n        user = self.create_user(email,\n            username=username,\n            password=password,\n        )\n\n        user.is_staff = True\n        user.is_superuser = True\n        user.is_active=True\n\n        user.save(using=self._db)\n        return user\n\nclass Suser(AbstractBaseUser,PermissionsMixin):\n\n    email = models.EmailField(\n        verbose_name=u'邮箱',\n        max_length=255,\n        unique=True,\n    )\n\n    username = models.CharField(max_length=50,verbose_name=u'用户名')\n\n    is_active = models.BooleanField(default=True, verbose_name=u'激活用户',help_text=(\n            '设置用户状态。'\n\n        ),)\n\n    is_staff = models.BooleanField(default=False,verbose_name=u'职员状态',help_text=(\n            '是否设置用户可登录管理站点。'\n\n        ),)\n\n\n    #全名\n    name = models.CharField(u'姓名',max_length=20, null=True)\n\n    #电话号码\n    phone = models.CharField(max_length=12,null=True,blank=True,verbose_name=u'联系方式')\n\n    #部门\n    department = models.ForeignKey('Department',null=True,blank=True,verbose_name=u'部门')\n\n    #用户QQ信息\n    QQ = models.CharField(max_length=50,null=True,blank=True)\n\n    #年龄\n    age = models.IntegerField(null=True,blank=True,verbose_name=u'年龄')\n\n    date_joined = models.DateTimeField(verbose_name=u'创建时间', default=timezone.now)\n\n    objects = MyUserManager()\n\n    USERNAME_FIELD = 'email'\n    REQUIRED_FIELDS = ['username']\n\n    def get_full_name(self):\n        # The user is identified by their email address\n        return self.email\n\n    def get_short_name(self):\n        # The user is identified by their email address\n        return self.email\n\n    def __str__(self):              # __unicode__ on Python 2\n        return self.email\n\n\n    @property\n    def is_admin(self):\n        \"Is the user a member of staff?\"\n        # Simplest possible answer: All admins are staff\n        return self.is_staff\n\n\n    def __unicode__(self):\n        return self.email\n\n    class Meta:\n        verbose_name = u'用户管理'\n        verbose_name_plural = u\"用户管理\"\n        #unique_together = ('email', )\n\n        permissions = (\n            (\"webapp_users_view\", u\"查看用户\"),\n            (\"webapp_users_view_info\", u\"查看用户详细\"),\n            (\"system_index_view\",\"系统首页\"),\n        )\n\nclass History_Login(models.Model):\n    user = models.ForeignKey(Suser)\n    login_time = models.DateTimeField(auto_now_add=True)\n    logout_time = models.DateTimeField(auto_now=True)\n    request_method = models.CharField(max_length=12, null=True)\n    request_url = models.CharField(max_length=100, null=True)\n    user_ip = models.GenericIPAddressField()\n\n    class Meta:\n        verbose_name = u'登录历史'\n        verbose_name_plural = u\"登录历史\"\n        permissions = (\n            (\"webapp_history_view\", u\"Can view %s\" %verbose_name),\n        )\n\nclass Operation(models.Model):\n    Opuser = models.CharField(max_length=12, null=True)\n    Optime = models.DateTimeField(auto_now_add=True)\n    Opaction = models.CharField(max_length=50, null=True)\n    class Meta:\n        verbose_name = u'操作记录'\n        verbose_name_plural = u'操作记录'\n\n\n\n"
  },
  {
    "path": "webapp/tasks.py",
    "content": "#!/usr/bin/env python\n#coding:utf-8\n\n__author__ = 'Luodi'\n\nimport time,os\n\nfrom celery import Celery\nfrom django.core.mail import send_mail\nfrom Publicapi.saltstackapi.SaltConApi import SaltApi\nfrom Publicapi.dockerapi.Manager import Dockerapi\nfrom dockermanager.Docker_Controller import GetDockerServerinfo,GetDockerImages\nfrom datetime import timedelta\nfrom servermanager.models import *\n\nfrom Publicapi.saltstackapi.Assets_Module import *\n\nfrom django.conf import settings\n\n\nfrom django.core import signals\nfrom django.db import close_old_connections\nfrom saltadmin.Minions_Controller import GetMinionConf,GetSaltJobs\n\n\n# 取消信号关联，实现数据库长连接\nsignals.request_finished.disconnect(close_old_connections)\n\nos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'SimpletourDevops.settings')\n\ncelery = Celery('tasks', backend='redis://192.168.2.232:6379/0',broker='redis://192.168.2.232:6379/0')\n\n\n\ncelery.config_from_object('django.conf:settings')\ncelery.autodiscover_tasks(lambda: settings.INSTALLED_APPS)\n\n\n\ncelery.conf.update(\n    CELERYBEAT_SCHEDULE = {\n        'every-minute': {\n            'task': 'webapp.tasks.DockerServers',\n            'schedule': timedelta(seconds=10)\n        },\n\n        'minions': {\n            'task': 'webapp.tasks.GetMinionStatus',\n            'schedule': timedelta(seconds=30)\n        },\n        'getjob': {\n            'task': 'webapp.tasks.GetSaltjobs',\n            'schedule': timedelta(seconds=60)\n        },\n    }\n)\n\n\nEMAIL_URL = 'http://192.168.4.223:8888/web/activate'\nReset_Pass = 'http://192.168.4.223:8888/web/resetpass'\n\n@celery.task\ndef sendmail(mail):\n    print \"++++++++++++++++++++++++++++++++++\"\n    print('sending mail to %s ......' %mail['to'])\n    time.sleep(5.0)\n    print('mail sent.')\n    emailmessages=\"用户注册激活邮件，请您点击: %s/%s\" %(EMAIL_URL,mail['string'])\n    send_mail(u\"SimpletourDevops用户激活邮件\",emailmessages,'923401910@qq.com',[mail['to'],],fail_silently=True)\n    print \"---------------------------------\"\n    return mail['to']\n\n@celery.task\ndef resetpass(mail):\n    print \"++++++++++++++++++++++++++++++++++\"\n    print('sending mail to %s ......' %mail['to'])\n    time.sleep(5.0)\n    print('mail sent.')\n    emailmessages=\"用户重置密码连接，请您点击:%s/%s\" %(Reset_Pass,mail['string'])\n    send_mail(u\"SimpletourDevops重置密码\",emailmessages,'923401910@qq.com',[mail['to'],],fail_silently=True)\n    print \"---------------------------------\"\n    return mail['to']\n\n@celery.task()\ndef SaltGrains(minion):\n    salt=SaltApi()\n    print \"------------------------\"\n    print \"%s\"  %minion['id']\n    data=salt.grainsall(minion['id'])\n    print \"------------------------\"\n    return data\n\n@celery.task()\ndef StopContainer(docker):\n    print \"-------------stop------container-----\"\n    dockerc=Dockerapi(docker['host'],docker['port'])\n    data=dockerc.StopContainer(docker['container'])\n    result={'resultInfo':u'容器停止成功!!', 'type': 'stop'}\n    return {'result': result}\n\n@celery.task()\ndef StartContainer(IP,port,container):\n    print \"|------------start------container------------|\"\n    dockerc=Dockerapi(IP,port)\n    data = dockerc.StartContainer(container)\n    result={'resultInfo':u'容器启动成功!!', 'type':'start'}\n    return {'result': result}\n\n@celery.task()\ndef RestartContainer(IP,port,container):\n    print \"-------------restart---container %s \" % container\n    dockerc=Dockerapi(IP,port)\n    dockerc.RestartContainer(container)\n    result={'resultInfo':u'重启容器成功!!','type':'restart'}\n    print \"ssssssssssssssssss\"\n    return {'result': result}\n\n@celery.task()\ndef SaltGrainsAll():\n    salt=SaltApi()\n    print \"----------Grainsall------------\"\n    clientkey=salt.List_all_keys()['minions']\n    for i in clientkey:\n        data=salt.grainsall(i)\n    return clientkey\n\n#定时任务\n@celery.task()\ndef DockerServers():\n    print u\"-----------------获取docker容器列表及状态---------------\"\n    containerdata=GetDockerServerinfo()\n    print u\"-----------------获取成功-----------------------\"\n    print u\"-----------------获取最新images列表-------------\"\n    imagedata=GetDockerImages()\n    print u\"-----------------获取镜像列表成功---------------\"\n    return containerdata,imagedata\n\n@celery.task()\ndef GetMinionStatus():\n    print u\"---------------获取saltstackminion状态\"\n    data = GetMinionConf()\n    print data\n\n@celery.task()\ndef GetSaltjobs():\n    print u\"--------------------获取jobs----\"\n    data  = GetSaltJobs()\n\n\n#更新资产\n@celery.task()\ndef UpdateServerInfo(serverid):\n    salt = SaltApi('http://192.168.2.150:8000/','roddy','roudy_123456')\n    serverdata = Server.objects.get(id=serverid)\n    saltid=serverdata.saltid\n    data=salt.grainsall(saltid)\n    ServerInfo=data\n\n    #CPU信息\n    CpuData=ServerCPUInfo(ServerInfo,saltid)\n    CpuINFO=CpuData.ServerCPU()\n\n    #DISK信息\n    DiskData =ServerDiskInfo(ServerInfo,saltid)\n    DiskINFO=DiskData.ServerDISK()\n\n    #NIC信息\n    NICData = ServerNICInfo(ServerInfo,saltid)\n    NICINFO=NICData.ServerNIC()\n    BaseINFO=CpuINFO['Serverbaseinfo']\n\n    #--------------------------更新CPU信息-------------------------\n    parentsn=CpuINFO['Serverbaseinfo']['sn']\n    Cpudict=CpuINFO['servercpuinfo']\n    Thread=Cpudict['thread']\n    L1cache=Cpudict['L1cache']\n    L2cache=Cpudict['L2cache']\n    L3cache=Cpudict['L3cache']\n    model=Cpudict['model']\n    Vendordata=Cpudict['model']\n    Vendor=Vendordata.split()[0]\n    Architecture=Cpudict['architecture']\n    cpu_mhz=Cpudict['cpu_mhz']\n    uuid=Cpudict['uuid']\n\n    if Cpu.objects.filter(parent_sn=parentsn):\n        ChangeCpu=Cpu.objects.get(parent_sn=parentsn)\n        ChangeCpu.Thread=Thread\n        ChangeCpu.L1cache=L1cache\n        ChangeCpu.L2cache=L2cache\n        ChangeCpu.L3cache=L3cache\n        ChangeCpu.Vendor=Vendor\n        ChangeCpu.model=model\n        ChangeCpu.Architecture = Architecture\n        ChangeCpu.cpu_mhz=cpu_mhz\n        ChangeCpu.parent_sn = parentsn\n        ChangeCpu.uuid= uuid\n        ChangeCpu.save()\n    else:\n        NewCpu=Cpu(Thread=Thread,\n                   uuid=uuid,\n                   model=model,\n                   Architecture=Architecture,\n                   cpu_mhz=cpu_mhz,\n                   L1cache=L1cache,\n                   Vendor=Vendor,\n                   L2cache=L2cache,\n                   L3cache=L3cache,\n                   parent_sn=parentsn,)\n        NewCpu.save()\n\n\n    #--------------------------更新服务器信息------------------------\n    serverdata.hostname = BaseINFO['hostname']\n    serverdata.sn = BaseINFO['sn']\n    if Cpu.objects.filter(parent_sn=BaseINFO['sn']):\n        Cpuid=Cpu.objects.get(parent_sn=parentsn)\n        serverdata.cpu = Cpuid\n\n    serverdata.cpu_count = BaseINFO['cpu_count']\n    serverdata.saltid = BaseINFO['saltid']\n    serverdata.mem = BaseINFO['mem']\n    serverdata.swap = BaseINFO['swap']\n    serverdata.platform = BaseINFO['platform']\n    serverdata.system = BaseINFO['system']\n    serverdata.version = BaseINFO['version']\n    serverdata.cpu_core_count =BaseINFO['cpu_core_count']\n    serverdata.save()\n\n\n    #---------------------------获取网卡信息----------------------------\n    Nicdict=NICINFO['servernicinfo']['nicinfo']\n    parentsn=NICINFO['Serverbaseinfo']['sn']\n    for nicname,nicvalue in Nicdict.items():\n        #排除lo和docker网卡\n        if nicname not in ['eth1','eth0','em1','em0','p3p1','p1p1','p8p1']:\n            continue\n        if nicvalue.get('inet'):\n            mac = nicvalue['hwaddr']\n            Model = nicvalue['Model']\n            nicstatus = nicvalue['up']\n            uuid = nicvalue['uuid']\n            name = nicname\n            ip = nicvalue['inet'][0]['address']\n            netmask = nicvalue['inet'][0]['netmask']\n\n            if NIC.objects.filter(mac=mac):\n                OldNic=NIC.objects.get(mac=mac)\n                OldNic.uuid = uuid\n                OldNic.name = name\n                OldNic.model = Model\n                OldNic.ip = ip\n                OldNic.mac = mac\n                OldNic.parent_sn = parentsn\n                OldNic.netmask = netmask\n                OldNic.nicstatus = nicstatus\n                OldNic.save()\n            else:\n                Newnic=NIC(uuid=uuid,name=name,model=Model,parent_sn=parentsn,ip=ip,mac=mac,netmask=netmask,nicstatus=nicstatus)\n                Newnic.save()\n        else:\n            continue\n\n    #删除以前网卡信息\n    for nic in serverdata.nic.all():\n        serverdata.nic.remove(nic)\n\n    #添加网卡到服务器\n    nicdata = NIC.objects.filter(parent_sn=parentsn)\n    for nic in nicdata:\n        sdata = Server.objects.get(sn=parentsn)\n        sdata.nic.add(nic)\n\n    #---------------获取硬盘信息-------------------------\n    parentsn=DiskINFO['Serverbaseinfo']['sn']\n    Diskdict=DiskINFO['serverdiskinfo']['diskinfo']\n    for diskname,diskvalue in Diskdict.items():\n        name = diskvalue['name']\n        uuid = diskvalue['uuid']\n        capacity= diskvalue['size']\n        disk_type=diskvalue['type']\n\n        if Disk.objects.filter(uuid=uuid):\n            for OldDisk in Disk.objects.filter(parent_sn=parentsn):\n                OldDisk.name = name\n                OldDisk.capacity=capacity\n                OldDisk.parent_sn=parentsn\n                OldDisk.disk_type = disk_type\n                OldDisk.save()\n        else:\n            NewDisk=Disk(name=name,uuid=uuid,parent_sn=parentsn,capacity=capacity,disk_type=disk_type)\n            NewDisk.save()\n\n    #删除以前磁盘信息\n    for disk in serverdata.disk.all():\n        serverdata.disk.remove(disk)\n\n    #添加磁盘到服务器\n    diskdata = Disk.objects.filter(parent_sn=parentsn)\n    for disk in diskdata:\n        sdata = Server.objects.get(sn=parentsn)\n        sdata.disk.add(disk)\n\n    serverinfo={}\n    Info_Data = Server.objects.get(id=serverid)\n    serverinfo['hostname']=Info_Data.hostname\n    serverinfo['last_update']= Info_Data.update_time.strftime(\"%Y-%m-%d %H:%M:%S\")\n    serverinfo['sn'] = Info_Data.sn\n    serverinfo['cpu'] = Info_Data.cpu_count\n    niclist=[]\n    for i in Info_Data.nic.all():\n        niclist.append(i.ip)\n    serverinfo['nic'] = niclist\n\n    disklist=[]\n    for d in Info_Data.disk.all():\n        disklist.append(d.name)\n    serverinfo['disk']=disklist\n\n    return {'result': serverinfo}\n\n@celery.task()\ndef DeleteContainer(IP,port,container):\n    print \"-------------delete---container %s \" %container\n    dockerc=Dockerapi(IP,port)\n    dockerc.removeContainer(container,v=False,force=True)\n    result={'resultInfo':u'容器删除成功!!','type':'delete'}\n    return {'result': result}\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "webapp/tests.py",
    "content": "from django.test import TestCase\n\n# Create your tests here.\n"
  },
  {
    "path": "webapp/urls.py",
    "content": "from django.conf.urls import url\nfrom webapp.views import (Login,\n                          Logout,\n                          Register,\n                          Activate,\n                          SendResetEmail,\n                          ResetPassword,\n                          SysrestUserpassword,\n                          Userinfo)\n\nurlpatterns = [\n    url(r'login/$', Login, name='Login'),\n    url(r'register/$', Register, name='Register'),\n    url(r'logout/$', Logout, name='Logout'),\n    url(r'activate/(?P<token>\\w+@\\w+.\\w+.[-_\\w]*\\w+.[-_\\w]*\\w+)/$', Activate, name='Activate'),\n    url(r'reset/$',SendResetEmail,name='SendResetEmail'),\n    url(r'resetpass/(?P<token>\\w+@\\w+.\\w+.[-_\\w]*\\w+.[-_\\w]*\\w+)/$', ResetPassword, name='ResetPassword'),\n    url(r'userinfo/$',Userinfo, name='Userinfo'),\n    url(r'restuserpass/(\\d+)$', SysrestUserpassword, name='SysrestUserpassword'),\n\n]\n"
  },
  {
    "path": "webapp/views.py",
    "content": "#coding:utf8\nfrom django.shortcuts import render\nfrom django.http import HttpResponse,HttpResponseRedirect\nfrom django.contrib.auth import authenticate, login, logout\nfrom django.contrib.auth.decorators import permission_required\nfrom django.contrib.auth.mixins import PermissionRequiredMixin\nfrom django.contrib.auth.decorators import login_required\nfrom django.shortcuts import get_object_or_404\nfrom webapp.models import Suser, History_Login,Operation\nfrom webapp import forms\nfrom webapp.tasks import sendmail,resetpass\nfrom django.conf import settings as django_settings\nfrom itsdangerous import TimestampSigner\nfrom django.db.models import Sum\nfrom servermanager.models import *\nfrom dockermanager.models import *\nimport json\n\n\n\n@login_required\ndef index(request):\n    priceData = Assets.objects.all().aggregate(Sum('price'))\n    #如果用户从管理后台登录将设置session值\n    if not request.session.get('user_id'):\n        usersession = request.session.get('_auth_user_id')\n        request.session['user_id'] = usersession\n    else:\n        usersession = request.session.get('user_id')\n    ServersCount = Server.objects.all().count()\n    DockerContainerCount = DockerContainer.objects.all().count()\n    DockerImageCount = Dockerimage.objects.all().count()\n    UserData = Suser.objects.get(id=usersession)\n    Opdata = Operation.objects.all().order_by('-id')[:10]\n    return render(request,'webapp/index.html',locals())\n\n\n#用户登录函数\ndef Login(request):\n    restdata = {'data':'', 'error': ''}\n    loginobj=forms.SimpleLogin()\n    restdata['data'] = loginobj\n    if request.method == 'POST':\n        CheckForm = forms.SimpleLogin(request.POST)\n        if CheckForm.is_valid():\n            username = request.POST['username']\n            password = request.POST['password']\n            user = authenticate(username=username, password=password)\n            #设置用户的会话过期时间,如果没有勾记住我，默认关闭浏览器就要重新登录\n            if not request.POST.get('remember_me', None):\n                request.session.set_expiry(0)\n            if user is not None:\n                if user.is_active:\n                    login(request,user)\n                    request.session['user_name'] = user.username\n                    request.session['user_id'] = user.id\n                    #记录用户登录日志\n                    history_login = History_Login(\n                         user=user,\n                         user_ip=request.META['REMOTE_ADDR'],\n                         request_method=request.META['REQUEST_METHOD'],\n                         request_url=request.META['HTTP_REFERER'],\n                    )\n                    history_login.save()\n                    msg={'msginfo':'login is ok'}\n                    return HttpResponse(json.dumps(msg))\n                else:\n                    msg={'msgerror':u\"用户没有激活!!!\"}\n                    return HttpResponse(json.dumps(msg))\n            else:\n                msg={'msgerror':u\"用户名或密码错误\"}\n                return HttpResponse(json.dumps(msg))\n        else:\n            restdata['data'] = CheckForm\n            restdata['error'] = CheckForm.errors.as_data().values()[0][0].messages[0]\n    return render(request, 'webapp/login.html', restdata)\n\n#用户注册函数\ndef Register(request):\n    restdata = {'data':'','regerror':''}\n    registerobj=forms.Register()       #实例化forms\n    restdata['data'] = registerobj     #将对象传到模板中\n\n    if request.method == 'POST':\n        form = forms.Register(request.POST)\n        if form.is_valid():\n            username = request.POST['username']\n            email = request.POST['email']\n            password1 = request.POST['password1']\n            password2 = request.POST['password2']\n            if not Suser.objects.all().filter(email=email):    #先判断是否存在该用户\n                if form.pwd_validate(password1,password2):     #判断密码是否一致\n                    user = Suser.objects.create_user(email,username,password1)\n                    user.save()\n                    #生成验证连接并发送邮件\n                    s=TimestampSigner(django_settings.SECRET_KEY)\n                    registerstring = s.sign(email)\n                    sendmail.delay(dict(to=email,string=registerstring))   #发送邮件\n                    return HttpResponseRedirect('/web/login/')\n                else:\n                    error=u'密码输入不一致!!'\n                    restdata['regerror'] = error\n            else:\n                error=u'用户已存在，请重新输入!!!!!'\n                restdata['regerror'] = error\n        else:\n            restdata['data'] = form\n    return render(request,'webapp/register.html',restdata)\n\n#激活用户函数\ndef Activate(request, token):\n    s=TimestampSigner(django_settings.SECRET_KEY)\n    email=s.unsign(token)\n    try:\n        s=TimestampSigner(django_settings.SECRET_KEY)\n        s.unsign(token,max_age=300)\n    except:\n        users=Suser.objects.filter(email=email)\n        for user in users:\n            user.delete()\n        return HttpResponse('连接已过期!!')\n\n    try:\n        user = Suser.objects.get(email=email)\n    except Suser.DoesNotExist:\n        return HttpResponse('用户不存在!!')\n\n    user.is_active=True\n    user.save()\n    return HttpResponseRedirect('/')\n\n#用户退出\ndef Logout(request):\n    #记录用户登出时间\n    #history_login = History_Login.objects.filter(user=request.user).order_by('-id')[0]\n    #history_login.save()\n    #登出用户\n    logout(request)\n    #删除用户的session\n    if request.session.get('user_name'):\n        del request.session['user_name']\n    return HttpResponseRedirect('/',)\n\n\n#发送重置密码链接给用户\ndef SendResetEmail(request):\n    if request.method == 'POST':\n        email = request.POST.get('email')\n        try:\n            user = Suser.objects.get(email=email)\n        except Suser.DoesNotExist:\n            msg={'msgerror':u'对不起，您输入的用户不存在,请重新输入!!!'}\n            return HttpResponse(json.dumps(msg))\n\n        s=TimestampSigner(django_settings.SECRET_KEY)\n        resetstring = s.sign(email)\n        resetpass.delay(dict(to=email,string=resetstring))\n        msg={'msginfo':u'邮件发送成功,请及时确认!!!!'}\n        return HttpResponse(json.dumps(msg))\n    else:\n        return render(request,'webapp/sendresetpw.html')\n\n\n#重置密码\ndef ResetPassword(request,token):\n    restdata = {'data':'','regerror':'','token':token}\n    registerobj=forms.Register()\n    restdata['data'] = registerobj\n    if request.method == 'POST':\n        s=TimestampSigner(django_settings.SECRET_KEY)\n        email=s.unsign(token)\n\n        form = forms.ResetPassword(request.POST)\n        if form.is_valid():\n            password1 = request.POST['password1']\n            password2 = request.POST['password2']\n            if form.pwd_validate(password1,password2):\n                try:\n                    s=TimestampSigner(django_settings.SECRET_KEY)\n                    s.unsign(token,max_age=300)\n                except:\n                    msg={'msgerror':u'哎哟我去，连接已过期,请重发邮件!!'}\n                    return HttpResponse(json.dumps(msg))\n                users=Suser.objects.get(email=email)\n                users.set_password(password1)\n                users.save()\n                msg={'msginfo':u'恭喜您，密码修改成功!!!'}\n                return HttpResponse(json.dumps(msg))\n            else:\n                msg={'msgerror':u'密码输入不一致!!'}\n                return HttpResponse(msg)\n        else:\n            restdata['data'] = form\n    else:\n        return render(request,'webapp/resetpass.html', restdata)\n\n\n#个人信息\n@login_required()\ndef Userinfo(reqest):\n    userid = reqest.session.get('user_id')\n    if reqest.method == 'GET':\n        Userdata=Suser.objects.get(id=userid)\n        data={'Userdata':Userdata,'usersession':reqest.session.get('user_id')}\n        return render(reqest,'webapp/userinfo.html',data)\n\n\n@login_required()\ndef SysrestUserpassword(request,id):\n    restdata = {'data':'','regerror':'','id':int(id),'usersession': request.session.get('user_id')}\n    registerobj=forms.Register()\n    restdata['data'] = registerobj\n    if request.method == 'POST':\n        form = forms.ResetPassword(request.POST)\n        if form.is_valid():\n            password1 = request.POST['password1']\n            password2 = request.POST['password2']\n            if form.pwd_validate(password1,password2):\n                users=Suser.objects.get(id=id)\n                users.set_password(password1)\n                users.save()\n                return HttpResponse('密码修改成功')\n            else:\n                error=u'密码输入不一致!!'\n                return HttpResponse(error)\n        else:\n            restdata['data'] = form\n    else:\n        return render(request,'webapp/sysrestuserpassword.html', restdata)\n\n\n\n"
  }
]