├── __init__.py ├── mcc ├── utils │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-35.pyc │ │ ├── excutor.cpython-35.pyc │ │ ├── mailHelper.cpython-35.pyc │ │ └── configReader.cpython-35.pyc │ ├── configReader.py │ ├── excutor.py │ └── mailHelper.py ├── mysetup.py ├── updatelog.md ├── _config.ini ├── README.md └── auto.py ├── wcc ├── util │ ├── __init__.py │ ├── DataBaseManager.py │ ├── mccLog.py │ ├── configReader.py │ └── excutor.py ├── templates │ ├── __init__.py │ ├── index.html │ └── base.html ├── static │ ├── img │ │ ├── favicon.ico │ │ └── validate.gif │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ ├── js │ │ ├── npm.js │ │ ├── stickUp.min.js │ │ └── bootstrap.min.js │ └── css │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap-theme.css │ │ └── bootstrap-theme.css.map ├── README.md ├── webControl.py └── wcc.py ├── uiControl ├── server │ ├── util │ │ ├── __init__.py │ │ ├── SocketManager.py │ │ ├── SocketHelper.py │ │ └── SocketThread.py │ ├── simpleServer.py │ └── Server.py ├── client_Slave │ ├── util │ │ ├── __init__.py │ │ ├── DataBaseManager.py │ │ ├── mccLog.py │ │ ├── configReader.py │ │ └── excutor.py │ ├── writeCommand.py │ ├── _config.ini │ ├── Slave.py │ └── SlaveSocket.py ├── client_Master │ ├── logo.jpg │ ├── setup.py │ ├── MasterSocket.py │ └── Master.py ├── gridbagsizer控件分布.xlsx ├── section3 │ ├── setup.py │ ├── py2exe-0.6.9.win32-py2.7.exe │ └── hideConsole.py └── readme.md └── README.md /__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mcc/utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /wcc/util/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /uiControl/server/util/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /uiControl/client_Slave/util/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /wcc/templates/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/wcc/templates/__init__.py -------------------------------------------------------------------------------- /uiControl/client_Slave/writeCommand.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8-*- 2 | with open('1.txt', 'w') as f: 3 | f.write('123') -------------------------------------------------------------------------------- /wcc/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/wcc/static/img/favicon.ico -------------------------------------------------------------------------------- /wcc/static/img/validate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/wcc/static/img/validate.gif -------------------------------------------------------------------------------- /uiControl/client_Master/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/uiControl/client_Master/logo.jpg -------------------------------------------------------------------------------- /uiControl/gridbagsizer控件分布.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/uiControl/gridbagsizer控件分布.xlsx -------------------------------------------------------------------------------- /uiControl/section3/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | import py2exe 3 | 4 | setup(console=['hideConsole.py']) 5 | -------------------------------------------------------------------------------- /mcc/utils/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/mcc/utils/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /mcc/utils/__pycache__/excutor.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/mcc/utils/__pycache__/excutor.cpython-35.pyc -------------------------------------------------------------------------------- /mcc/utils/__pycache__/mailHelper.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/mcc/utils/__pycache__/mailHelper.cpython-35.pyc -------------------------------------------------------------------------------- /uiControl/section3/py2exe-0.6.9.win32-py2.7.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/uiControl/section3/py2exe-0.6.9.win32-py2.7.exe -------------------------------------------------------------------------------- /mcc/utils/__pycache__/configReader.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/mcc/utils/__pycache__/configReader.cpython-35.pyc -------------------------------------------------------------------------------- /wcc/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/wcc/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /wcc/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/wcc/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /wcc/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/wcc/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /wcc/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingname/RemoteControl/HEAD/wcc/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /mcc/mysetup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | import py2exe 3 | 4 | setup( 5 | console=["auto.py"], 6 | options = { "py2exe": { "dll_excludes": ["MSVCP90.dll"] } } 7 | ) -------------------------------------------------------------------------------- /mcc/updatelog.md: -------------------------------------------------------------------------------- 1 | #UpdateLog 2 | 3 | #2016-04-12 4 | 使用Python3.5.1重构程序 5 | 6 | #2015-09-05 7 | 增加沙盘模式,从此可以无限制扩展程序的功能。 8 | 9 | #2015-06-30 10 | 本次更新全面重构了整个程序。使用面向对象的开发方式进行开发。同时规范了变量的命名方式。 -------------------------------------------------------------------------------- /uiControl/client_Master/setup.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | from distutils.core import setup 3 | import py2exe 4 | 5 | ''' 6 | 生成exe文件以后,请将logo.jpg放在dist文件夹里面,否则程序会报错。 7 | ''' 8 | setup(windows=['Master.py'], 9 | options={'py2exe': {'dll_excludes': ['MSVCP90.dll']}} 10 | ) 11 | -------------------------------------------------------------------------------- /uiControl/client_Slave/_config.ini: -------------------------------------------------------------------------------- 1 | [Server] 2 | #host = xx.xx.xx.xx 3 | host = 192.168.2.100 4 | port = 5000 5 | 6 | [Client] 7 | timeout = 5 8 | 9 | [Command] 10 | shutdown=shutdown -f -s -t 10 -c closing... 11 | dir=dir 12 | 13 | #打开文件,文件名不能为中文,不要有空格 14 | [Open] 15 | music = F:\backup\Music\Intro.mp3 16 | notepad = notepad 17 | -------------------------------------------------------------------------------- /mcc/_config.ini: -------------------------------------------------------------------------------- 1 | [Slave] 2 | pophost = pop.sina.com 3 | smtphost = smtp.sina.com 4 | port = 25 5 | username = abc0@sina.com 6 | password = 12345 7 | 8 | [Boss] 9 | mail = boss@foxmail.com 10 | timelimit = 300 11 | 12 | [Command] 13 | shutdown=shutdown -f -s -t 10 -c closing... 14 | dir=dir 15 | 16 | [Open] 17 | music = D:\backup\Music\Intro.mp3 18 | notepad = notepad 19 | -------------------------------------------------------------------------------- /wcc/static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /wcc/util/DataBaseManager.py: -------------------------------------------------------------------------------- 1 | import pymongo 2 | 3 | class DataBaseManager(object): 4 | def __init__(self, host='127.0.0.1', port=27017): 5 | connection = pymongo.MongoClient(host, port) 6 | tdb = connection.webControl 7 | self.post_info = tdb.test 8 | 9 | def insert(self, info): 10 | self.post_info.insert(info) 11 | 12 | def find(self, key, value): 13 | return self.post_info.find({key: value}) 14 | 15 | def update(self, _id, key, value): 16 | self.post_info.update({"_id": _id}, {"$set": {key: value}}) 17 | -------------------------------------------------------------------------------- /uiControl/client_Slave/util/DataBaseManager.py: -------------------------------------------------------------------------------- 1 | import pymongo 2 | 3 | class DataBaseManager(object): 4 | def __init__(self, host='127.0.0.1', port=27017): 5 | connection = pymongo.MongoClient(host, port) 6 | tdb = connection.webControl 7 | self.post_info = tdb.test 8 | 9 | def insert(self, info): 10 | self.post_info.insert(info) 11 | 12 | def find(self, key, value): 13 | return self.post_info.find({key: value}) 14 | 15 | def update(self, _id, key, value): 16 | self.post_info.update({"_id": _id}, {"$set": {key: value}}) 17 | -------------------------------------------------------------------------------- /wcc/util/mccLog.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | import logging 3 | from datetime import datetime 4 | 5 | class mccLog(object): 6 | def __init__(self): 7 | logging.basicConfig(level=logging.DEBUG, 8 | format='%(asctime)s %(levelname)s %(message)s', 9 | datefmt='%Y-%m-%d %H:%M:%S', 10 | filename= datetime.now().strftime("%Y%m%d%H%M%S") + '.log', 11 | filemode='a') 12 | 13 | def mccWriteLog(self, logContent): 14 | logging.info(logContent) 15 | 16 | def mccError(self, errorContent): 17 | logging.error(errorContent) 18 | -------------------------------------------------------------------------------- /uiControl/client_Slave/util/mccLog.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | import logging 3 | from datetime import datetime 4 | 5 | class mccLog(object): 6 | def __init__(self): 7 | logging.basicConfig(level=logging.DEBUG, 8 | format='%(asctime)s %(levelname)s %(message)s', 9 | datefmt='%Y-%m-%d %H:%M:%S', 10 | filename= datetime.now().strftime("%Y%m%d%H%M%S") + '.log', 11 | filemode='a') 12 | 13 | def mccWriteLog(self, logContent): 14 | logging.info(logContent) 15 | 16 | def mccError(self, errorContent): 17 | logging.error(errorContent) 18 | -------------------------------------------------------------------------------- /mcc/utils/configReader.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | from configparser import ConfigParser 3 | import os, sys 4 | 5 | class ConfigReader(object): 6 | def __init__(self, configPath): 7 | configFile = os.path.join(sys.path[0],configPath) 8 | self.cReader = ConfigParser() 9 | self.cReader.read(configFile) 10 | 11 | def readConfig(self, section, item): 12 | return self.cReader[section][item] 13 | 14 | def getDict(self, section): 15 | commandDict = {} 16 | items = self.cReader.items(section) 17 | for key, value in items: 18 | commandDict[key] = value 19 | return commandDict 20 | -------------------------------------------------------------------------------- /uiControl/client_Slave/util/configReader.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | import ConfigParser 3 | import os, sys 4 | 5 | class configReader(object): 6 | def __init__(self, configPath): 7 | configFile = os.path.join(sys.path[0], configPath) 8 | self.cReader = ConfigParser.ConfigParser() 9 | self.cReader.read(configFile) 10 | 11 | def readConfig(self, section, item): 12 | return self.cReader.get(section, item) 13 | 14 | def getDict(self, section): 15 | commandDict = {} 16 | items = self.cReader.items(section) 17 | for key, value in items: 18 | commandDict[key] = value 19 | return commandDict 20 | 21 | -------------------------------------------------------------------------------- /wcc/util/configReader.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | import ConfigParser 3 | import os, sys 4 | 5 | class configReader(object): 6 | def __init__(self, configPath): 7 | configFile = os.path.join(sys.path[0], configPath) 8 | self.cReader = ConfigParser.ConfigParser() 9 | self.cReader.read(configFile) 10 | 11 | def readConfig(self, section, item): 12 | return self.cReader.get(section, item) 13 | 14 | def getDict(self, section): 15 | commandDict = {} 16 | items = self.cReader.items(section) 17 | for key, value in items: 18 | commandDict[key] = value 19 | return commandDict 20 | 21 | -------------------------------------------------------------------------------- /uiControl/section3/hideConsole.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | 3 | import ctypes 4 | import time 5 | 6 | # def hideWindows(): 7 | whnd = ctypes.windll.kernel32.GetConsoleWindow() 8 | 9 | if whnd != 0: 10 | print u'2秒后隐藏' 11 | time.sleep(2) 12 | ctypes.windll.user32.ShowWindow(whnd, 0) 13 | message = 'jikexueyuan\n\n窗口隐藏以后依然可以默默的运行。' 14 | with open('1.txt', 'w') as f: 15 | f.write(message) 16 | time.sleep(5) 17 | ctypes.windll.user32.ShowWindow(whnd, 1) 18 | ctypes.windll.kernel32.CloseHandle(whnd) 19 | 20 | raw_input('press enter') 21 | 22 | # def showWindows(): 23 | # whnd = ctypes.windll.kernel32.GetConsoleWindow() 24 | # if whnd != 0: 25 | # ctypes.windll.user32.ShowWindow(whnd, 1) 26 | # ctypes.windll.kernel32.CloseHandle(whnd) 27 | 28 | -------------------------------------------------------------------------------- /uiControl/server/util/SocketManager.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | 3 | from SocketHelper import SocketHelper 4 | 5 | class SocketManager: 6 | HOST = 'localhost' # 服务器主机地址 7 | PORT = 5000 # 服务器监听端口 8 | BUFFER_SIZE = 2048*100 9 | 10 | def __init__(self): 11 | self.socketSlavePool = [] 12 | 13 | def watch(self): 14 | socketWatcher = SocketHelper(host=self.HOST, port=self.PORT, name='socketWatcher', 15 | socketSlavePool=self.socketSlavePool) 16 | socketWatcher.start() 17 | 18 | def heartBeat(self): 19 | self.socketSlavePool.append({'readFlag': True}) 20 | for each in self.socketSlavePool: 21 | if each != 'readFlag': 22 | each.send('heartBeat') 23 | rec = each.recv(self.BUFFER_SIZE, timeout=5) 24 | if rec == 'heartBeat': 25 | pass 26 | 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Remote Control 2 | 3 | ##Introduction 4 | 5 | This project is for [jikexueyuan](http://jikexueyuan.com) which is an online educational website. And I have tough *How to program a remote software* there. You can watch the videos of this project to know the prinple of it. 6 | 7 | ##WCC 8 | 9 | WCC(Web Control Computer)is a software for controlling computers by webpages, for more information, please see:[Readme for WCC](https://github.com/kingname/RemoteControl/blob/master/wcc/README.md) 10 | 11 | ##MCC 12 | 13 | MCC(Mail Control Computer) is a software for controlling computers by Mail, and also the software which can send mail such as wechat. For more information, please see [Readme for MCC](https://github.com/kingname/RemoteControl/blob/master/mcc/README.md) 14 | 15 | 16 | 17 | ##UiControl 18 | 19 | UIControl is a remote control software with a UI which is based on wxPython. 20 | 21 | You can control the slave computer in the UI of the master. For more information, please see [Readme for UiControl](https://github.com/kingname/RemoteControl/blob/master/uiControl/README.md). -------------------------------------------------------------------------------- /uiControl/readme.md: -------------------------------------------------------------------------------- 1 | ##UIControl 2 | ####介绍 3 | 4 | 这个项目是我在极客学院《图形化远程控制程序》课程的配套程序,如果你想了解这个程序的运行原理,请访问最下面的课程链接观看我对这个程序的讲解。或者你也可以自行阅读程序的源代码。 5 | 6 | 7 | 8 | ##如何使用 9 | 10 | 程序分为三个部分,服务器端,控制端和被控端。 11 | 12 | ###服务器端 13 | 服务器端对应的的文件为server/Server.py, 如果你需要在公网环境下控制远程的电脑,请将服务器端部署在公网环境下的电脑中。运行服务器端不需要进行任何配置,只需要运行Server.py: 14 | 15 | python Server.py 16 | 17 | simpleServer.py是一个socket的demo, 你可以阅读它的代码来更好的理解socket的实现方法。 18 | 19 | 20 | ##控制端 21 | 22 | 控制端对应的文件为client_Master/Master.py, 如果要使用控制端,请使用任何文本编辑器打开Master.py, 并将第7行SERVER的值设定为服务器端的公网IP地址,然后运行: 23 | 24 | python Master.py 25 | 26 | 由于控制端有图形界面,因此请安装wxPython. 27 | 28 | 29 | 30 | ##被控端 31 | 32 | 被控端对应的文件为client_Slave/Slave.py,请使用任何文本编辑器打开_config.ini,其中[Server]下面的host配置为服务器端的公网IP地址[Client]下面的timeout表示Socket连接超时的时间,你可以自行设定。[Command]和[Open]下面的内容为配置的各种命令,左侧是命令的名称。不同点在于[Command]使用os.system运行命令,[Open]使用Win32Api来运行命令。 33 | 34 | python Slave.py 35 | 36 | 如果你的操作系统不是Windows或者你没有安装Win32Api, 请修改client_Slave/util/excutor.py, 将 37 | 38 | import win32api 39 | 40 | 和所有与win32有关的代码注释掉,同时不能再使用[Open]下面的命令。 41 | 42 | 43 | 44 | ###隐藏窗口 45 | 46 | 在section3下面的代码演示了如何隐藏windows的cmd窗口,由于这个功能有木马性质,因此我不会将它集成到被控端里面,如果你有这个需要,你可以自行将代码集成进去。 47 | 48 | 49 | 50 | ##视频课程 51 | 52 | [Python 图形程序入门](http://www.jikexueyuan.com/course/2553.html) 53 | 54 | 编写图形界面的远程控制程序(近期上线) 55 | 56 | 开发远程控制程序高级功能(近期上线) 57 | 58 | -------------------------------------------------------------------------------- /wcc/README.md: -------------------------------------------------------------------------------- 1 | #WCC v0.1 2 | 3 | ##介绍/Introduce 4 | 5 | WCC(Web Control Computer)是一个通过网页控制电脑的程序,用户可以在网页上下达命令,安装了客户端的电脑将会执行命令。下命令的方式分为两种,预定义命令和直接写入Python代码。 6 | 7 | ##安装与配置/Install and config 8 | 9 | ###客户端 10 | 11 | ####_config.ini 12 | 13 | 对v0.1版本,客户端直接读取服务器上的MongoDB来获取数据,因此需要配置服务器的域名和端口。 14 | 15 | [Server] 16 | host = xxxx.com 17 | port = 27017 18 | 19 | 其中host填写服务器的域名或者IP地址,port填写MongoDB的端口,默认是27017. 20 | 21 | [Client] 22 | timelimit = 10 23 | 24 | 客户端采用轮询的方式查询数据库,timelimit设定轮询的时间间隔,默认为10,单位为秒。 25 | 26 | [Command] 27 | shutdown=shutdown -f -s -t 10 -c closing... 28 | dir=dir 29 | 30 | #打开文件,文件名不能为中文,不要有空格 31 | [Open] 32 | music = F:\backup\Music\Intro.mp3 33 | notepad = notepad 34 | 35 | 这一段设定预定义的命令。 36 | 37 | [Command]下面的命令是使用CMD来执行。 38 | 39 | [Open]下面的命令是使用win32api来执行。等号左侧是命令的名字,右侧是具体命令。 40 | 41 | 设定好以后,运行wcc.py: 42 | 43 | python wcc.py 44 | 45 | ###网页端 46 | 47 | 对于网页端来说,需要注意的是,要允许从外部访问MongoDB。 48 | 49 | 需要直接运行webControl.py: 50 | 51 | python webControl.py 52 | 53 | ##使用/Usage 54 | 55 | 打开网页端如图: 56 | 57 | ![](http://7sbpmp.com1.z0.glb.clouddn.com/wcc.png) 58 | 59 | 其中**内置命令** 这一项可以填写在_config.ini中定义的命令。**直接写代码**下面,可以直接贴Python的代码,格式和缩进会自动保留。 60 | 61 | 填写完成以后,点击**发送命令**按钮,10秒内,远程电脑上就会执行命令了。 62 | 63 | 64 | 65 | ##视频课程 66 | 67 | [Flask 快速搭建网站](http://www.jikexueyuan.com/course/2348.html) 68 | 69 | [网页控制电脑](http://www.jikexueyuan.com/course/2389.html) -------------------------------------------------------------------------------- /uiControl/client_Slave/Slave.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8 -*- 2 | 3 | from util.configReader import configReader 4 | import SlaveSocket 5 | 6 | __Author__ = 'kingname' 7 | __Verson__ = 1.0 8 | 9 | class Slave(object): 10 | CONFIGPATH = '_config.ini' 11 | KEY_COMMAND = 'Command' 12 | KEY_OPEN = 'Open' 13 | KEY_Server = 'Server' 14 | KEY_Client = 'Client' 15 | KEY_TIMEOUT = 'timeout' 16 | KEY_PORT = 'port' 17 | 18 | def __init__(self): 19 | self.configReader = configReader(self.CONFIGPATH) 20 | self.timeout = 5 21 | self.commandDict = {} 22 | self.openDict = {} 23 | self.server = '' 24 | self.port = 5000 25 | self.initEnv() 26 | self.run() 27 | 28 | def initEnv(self): 29 | self.commandDict = self.configReader.getDict(self.KEY_COMMAND) 30 | self.openDict = self.configReader.getDict(self.KEY_OPEN) 31 | self.server = self.configReader.getDict(self.KEY_Server) 32 | print 'Server is: %s' % str(self.server) 33 | self.timeout = int(self.configReader.readConfig(self.KEY_Client, self.KEY_TIMEOUT)) 34 | print 'init finished' 35 | 36 | def run(self): 37 | slave = SlaveSocket.SlaveSocket(self.server['host'], int(self.server['port']), self.commandDict, self.openDict, self.timeout) 38 | slave.setDaemon(True) 39 | slave.start() 40 | slave.join() 41 | 42 | if __name__=='__main__': 43 | mcc = Slave() 44 | -------------------------------------------------------------------------------- /uiControl/server/simpleServer.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | import socket 3 | 4 | class SimpleServer: 5 | BUFFER_SIZE = 2048*100 6 | 7 | def __init__(self, host='', port=5000): 8 | self.sock = None 9 | self.host = host 10 | self.port = port 11 | 12 | def connect(self): 13 | try: 14 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 15 | self.sock.bind((self.host, self.port)) 16 | # 开启socket监听 17 | self.sock.listen(5) 18 | except Exception, e: 19 | print 'socket 错误: %s' % str(e) 20 | return None 21 | 22 | def receive(self): 23 | if self.sock: 24 | conn, addr = self.sock.accept() 25 | print '收到来自 %s的连接' % str(addr) 26 | while True: 27 | # 读取数据,数据还没到来阻塞 28 | data = conn.recv(self.BUFFER_SIZE) 29 | if len(data): 30 | print u'收到来自: %s, 的信息: %s' % (addr[0], data) 31 | conn.sendall(u'I have received the data: %s' % data) 32 | else: 33 | print u'socket 连接中断。' 34 | break 35 | 36 | if __name__ == '__main__': 37 | HOST = '' # 服务器主机地址 38 | PORT = 5000 # 服务器监听端口 39 | 40 | simple = SimpleServer(HOST, PORT) 41 | simple.connect() 42 | while True: 43 | print u'等待连接建立...' 44 | simple.receive() #进程运行到这里就会阻塞,直到第一次连接主动或者意外断开,才会进入第二次循环。认识到这一点非常重要。 45 | -------------------------------------------------------------------------------- /wcc/webControl.py: -------------------------------------------------------------------------------- 1 | #--coding:utf8-- 2 | from flask.ext.bootstrap import Bootstrap 3 | from flask import Flask, render_template, redirect 4 | from flask.ext.wtf import Form 5 | from wtforms import StringField, SubmitField, TextAreaField 6 | from util.DataBaseManager import DataBaseManager 7 | 8 | app = Flask(__name__) 9 | bootstrap = Bootstrap(app) 10 | 11 | app. config['SECRET_KEY'] = 'youcouldneverknowhis-name' 12 | app.config.from_object(__name__) 13 | 14 | class contentForm(Form): 15 | commandInConfig = StringField(u'') 16 | commandInWrite = TextAreaField(u'', default="") 17 | sendCommand = SubmitField(u'发送命令') 18 | clearCommand = SubmitField(u'清空命令') 19 | 20 | @app.route('/', methods=['GET', 'POST']) 21 | def index(): 22 | form = contentForm() 23 | dataBaseManager = DataBaseManager() 24 | if form.validate_on_submit(): 25 | innerCommand = form.commandInConfig.data 26 | writeCommand = form.commandInWrite.data 27 | 28 | if not (innerCommand or writeCommand): 29 | errorinfo = u'内置命令和自定义代码至少要写一个!' 30 | return render_template('index.html', form=form, errorinfo=errorinfo) 31 | else: 32 | info = {'innerCommand': innerCommand, 'writeCommand': writeCommand, 'run': False} 33 | dataBaseManager.insert(info) 34 | return redirect('/') 35 | return render_template('index.html', form=form, errorinfo='') 36 | 37 | if __name__ == "__main__": 38 | app.run(host='0.0.0.0', port=80, threaded=True) 39 | app.run(processes=10) 40 | -------------------------------------------------------------------------------- /wcc/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block title %}极客学院{% endblock %} 3 | {% import "bootstrap/wtf.html" as wtf %} 4 | 5 | {% block content %} 6 |
7 | 10 | {% if errorinfo %} 11 |
12 | 13 |

14 | 错误! 15 |

16 |

{{ errorinfo }}

17 | 18 |
19 | {% endif %} 20 |
21 | {{ form.csrf_token }} 22 |
23 |
24 |
25 |

内置命令:

26 |

27 | {{ form.commandInConfig(class="col-md-12", value="") }} 28 |

29 |
30 |
31 |

32 | 直接写代码[代码中请不要出现中文或者中文字符]: 33 |

34 |

35 | {{ form.commandInWrite(class="col-md-12", cols="50", rows="10")|safe }} 36 |

37 |
38 |
39 | {{ form.sendCommand(class="btn btn-default", type="submit",id="submit") }}{{ form.clearCommand(class="btn btn-default", type="reset") }} 40 |
41 |
42 |
43 |
44 |
45 | {% endblock %} -------------------------------------------------------------------------------- /uiControl/server/Server.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | import socket 3 | import util.SocketThread as SocketThread 4 | import threading 5 | import random 6 | 7 | class Server: 8 | BUFFER_SIZE = 2048*100 9 | 10 | def __init__(self, host='', port=5000): 11 | self.sock = None 12 | self.host = host 13 | self.port = port 14 | self.socketPool = {} 15 | self.lock = threading.Lock() 16 | self.connect() 17 | self.dispatch() 18 | 19 | 20 | def connect(self): 21 | try: 22 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 23 | self.sock.bind((self.host, self.port)) 24 | # 开启socket监听 25 | self.sock.listen(5) 26 | except Exception, e: 27 | print e 28 | # print u'socket error: %s' % str(e) 29 | return None 30 | 31 | def dispatch(self): 32 | while True: 33 | if self.sock: 34 | conn, addr = self.sock.accept() 35 | print '收到来自 %s的连接' % str(addr[0]) 36 | self.lock.acquire() 37 | if not addr[0] in self.socketPool: 38 | name = addr[0] 39 | else: 40 | name = addr[0] + '-' + str(random.randint(1000, 9999)) 41 | oneSock = SocketThread.SocketThread(conn, name, self.socketPool) 42 | oneSock.setDaemon(True) 43 | oneSock.start() 44 | self.socketPool[name] = conn 45 | self.lock.release() 46 | 47 | if __name__ == '__main__': 48 | HOST = '' # 服务器主机地址 49 | PORT = 5000 # 服务器监听端口 50 | 51 | simple = Server(HOST, PORT) 52 | -------------------------------------------------------------------------------- /mcc/README.md: -------------------------------------------------------------------------------- 1 | MCC 2 | === 3 | 4 | Mail Control Computer 5 | 6 | ##目的: 7 | 本程序通过邮件控制电脑。 8 | 9 | ##原理: 10 | Python使用Poplib库,周期性访问邮箱,根据邮件主题的相应名称执行对应的操作。 11 | 12 | 目前奴隶邮箱(Python检查的那个邮箱,简称奴隶邮箱)使用sina邮箱测试成功,其他邮箱未做测试。 13 | 主人邮箱(发送命令的邮箱称为主人邮箱),通过发送邮件给奴隶邮箱来控制操作。目前测试使用QQ邮箱与使用微信发送的QQ邮件能测试通过。 14 | 15 | ##配置 16 | 打开_config.ini文件: 17 | 18 | ###Slave 19 | 20 | * pophost填写奴隶邮箱的pop3服务器,例如新浪的pop3服务器为 21 | 22 | pop.sina.com 23 | 24 | * smtphost填写奴隶邮箱的SMTP服务器,例如新浪的SMTP服务器为 25 | 26 | 27 | smtp.sina.com 28 | 29 | * username为奴隶邮箱的邮箱号 30 | * password为奴隶邮箱的密码 31 | * 必须要先在新浪邮箱的账户控制中允许客服端收件,并打开POP3和SMTP协议,否则会出错。如图所示: 32 | ![](http://7sbpmp.com1.z0.glb.clouddn.com/QQ截图20150630000146.png) 33 | 34 | ###Boss 35 | * mail为主人邮箱号 36 | * timelimit控制程序检查邮箱的评论,默认为300秒,也就是5分钟 37 | 38 | ###Command 39 | 这个section的内容是可以使用Python运行的cmd命令,理论上讲,任何Python可以执行的命令都可以添加到这里。 40 | 41 | 名字 = 命令 42 | 43 | ###Open 44 | 这个section下的内容为可以通过Python打开的文件或者内容,例如打开记事本,打开音乐等等。 45 | 46 | 名字 = 地址 47 | 48 | ##使用 49 | ###普通模式 50 | 51 | 普通模式可以使用定义好的命令。命令请使用#f#结尾。 52 | 53 | 使用主人邮箱往奴隶邮箱发送邮件,标题为_config.ini中的任一命令的**名字**(等号左边的内容)。例如,想打开记事本,那就使用邮箱发送标题为notepad#f#的邮件。 54 | 55 | ###沙盘模式 56 | 57 | 沙盘模式可以无限制的扩展程序的功能,通过邮件将新的Python代码直接写入到对方电脑并运行。 58 | 59 | 使用主人邮箱往奴隶邮箱发送命令,例如: 60 | 61 | sandbox:test.py$n$import win32api$c$if 1 + 1 == 2:$c$$$$$win32api.MessageBox(0, 'sandbox', 'this is sandbox')#f# 62 | 63 | 格式: 64 | 65 | sandbox:文件名$n$代码 66 | 67 | 其中预定义的标记如下: 68 | 69 | $n$:文件名与代码的分隔符 70 | $c$:换行 71 | $:空格,4个$连着用表示缩进 72 | #f#:结束标志 73 | 74 | ##编译 75 | python mysetup.py py2exe 76 | 77 | 78 | ## 视频课程 79 | 80 | [微信远控:Python 控制电脑的两种方法](http://www.jikexueyuan.com/course/1962.html) 81 | 82 | [微信远控:让微信控制电脑](http://www.jikexueyuan.com/course/2120.html) 83 | 84 | -------------------------------------------------------------------------------- /mcc/auto.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8 -*- 2 | 3 | import time 4 | import logging 5 | from utils.mailHelper import mailHelper 6 | from utils.excutor import executor 7 | from utils.configReader import ConfigReader 8 | 9 | __Author__ = 'kingname' 10 | __Verson__ = 0.6 11 | 12 | logger = logging.getLogger('mcc') 13 | logger.setLevel(logging.DEBUG) 14 | 15 | ch = logging.StreamHandler() 16 | ch.setLevel(logging.INFO) 17 | 18 | fh = logging.FileHandler('mccLog.log') 19 | fh.setLevel(logging.DEBUG) 20 | 21 | formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 22 | 23 | ch.setFormatter(formatter) 24 | fh.setFormatter(formatter) 25 | 26 | logger.addHandler(ch) 27 | logger.addHandler(fh) 28 | 29 | class MCC(object): 30 | CONFIGPATH = '_config.ini' 31 | KEY_COMMAND = 'Command' 32 | KEY_OPEN = 'Open' 33 | KEY_BOSS = 'Boss' 34 | KEY_TIMELIMIT = 'timelimit' 35 | 36 | def __init__(self): 37 | self.mailHelper = mailHelper() 38 | self.configReader = ConfigReader(self.CONFIGPATH) 39 | commandDict = self.configReader.getDict(self.KEY_COMMAND) 40 | openDict = self.configReader.getDict(self.KEY_OPEN) 41 | self.timeLimit = int(self.configReader.readConfig(self.KEY_BOSS, self.KEY_TIMELIMIT)) 42 | self.excutor = executor(commandDict, openDict) 43 | self.toRun() 44 | 45 | def toRun(self): 46 | while True: 47 | self.run() 48 | time.sleep(self.timeLimit) 49 | 50 | def run(self): 51 | mailBody = self.mailHelper.acceptMail() 52 | if mailBody: 53 | exe = self.mailHelper.analysisMail(mailBody) 54 | if exe: 55 | self.excutor.execute(exe, self.mailHelper) 56 | 57 | if __name__ == '__main__': 58 | mcc = MCC() 59 | 60 | 61 | -------------------------------------------------------------------------------- /uiControl/client_Slave/util/excutor.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | 3 | import os 4 | import win32api 5 | from util.mccLog import mccLog 6 | 7 | class executor(object): 8 | def __init__(self, commandDict, openDict): 9 | self.mccLog = mccLog() 10 | self.commandDict = commandDict 11 | self.openDict = openDict 12 | 13 | def execute(self, commandType, command): 14 | self.mccLog.mccWriteLog(u'开始处理命令。') 15 | if commandType == 'commandInConfig': 16 | self.exeInnerCommand(command) 17 | elif commandType == 'commandInWrite': 18 | self.exeWriteCommand(command) 19 | 20 | def exeInnerCommand(self, innerCommand): 21 | if innerCommand in self.commandDict: 22 | self.mccLog.mccWriteLog(u'执行命令') 23 | try: 24 | command = self.commandDict[innerCommand] 25 | os.system(command) 26 | self.mccLog.mccWriteLog(u'执行命令成功') 27 | except Exception, e: 28 | self.mccLog.mccError(u'执行命令失败' + str(e)) 29 | elif innerCommand in self.openDict: 30 | self.mccLog.mccWriteLog(u'打开文件') 31 | try: 32 | openFile = self.openDict[innerCommand] 33 | win32api.ShellExecute(0, 'open', openFile, '', '', 1) 34 | self.mccLog.mccWriteLog(u'打开文件成功') 35 | except Exception, e: 36 | self.mccLog.mccError(u'打开文件失败:' + str(e)) 37 | else: 38 | self.mccLog.mccError(u'命令%s不存在!' % innerCommand) 39 | 40 | def exeWriteCommand(self, writeCommand): 41 | if writeCommand: 42 | self.sandBox(writeCommand) 43 | 44 | def sandBox(self, code): 45 | ''' 46 | 注意:提交的代码请不要出现中文或者中文字符,否则会报错。 47 | ''' 48 | with open('writeCommand.py', 'w') as f: 49 | f.write(code) 50 | os.system('python ' + 'writeCommand.py') 51 | -------------------------------------------------------------------------------- /wcc/templates/base.html: -------------------------------------------------------------------------------- 1 | {% block doc -%} 2 | 3 | 4 | {%- block html %} 5 | 6 | {%- block head %} 7 | {% block title %}网页远控{% endblock title %} 8 | 9 | {%- block metas %} 10 | 11 | {%- endblock metas %} 12 | 13 | {%- block styles %} 14 | 15 | 16 | 21 | {%- endblock styles %} 22 | {%- endblock head %} 23 | 24 | 25 | {% block body -%} 26 | {% block navbar %} 27 | 45 | {%- endblock navbar %} 46 | {% block content -%} 47 | {%- endblock content %} 48 | 49 | {% block scripts %} 50 | 51 | 52 | {%- endblock scripts %} 53 | {%- endblock body %} 54 | 55 | {%- endblock html %} 56 | 57 | {% endblock doc -%} 58 | -------------------------------------------------------------------------------- /wcc/util/excutor.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | 3 | import os 4 | import win32api 5 | from util.mccLog import mccLog 6 | 7 | class executor(object): 8 | def __init__(self, commandDict, openDict): 9 | self.mccLog = mccLog() 10 | self.commandDict = commandDict 11 | self.openDict = openDict 12 | 13 | def execute(self, commandList): 14 | self.mccLog.mccWriteLog(u'开始处理命令。') 15 | finishList = [] 16 | for each in commandList: 17 | innerCommand = each['innerCommand'] 18 | writeCommand = each['writeCommand'] 19 | if not innerCommand: 20 | self.exeWriteCommand(writeCommand) 21 | else: 22 | self.exeInnerCommand(innerCommand) 23 | self.exeWriteCommand(writeCommand) 24 | finishList.append(each['_id']) 25 | return finishList 26 | 27 | def exeInnerCommand(self, innerCommand): 28 | if innerCommand in self.commandDict: 29 | self.mccLog.mccWriteLog(u'执行命令') 30 | try: 31 | command = self.commandDict[innerCommand] 32 | os.system(command) 33 | self.mccLog.mccWriteLog(u'执行命令成功') 34 | except Exception, e: 35 | self.mccLog.mccError(u'执行命令失败' + str(e)) 36 | elif innerCommand in self.openDict: 37 | self.mccLog.mccWriteLog(u'打开文件') 38 | try: 39 | openFile = self.openDict[innerCommand] 40 | win32api.ShellExecute(0, 'open', openFile, '', '', 1) 41 | self.mccLog.mccWriteLog(u'打开文件成功') 42 | except Exception, e: 43 | self.mccLog.mccError(u'打开文件失败:' + str(e)) 44 | else: 45 | self.mccLog.mccError(u'命令%s不存在!' % innerCommand) 46 | 47 | def exeWriteCommand(self, writeCommand): 48 | if writeCommand: 49 | self.sandBox(writeCommand) 50 | 51 | def sandBox(self, code): 52 | ''' 53 | 注意:在网页上面提交的代码请不要出现中文或者中文字符,否则会报错。 54 | ''' 55 | with open('writeCommand.py', 'w') as f: 56 | f.write(code) 57 | os.system('python ' + 'writeCommand.py') 58 | -------------------------------------------------------------------------------- /mcc/utils/excutor.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | 3 | import os 4 | import win32api 5 | import logging 6 | from utils.mailHelper import mailHelper 7 | 8 | class executor(object): 9 | def __init__(self, commandDict, openDict): 10 | self.mccLog = logging.getLogger('mcc') 11 | self.commandDict = commandDict 12 | self.openDict = openDict 13 | 14 | def execute(self, exe, mailHelper): 15 | self.mailHelper = mailHelper 16 | subject = exe['subject'] 17 | self.mccLog.info('开始处理命令。') 18 | self.mailHelper.sendMail('pass','Slave') 19 | if subject in self.commandDict: 20 | self.mccLog.info('执行命令') 21 | try: 22 | command = self.commandDict[subject] 23 | os.system(command) 24 | self.mailHelper.sendMail('Success','Boss') 25 | self.mccLog.info('执行命令成功') 26 | except Exception as e: 27 | self.mccLog.error('执行命令失败' + str(e)) 28 | self.mailHelper.sendMail('error', 'Boss', e) 29 | elif subject in self.openDict: 30 | self.mccLog.info('打开文件') 31 | try: 32 | openFile = self.openDict[subject] 33 | win32api.ShellExecute(0, 'open', openFile, '', '', 1) 34 | self.mailHelper.sendMail('Success', 'Boss') 35 | self.mccLog.info('打开文件成功') 36 | except Exception as e: 37 | self.mccLog.error('打开文件失败:' + str(e)) 38 | self.mailHelper.sendMail('error', 'Boss', e) 39 | elif subject[:7].lower() == 'sandbox': 40 | self.sandBox(subject[8:]) 41 | else: 42 | self.mailHelper.sendMail('error', 'boss', 'no such command') 43 | 44 | def sandBox(self, code): 45 | """sandbox:test.py$n$import win32api$c$if 1 + 1 == 2:$c$$$$$win32api.MessageBox(0, 'sandbox', 'this is sandbox')""" 46 | 47 | name = code.split('$n$')[0] 48 | code = code.split('$n$')[1] 49 | codestr = '\n'.join(code.split('$c$')) 50 | codestr = codestr.replace('$', ' ') 51 | with open(name, 'w') as f: 52 | f.write(codestr) 53 | os.system('python ' + name) 54 | -------------------------------------------------------------------------------- /wcc/wcc.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8 -*- 2 | 3 | import time 4 | import sys 5 | from util.excutor import executor 6 | from util.configReader import configReader 7 | from util.DataBaseManager import DataBaseManager 8 | 9 | __Author__ = 'kingname' 10 | __Verson__ = 1.0 11 | 12 | reload(sys) 13 | sys.setdefaultencoding('utf-8') 14 | 15 | class WCC(object): 16 | CONFIGPATH = '_config.ini' 17 | KEY_COMMAND = 'Command' 18 | KEY_OPEN = 'Open' 19 | KEY_Server = 'Server' 20 | KEY_Client = 'Client' 21 | KEY_TIMELIMIT = 'timelimit' 22 | 23 | def __init__(self): 24 | self.configReader = configReader(self.CONFIGPATH) 25 | self.initEnv() 26 | self.toRun() 27 | 28 | def initEnv(self): 29 | commandDict = self.configReader.getDict(self.KEY_COMMAND) 30 | openDict = self.configReader.getDict(self.KEY_OPEN) 31 | server = self.configReader.getDict(self.KEY_Server) 32 | print 'Server is: %s' % str(server) 33 | self.timeLimit = int(self.configReader.readConfig(self.KEY_Client, self.KEY_TIMELIMIT)) 34 | self.excutor = executor(commandDict, openDict) 35 | self.dbManager = DataBaseManager(server['host'], int(server['port'])) 36 | print 'init finished' 37 | 38 | def toRun(self): 39 | while True: 40 | print 'try:' 41 | self.run() 42 | time.sleep(self.timeLimit) 43 | 44 | def run(self): 45 | commandList = self._generateCommandList() 46 | print 'commandList is: %s' % str(commandList) 47 | if commandList: 48 | finishCommandList = self.excutor.execute(commandList) 49 | self.flagFinish(finishCommandList) 50 | 51 | def flagFinish(self, commandList): 52 | for each in commandList: 53 | self.dbManager.update(each, 'run', True) 54 | 55 | def _generateCommandList(self): 56 | commandObj = self.dbManager.find('run', False) 57 | commandList = [] 58 | if commandObj: 59 | print 'in command obj' 60 | for each in commandObj: 61 | commandDict = {'_id': each['_id'], 62 | 'innerCommand': each['innerCommand'], 63 | 'writeCommand': each['writeCommand'], 64 | 'run': each['run']} 65 | commandList.append(commandDict) 66 | return commandList[::-1] #将列表倒序 67 | 68 | if __name__=='__main__': 69 | mcc = WCC() 70 | -------------------------------------------------------------------------------- /wcc/static/js/stickUp.min.js: -------------------------------------------------------------------------------- 1 | jQuery(function($){$(document).ready(function(){var contentButton = [];var contentTop = [];var content = [];var lastScrollTop = 0;var scrollDir = '';var itemClass = '';var itemHover = '';var menuSize = null;var stickyHeight = 0;var stickyMarginB = 0;var currentMarginT = 0;var topMargin = 0;$(window).scroll(function(event){var st = $(this).scrollTop();if (st > lastScrollTop){scrollDir = 'down';} else {scrollDir = 'up';}lastScrollTop = st;});$.fn.stickUp = function( options ) {$(this).addClass('stuckMenu');var objn = 0;if(options != null) {for(var o in options.parts) {if (options.parts.hasOwnProperty(o)){content[objn] = options.parts[objn];objn++;}}if(objn == 0) {console.log('error:needs arguments');}itemClass = options.itemClass;itemHover = options.itemHover;if(options.topMargin != null) {if(options.topMargin == 'auto') {topMargin = parseInt($('.stuckMenu').css('margin-top'));} else {if(isNaN(options.topMargin) && options.topMargin.search("px") > 0){topMargin = parseInt(options.topMargin.replace("px",""));} else if(!isNaN(parseInt(options.topMargin))) {topMargin = parseInt(options.topMargin);} else {console.log("incorrect argument, ignored.");topMargin = 0;} }} else {topMargin = 0;}menuSize = $('.'+itemClass).size();}stickyHeight = parseInt($(this).height());stickyMarginB = parseInt($(this).css('margin-bottom'));currentMarginT = parseInt($(this).next().closest('div').css('margin-top'));vartop = parseInt($(this).offset().top);};$(document).on('scroll', function() {varscroll = parseInt($(document).scrollTop());if(menuSize != null){for(var i=0;i < menuSize;i++){contentTop[i] = $('#'+content[i]+'').offset().top;function bottomView(i) {contentView = $('#'+content[i]+'').height()*.4;testView = contentTop[i] - contentView;if(varscroll > testView){$('.'+itemClass).removeClass(itemHover);$('.'+itemClass+':eq('+i+')').addClass(itemHover);} else if(varscroll < 50){$('.'+itemClass).removeClass(itemHover);$('.'+itemClass+':eq(0)').addClass(itemHover);}}if(scrollDir == 'down' && varscroll > contentTop[i]-50 && varscroll < contentTop[i]+50) {$('.'+itemClass).removeClass(itemHover);$('.'+itemClass+':eq('+i+')').addClass(itemHover);}if(scrollDir == 'up') {bottomView(i);}}}if(vartop < varscroll + topMargin){$('.stuckMenu').addClass('isStuck');$('.stuckMenu').next().closest('div').css({'margin-top': stickyHeight + stickyMarginB + currentMarginT + 'px'}, 10);$('.stuckMenu').css("position","fixed");$('.isStuck').css({top: '0px'}, 10, function(){});};if(varscroll + topMargin < vartop){$('.stuckMenu').removeClass('isStuck');$('.stuckMenu').next().closest('div').css({'margin-top': currentMarginT + 'px'}, 10);$('.stuckMenu').css("position","relative");};});});}); -------------------------------------------------------------------------------- /uiControl/client_Slave/SlaveSocket.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | import socket 3 | import threading 4 | import time 5 | import json 6 | from util.excutor import executor 7 | 8 | class SlaveSocket(threading.Thread): 9 | BUFFER_SIZE = 2048*100 10 | 11 | def __init__(self, host='', port=5000, commandDict=None, openDict=None, timeout=5): 12 | threading.Thread.__init__(self) 13 | self.connected = False 14 | self.sock = None 15 | self.host = host 16 | self.port = port 17 | self.stop = False 18 | self.timeout = timeout 19 | self.executor = executor(commandDict, openDict) 20 | 21 | def connect(self): 22 | startTime = time.time() 23 | timeDelta = 0 24 | while timeDelta <= self.timeout: 25 | try: 26 | # 创建客户端套接字 27 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 28 | # 连接到服务器 29 | self.sock.connect((self.host, self.port)) 30 | self.connected = True 31 | return True 32 | except Exception, _: 33 | time.sleep(1) 34 | timeDelta = int(time.time() - startTime) 35 | if timeDelta > self.timeout: 36 | print u'连接超时' 37 | return False 38 | 39 | def run(self): 40 | while not self.stop: 41 | if not self.connected: 42 | print u'开始连接...' 43 | if self.connect(): 44 | print u'连接成功' 45 | else: 46 | try: 47 | data = self.sock.recv(self.BUFFER_SIZE) 48 | if len(data): 49 | self.analysisCommand(data) 50 | else: 51 | print u'socket 连接中断。' 52 | break 53 | except Exception, e: 54 | print 'socket error, because: %s ' % str(e) 55 | self.connected = False 56 | continue 57 | 58 | def analysisCommand(self, data): 59 | u''' 60 | {"command":"xxx", "type":"commandInConfig"} 61 | ''' 62 | print u'接受到的命令是: %s' % data 63 | if data: 64 | try: 65 | commandDict = json.loads(data[:-10]) 66 | except Exception, e: 67 | print u'命令格式不对。' 68 | return '' 69 | print str(commandDict) 70 | commandType = commandDict['type'] 71 | command = commandDict['command'] 72 | if command == 'runaway': 73 | self.stop = True 74 | self.sock.close() 75 | else: 76 | self.executor.execute(commandType, command) 77 | 78 | 79 | -------------------------------------------------------------------------------- /uiControl/server/util/SocketHelper.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | 3 | import socket 4 | import json 5 | import threading 6 | 7 | class SocketHelper(threading.Thread): 8 | BUFFER_SIZE = 2048*100 # 读取数据大小 9 | 10 | def __init__(self, host=None, port=None, name=None, socketSlavePool=[]): 11 | threading.Thread.__init__(self, name=name) 12 | self.host = host 13 | self.port = port 14 | self.sock = None 15 | self.stop = False 16 | self.name = name 17 | self.socketSlavePool = socketSlavePool 18 | 19 | def connect(self): 20 | try: 21 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 22 | self.sock.bind((self.host, self.port)) 23 | # 开启socket监听 24 | self.sock.listen(5) 25 | except Exception, e: 26 | print 'socket error because: %s' % str(e) 27 | return None 28 | 29 | def receive(self): 30 | if self.sock: 31 | conn, addr = self.sock.accept() 32 | print 'accept a new connect from address: %s' % str(addr) 33 | 34 | command = '' 35 | while True: 36 | # 读取数据,数据还没到来阻塞 37 | data = conn.recv(self.BUFFER_SIZE) 38 | if len(data): 39 | print data 40 | command += data 41 | else: 42 | print 'Server Recv finished' 43 | print 'the command is: %s' % command 44 | return {'conn': conn, 'command': command} 45 | 46 | def analysisCommand(self, rec): 47 | u''' 48 | 命令将会按照以下格式: 49 | {'who':{'from': 'master', 'ip': 'xx.xx.xx.xxx'}, 'command': 'yyyyy'} 50 | {'who':{'from': 'slave', 'ip': 'xx.xx.xx.xxx'}, 'info': 'yyyyy'} 51 | ''' 52 | conn = rec['conn'] 53 | command = rec['command'] 54 | try: 55 | commandDict = json.loads(command) 56 | except Exception, e: 57 | print 'the command is invaild!' 58 | whoFrom = commandDict['who']['from'] 59 | if whoFrom == 'master': 60 | self.doCommand(commandDict['who']['ip'], conn, commandDict['command']) 61 | elif whoFrom == 'slave': 62 | self.getSlaveInfo(commandDict['who']['ip'], conn, commandDict['info']) 63 | 64 | def doCommand(self, ip, conn, command): 65 | print 'ip is: %s' % ip 66 | print 'command is: %s' % command 67 | self.socketMasterPool.append({ip: conn}) 68 | 69 | def getSlaveInfo(self, ip, conn, info): 70 | print 'ip is: %s' % ip 71 | print 'info is: %s' % info 72 | self.socketSlavePool.append({ip: conn}) 73 | 74 | def close(self): 75 | if self.sock: 76 | self.sock.close() 77 | 78 | def run(self): 79 | self.connect() 80 | print 'connect done!' 81 | while not self.stop: 82 | rec = self.receive() 83 | if rec: 84 | print 'receive a connect!' 85 | self.analysisCommand(rec) 86 | 87 | 88 | def stop(self): 89 | self.stop = True 90 | self.close() 91 | -------------------------------------------------------------------------------- /uiControl/client_Master/MasterSocket.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | import socket 3 | import threading 4 | import time 5 | import json 6 | 7 | class MasterSocket(threading.Thread): 8 | BUFFER_SIZE = 2048*100 9 | 10 | def __init__(self, host='', port=5000, command='', serverList=None, commandType='', to='', timeout=5): 11 | threading.Thread.__init__(self) 12 | self.connected = False 13 | self.sock = None 14 | self.host = host 15 | self.port = port 16 | self.command = command 17 | self.timeout = timeout 18 | if serverList is not None: 19 | self.serverList = serverList 20 | 21 | if to: 22 | self.to = to 23 | else: 24 | self.to = '' 25 | if commandType: 26 | self.commandType = commandType 27 | else: 28 | self.commandType = '' 29 | 30 | def connect(self): 31 | startTime = time.time() 32 | timeDelta = 0 33 | while timeDelta <= self.timeout: 34 | try: 35 | # 创建客户端套接字 36 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 37 | # 连接到服务器 38 | self.sock.connect((self.host, self.port)) 39 | self.connected = True 40 | return True 41 | except Exception, _: 42 | time.sleep(1) 43 | timeDelta = int(time.time() - startTime) 44 | if timeDelta > self.timeout: 45 | print u'连接超时' 46 | return False 47 | 48 | def run(self): 49 | print u'开始连接...' 50 | if self.connect(): 51 | print u'连接成功' 52 | try: 53 | self.send(self.command) 54 | except Exception, e: 55 | print 'socket error, because: %s ' % str(e) 56 | 57 | def generateJson(self, fromWhere, command, to='', commandType=''): 58 | commandDict = {'from': fromWhere, 'to': to, 'command': command, 'type': commandType} 59 | return json.dumps(commandDict) 60 | 61 | def send(self, command): 62 | print u'往服务器发送数据: %s' % command 63 | receiveData = '' 64 | try: 65 | # 发起数据给服务器 66 | self.sock.sendall(self.generateJson('master', command, to=self.to, commandType=self.commandType)) 67 | 68 | while '#finished#' not in receiveData: 69 | # 接收服务器返回的数据 70 | data = self.sock.recv(self.BUFFER_SIZE) 71 | receiveData += data 72 | print u'收到服务器返回: %s' % receiveData 73 | self.analysisResult(receiveData) 74 | 75 | except socket.errno, e: 76 | print 'Socket error: %s' % str(e) 77 | except Exception, e: 78 | print 'Other exception: %s' % e 79 | finally: 80 | print u'关闭socket' 81 | self.sock.close() 82 | 83 | def analysisResult(self, result): 84 | print u'开始分析返回信息: %s' % result 85 | if result: 86 | try: 87 | resultDict = json.loads(result[:-10]) 88 | except Exception, e: 89 | print u'返回信息有误' 90 | return '' 91 | if 'slaveList' in resultDict: 92 | self.serverList += resultDict['slaveList'] 93 | print u'被控端列表: %s' % str(self.serverList) 94 | # self.sock.close() 95 | 96 | 97 | -------------------------------------------------------------------------------- /mcc/utils/mailHelper.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | 3 | from email.mime.text import MIMEText 4 | from .configReader import ConfigReader 5 | import logging 6 | import poplib 7 | import smtplib 8 | import re 9 | 10 | class mailHelper(object): 11 | CONFIGPATH = '_config.ini' 12 | 13 | def __init__(self): 14 | self.mccLog = logging.getLogger('mcc') 15 | cfReader = ConfigReader(self.CONFIGPATH) 16 | self.pophost = cfReader.readConfig('Slave', 'pophost') 17 | self.smtphost = cfReader.readConfig('Slave', 'smtphost') 18 | self.port = cfReader.readConfig('Slave', 'port') 19 | self.username = cfReader.readConfig('Slave', 'username') 20 | self.password = cfReader.readConfig('Slave', 'password') 21 | self.bossMail = cfReader.readConfig('Boss', 'mail') 22 | self.loginMail() 23 | self.configSlaveMail() 24 | 25 | def loginMail(self): 26 | self.mccLog.info('开始登录邮箱') 27 | try: 28 | self.pp = poplib.POP3_SSL(self.pophost) 29 | self.pp.set_debuglevel(1) 30 | self.pp.user(self.username) 31 | self.pp.pass_(self.password) 32 | self.pp.list() 33 | self.mccLog.info('登录邮箱成功。') 34 | except Exception as e: 35 | self.mccLog.error('登录邮箱失败' + str(e)) 36 | exit() 37 | 38 | def acceptMail(self): 39 | self.mccLog.info(u'开始抓取邮件。') 40 | try: 41 | ret = self.pp.list() 42 | mailBody = self.pp.retr(len(ret[1])) 43 | self.mccLog.info('抓取邮件成功。') 44 | return mailBody 45 | except Exception as e: 46 | self.mccLog.error('抓取邮件失败,因为{}'.format(e)) 47 | return None 48 | 49 | def analysisMail(self, mailBody): 50 | print(str(mailBody[1])) 51 | self.mccLog.info('开始抓取subject和发件人') 52 | try: 53 | subject = re.findall('Subject: (.*?)#f#', str(mailBody[1]), re.S)[0] 54 | 55 | sender = re.findall("'X-Sender: (.*?)', ", str(mailBody[1]), re.S)[0] 56 | self.mccLog.debug('subject 为:{}'.format(subject)) 57 | self.mccLog.debug('sender 为:{}'.format(sender)) 58 | 59 | command = {'subject': subject, 'sender': sender} 60 | self.mccLog.info('抓取subject和发件人成功') 61 | return command 62 | except Exception as e: 63 | self.mccLog.error('抓取subject和发件人失败' + str(e)) 64 | return None 65 | 66 | def configSlaveMail(self): 67 | self.mccLog.info('开始配置发件箱。') 68 | try: 69 | self.handle = smtplib.SMTP(self.smtphost, self.port) 70 | self.handle.login(self.username, self.password) 71 | self.mccLog.info('发件箱配置成功') 72 | except Exception as e: 73 | self.mccLog.error('发件箱配置失败' + str(e)) 74 | exit() 75 | 76 | def sendMail(self, subject, receiver, body='Success'): 77 | msg = MIMEText(body, 'plain', 'utf-8') #中文需参数‘utf-8’,单字节字符不需要 78 | msg['Subject'] = subject 79 | msg['from'] = self.username 80 | self.mccLog.info('开始发送邮件给:{}'.format(receiver)) 81 | if receiver == 'Slave': 82 | try: 83 | self.handle.sendmail(self.username, self.username, msg.as_string()) 84 | self.mccLog.info('发送邮件成功') 85 | return True 86 | except Exception as e: 87 | self.mccLog.error('发送邮件失败:{}'.format(e)) 88 | return False 89 | 90 | elif receiver == 'Boss': 91 | try: 92 | self.handle.sendmail(self.username, self.bossMail, msg.as_string()) 93 | self.mccLog.info('发送邮件成功') 94 | except Exception as e: 95 | self.mccLog.error('发送邮件失败:{}'.format(e)) 96 | return False 97 | -------------------------------------------------------------------------------- /uiControl/server/util/SocketThread.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | 3 | import socket 4 | import json 5 | import threading 6 | 7 | class SocketThread(threading.Thread): 8 | BUFFER_SIZE = 2048*100 # 读取数据大小 9 | def __init__(self, conn=None, ip=None, socketPool=None): 10 | threading.Thread.__init__(self) 11 | print u'生成一个socket, ip地址为: %s' % str(ip) 12 | self.conn = conn 13 | self.ip = ip 14 | self.socketPool = socketPool 15 | self.lock = threading.Lock() 16 | 17 | def getIp(self): 18 | return self.ip 19 | 20 | def sendToMaster(self, message): 21 | self.conn.sendall(self.generateReturn(message)) 22 | 23 | def run(self): 24 | while True: 25 | # 读取数据,数据还没到来阻塞 26 | try: 27 | data = self.conn.recv(self.BUFFER_SIZE) 28 | if len(data): 29 | self.analysisCommand(data) 30 | else: 31 | print u'对方关闭Socket。' 32 | self.lock.acquire() 33 | if self.ip in self.socketPool: 34 | self.socketPool.pop(self.ip) 35 | print 'pop1' 36 | print self.socketPool 37 | self.lock.release() 38 | break 39 | except Exception, e: 40 | print u'socket 连接中断。' 41 | self.lock.acquire() 42 | if self.ip in self.socketPool: 43 | self.socketPool.pop(self.ip) 44 | print 'pop2' 45 | self.lock.release() 46 | break 47 | 48 | def analysisCommand(self, command): 49 | u''' 50 | {"from":"master", "to": "xx.xx.xx.xx", "type": "commandInConfig", "command": "xxxx"} 51 | to的值可能是空,表示在服务器执行,会在是具体IP地址 52 | {"from":"slave", "info":"xxxx"} 53 | 54 | ''' 55 | try: 56 | print 'command is %s' % command 57 | commandDict = json.loads(command) 58 | except Exception, e: 59 | print 'command is invaild' 60 | return '' 61 | 62 | if commandDict: 63 | commandFrom = commandDict['from'] 64 | if commandFrom == 'master': 65 | #下面这一行用来解决第二次课遇到的问题 66 | self.socketPool.pop(self.ip) 67 | result = self.analysisMasterCommand(commandDict['type'], commandDict['to'], commandDict['command']) 68 | print result 69 | self.sendToMaster(result) 70 | 71 | def getSlaveList(self): 72 | print 'into get Slave list' 73 | self.lock.acquire() 74 | slaveList = self.socketPool.keys() 75 | self.lock.release() 76 | return slaveList 77 | 78 | def generateToSlaveMessage(self, message, commandType): 79 | return json.dumps({'command': message, 'type': commandType}) + '#finished#' 80 | 81 | def sendToSlave(self, connToSlave, message, commandType): 82 | print 'in send to slave' 83 | toSlaveMessage = self.generateToSlaveMessage(message, commandType) 84 | print u'以下命令将会被发送给被控端: %s' % toSlaveMessage 85 | try: 86 | connToSlave.send(toSlaveMessage) 87 | except Exception, e: 88 | print u'向被控端发送数据出错:%s' % str(e) 89 | 90 | def generateReturn(self, info): 91 | returnInfo = {'slaveList': info} 92 | returnInfo = json.dumps(returnInfo) 93 | returnInfo = returnInfo + '#finished#' 94 | print u'以下内容将会返回给控制端: %s' % returnInfo 95 | return returnInfo 96 | 97 | def analysisMasterCommand(self, commandType, to, command): 98 | if not to: 99 | print u'这条命令在服务器上执行, 命令是%s' % command 100 | if command == 'listSlave': 101 | return self.getSlaveList() 102 | print u'这条命令将会在%s上面执行,命令的类型是%s, 命令的内容是:%s' % (to, commandType, command) 103 | if to not in self.socketPool: 104 | print u'找不到ip地址为%s的被控端' % to 105 | return '' 106 | else: 107 | self.sendToSlave(self.socketPool[to], command, commandType) 108 | return '' 109 | -------------------------------------------------------------------------------- /uiControl/client_Master/Master.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf8-*- 2 | 3 | import wx 4 | from MasterSocket import MasterSocket 5 | import threading 6 | 7 | # SERVER = '128.199.151.202' 8 | SERVER = '192.168.2.100' 9 | PORT = 5000 10 | 11 | '''基于Sizer的控件相对布局''' 12 | class Slave(wx.Frame): 13 | def __init__(self): 14 | wx.Frame.__init__(self, parent=None, id=-1, title=u'极客学院', size=(600, 600)) 15 | self.panel = wx.Panel(self, -1) 16 | self.lock = threading.Lock() 17 | self.Centre() 18 | 19 | #定义我们需要的各个控件 20 | 21 | commandStatic = wx.StaticText(self.panel, -1, u'输命令:') 22 | writePyStatic = wx.StaticText(self.panel, -1, u'写代码:') 23 | 24 | self.commandText = wx.TextCtrl(self.panel, -1, u'') 25 | self.writePyText = wx.TextCtrl(self.panel, -1, u'''#-*-coding:utf-8-*-\n#python code here''', 26 | style=wx.TE_MULTILINE, size=(300, 200)) 27 | 28 | self.send = wx.Button(self.panel, label=u'发送命令') 29 | self.clear = wx.Button(self.panel, label=u'清空命令') 30 | self.screen = wx.Button(self.panel, label=u'查看屏幕') 31 | self.refresh = wx.Button(self.panel, label=u'刷新') 32 | 33 | # self.serverList = ['192.168.0.4', '10.19.2.1', '192.168.0.111', '172.26.123.5', '192.168.6.11', '192.99.8.8'] 34 | self.serverList = [] 35 | self.server = wx.ListBox(self.panel, -1, size=(120, 100), choices=self.serverList, style=wx.LB_SINGLE) 36 | 37 | img = wx.Image(r'logo.jpg', wx.BITMAP_TYPE_ANY).Scale(200, 200) 38 | self.screenBox = wx.StaticBitmap(self.panel, -1, wx.BitmapFromImage(img)) 39 | 40 | self.Bind(wx.EVT_BUTTON, self.onSend, self.send) 41 | self.Bind(wx.EVT_BUTTON, self.onClear, self.clear) 42 | self.Bind(wx.EVT_BUTTON, self.onScreen, self.screen) 43 | self.Bind(wx.EVT_BUTTON, self.onRefresh, self.refresh) 44 | 45 | #基于GirdBagSizer布局 46 | self.gridBagSizerAll = wx.GridBagSizer(hgap=5, vgap=5) 47 | self.gridBagSizerAll.Add(self.server, pos=(0, 0), 48 | flag=wx.ALL | wx.EXPAND, 49 | span=(6, 2), border=5) 50 | self.gridBagSizerAll.Add(self.refresh, pos=(6, 0), 51 | flag=wx.ALL | wx.EXPAND, 52 | span=(1, 2), border=5) 53 | 54 | self.gridBagSizerAll.Add(commandStatic, pos=(0, 2), 55 | flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, 56 | border=5) 57 | self.gridBagSizerAll.Add(self.commandText, pos=(0, 3), 58 | flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, 59 | span=(1, 2), border=5) 60 | 61 | self.gridBagSizerAll.Add(writePyStatic, pos=(1, 2), 62 | flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, 63 | span=(1, 3), border=5) 64 | self.gridBagSizerAll.Add(self.writePyText, pos=(2, 2), 65 | flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, 66 | span=(4, 3), border=5) 67 | self.gridBagSizerAll.Add(self.send, pos=(6, 2), 68 | flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, 69 | span=(1, 1), border=5) 70 | self.gridBagSizerAll.Add(self.clear, pos=(6, 3), 71 | flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, 72 | span=(1, 1), border=5) 73 | self.gridBagSizerAll.Add(self.screen, pos=(6, 4), 74 | flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, 75 | span=(1, 1), border=5) 76 | 77 | self.gridBagSizerAll.Add(self.screenBox, pos=(0, 5), 78 | flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, 79 | span=(7, 2), border=5) 80 | 81 | self.panel.SetSizer(self.gridBagSizerAll) 82 | 83 | # self.SetSizeHints(250, 200, 700, 400) #设定窗口的最大最小值 84 | self.gridBagSizerAll.AddGrowableCol(0, 1) 85 | self.gridBagSizerAll.AddGrowableCol(1, 1) 86 | self.gridBagSizerAll.AddGrowableCol(2, 1) 87 | self.gridBagSizerAll.AddGrowableCol(3, 1) 88 | self.gridBagSizerAll.AddGrowableCol(4, 1) 89 | self.gridBagSizerAll.AddGrowableCol(5, 1) 90 | self.gridBagSizerAll.AddGrowableCol(6, 1) 91 | 92 | self.gridBagSizerAll.AddGrowableRow(0, 1) 93 | self.gridBagSizerAll.AddGrowableRow(1, 1) 94 | self.gridBagSizerAll.AddGrowableRow(2, 1) 95 | self.gridBagSizerAll.AddGrowableRow(3, 1) 96 | self.gridBagSizerAll.AddGrowableRow(4, 1) 97 | self.gridBagSizerAll.AddGrowableRow(5, 1) 98 | self.gridBagSizerAll.AddGrowableRow(6, 1) 99 | self.gridBagSizerAll.Fit(self) 100 | 101 | def onSend(self, event): 102 | server = self.server.GetSelection() 103 | if server != -1: 104 | slave = self.serverList[server] 105 | command = self.commandText.GetValue() 106 | writePy = self.writePyText.GetValue() 107 | if command: 108 | print u'输入的命令是: %s' % command 109 | self.masterSocket = MasterSocket(SERVER, PORT, command, commandType='commandInConfig', to=slave) 110 | elif writePy: 111 | self.masterSocket = MasterSocket(SERVER, PORT, writePy, commandType='commandInWrite', to=slave) 112 | else: 113 | print u'请输入命令' 114 | return None 115 | self.masterSocket.setDaemon(True) 116 | self.masterSocket.start() 117 | else: 118 | print u'请先选择被控端。' 119 | return None 120 | 121 | def onClear(self, event): 122 | self.commandText.Clear() 123 | self.writePyText.Clear() 124 | self.writePyText.AppendText(u'''#-*-coding:utf-8-*-\n#Python code here''') 125 | 126 | def onScreen(self, event): 127 | img = wx.Image(r'python.jpg', wx.BITMAP_TYPE_ANY).Scale(300, 200) 128 | self.screenBox.SetBitmap(wx.BitmapFromImage(img)) 129 | self.gridBagSizerAll.Fit(self) 130 | 131 | def onRefresh(self, event): 132 | self.serverList = [] 133 | 134 | socketForServerList = MasterSocket(SERVER, PORT, 'listSlave', self.serverList) 135 | socketForServerList.setDaemon(True) 136 | socketForServerList.start() 137 | socketForServerList.join() 138 | 139 | self.lock.acquire() 140 | print u'被控端列表111:%s' % str(self.serverList) 141 | self.server.Clear() 142 | for each in self.serverList: 143 | self.server.Append(each) 144 | self.lock.release() 145 | 146 | if __name__ == "__main__": 147 | app = wx.App() 148 | frame = Slave() 149 | frame.Show() 150 | app.MainLoop() 151 | -------------------------------------------------------------------------------- /wcc/static/css/bootstrap-theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.2 (http://getbootstrap.com) 3 | * Copyright 2011-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary:disabled,.btn-primary[disabled]{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} -------------------------------------------------------------------------------- /wcc/static/css/bootstrap-theme.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.2 (http://getbootstrap.com) 3 | * Copyright 2011-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | .btn-default, 8 | .btn-primary, 9 | .btn-success, 10 | .btn-info, 11 | .btn-warning, 12 | .btn-danger { 13 | text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); 14 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); 15 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); 16 | } 17 | .btn-default:active, 18 | .btn-primary:active, 19 | .btn-success:active, 20 | .btn-info:active, 21 | .btn-warning:active, 22 | .btn-danger:active, 23 | .btn-default.active, 24 | .btn-primary.active, 25 | .btn-success.active, 26 | .btn-info.active, 27 | .btn-warning.active, 28 | .btn-danger.active { 29 | -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); 30 | box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); 31 | } 32 | .btn-default .badge, 33 | .btn-primary .badge, 34 | .btn-success .badge, 35 | .btn-info .badge, 36 | .btn-warning .badge, 37 | .btn-danger .badge { 38 | text-shadow: none; 39 | } 40 | .btn:active, 41 | .btn.active { 42 | background-image: none; 43 | } 44 | .btn-default { 45 | text-shadow: 0 1px 0 #fff; 46 | background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); 47 | background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); 48 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); 49 | background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); 50 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); 51 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 52 | background-repeat: repeat-x; 53 | border-color: #dbdbdb; 54 | border-color: #ccc; 55 | } 56 | .btn-default:hover, 57 | .btn-default:focus { 58 | background-color: #e0e0e0; 59 | background-position: 0 -15px; 60 | } 61 | .btn-default:active, 62 | .btn-default.active { 63 | background-color: #e0e0e0; 64 | border-color: #dbdbdb; 65 | } 66 | .btn-default.disabled, 67 | .btn-default:disabled, 68 | .btn-default[disabled] { 69 | background-color: #e0e0e0; 70 | background-image: none; 71 | } 72 | .btn-primary { 73 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); 74 | background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); 75 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); 76 | background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); 77 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); 78 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 79 | background-repeat: repeat-x; 80 | border-color: #245580; 81 | } 82 | .btn-primary:hover, 83 | .btn-primary:focus { 84 | background-color: #265a88; 85 | background-position: 0 -15px; 86 | } 87 | .btn-primary:active, 88 | .btn-primary.active { 89 | background-color: #265a88; 90 | border-color: #245580; 91 | } 92 | .btn-primary.disabled, 93 | .btn-primary:disabled, 94 | .btn-primary[disabled] { 95 | background-color: #265a88; 96 | background-image: none; 97 | } 98 | .btn-success { 99 | background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); 100 | background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); 101 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); 102 | background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); 103 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); 104 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 105 | background-repeat: repeat-x; 106 | border-color: #3e8f3e; 107 | } 108 | .btn-success:hover, 109 | .btn-success:focus { 110 | background-color: #419641; 111 | background-position: 0 -15px; 112 | } 113 | .btn-success:active, 114 | .btn-success.active { 115 | background-color: #419641; 116 | border-color: #3e8f3e; 117 | } 118 | .btn-success.disabled, 119 | .btn-success:disabled, 120 | .btn-success[disabled] { 121 | background-color: #419641; 122 | background-image: none; 123 | } 124 | .btn-info { 125 | background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); 126 | background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); 127 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); 128 | background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); 129 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); 130 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 131 | background-repeat: repeat-x; 132 | border-color: #28a4c9; 133 | } 134 | .btn-info:hover, 135 | .btn-info:focus { 136 | background-color: #2aabd2; 137 | background-position: 0 -15px; 138 | } 139 | .btn-info:active, 140 | .btn-info.active { 141 | background-color: #2aabd2; 142 | border-color: #28a4c9; 143 | } 144 | .btn-info.disabled, 145 | .btn-info:disabled, 146 | .btn-info[disabled] { 147 | background-color: #2aabd2; 148 | background-image: none; 149 | } 150 | .btn-warning { 151 | background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); 152 | background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); 153 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); 154 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); 155 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); 156 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 157 | background-repeat: repeat-x; 158 | border-color: #e38d13; 159 | } 160 | .btn-warning:hover, 161 | .btn-warning:focus { 162 | background-color: #eb9316; 163 | background-position: 0 -15px; 164 | } 165 | .btn-warning:active, 166 | .btn-warning.active { 167 | background-color: #eb9316; 168 | border-color: #e38d13; 169 | } 170 | .btn-warning.disabled, 171 | .btn-warning:disabled, 172 | .btn-warning[disabled] { 173 | background-color: #eb9316; 174 | background-image: none; 175 | } 176 | .btn-danger { 177 | background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); 178 | background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); 179 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); 180 | background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); 181 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); 182 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 183 | background-repeat: repeat-x; 184 | border-color: #b92c28; 185 | } 186 | .btn-danger:hover, 187 | .btn-danger:focus { 188 | background-color: #c12e2a; 189 | background-position: 0 -15px; 190 | } 191 | .btn-danger:active, 192 | .btn-danger.active { 193 | background-color: #c12e2a; 194 | border-color: #b92c28; 195 | } 196 | .btn-danger.disabled, 197 | .btn-danger:disabled, 198 | .btn-danger[disabled] { 199 | background-color: #c12e2a; 200 | background-image: none; 201 | } 202 | .thumbnail, 203 | .img-thumbnail { 204 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 205 | box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 206 | } 207 | .dropdown-menu > li > a:hover, 208 | .dropdown-menu > li > a:focus { 209 | background-color: #e8e8e8; 210 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 211 | background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 212 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); 213 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); 214 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); 215 | background-repeat: repeat-x; 216 | } 217 | .dropdown-menu > .active > a, 218 | .dropdown-menu > .active > a:hover, 219 | .dropdown-menu > .active > a:focus { 220 | background-color: #2e6da4; 221 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 222 | background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 223 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); 224 | background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); 225 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); 226 | background-repeat: repeat-x; 227 | } 228 | .navbar-default { 229 | background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); 230 | background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); 231 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); 232 | background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); 233 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); 234 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 235 | background-repeat: repeat-x; 236 | border-radius: 4px; 237 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); 238 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); 239 | } 240 | .navbar-default .navbar-nav > .open > a, 241 | .navbar-default .navbar-nav > .active > a { 242 | background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); 243 | background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); 244 | background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); 245 | background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); 246 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); 247 | background-repeat: repeat-x; 248 | -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); 249 | box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); 250 | } 251 | .navbar-brand, 252 | .navbar-nav > li > a { 253 | text-shadow: 0 1px 0 rgba(255, 255, 255, .25); 254 | } 255 | .navbar-inverse { 256 | background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); 257 | background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); 258 | background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); 259 | background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); 260 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); 261 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 262 | background-repeat: repeat-x; 263 | } 264 | .navbar-inverse .navbar-nav > .open > a, 265 | .navbar-inverse .navbar-nav > .active > a { 266 | background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); 267 | background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); 268 | background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); 269 | background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); 270 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); 271 | background-repeat: repeat-x; 272 | -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); 273 | box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); 274 | } 275 | .navbar-inverse .navbar-brand, 276 | .navbar-inverse .navbar-nav > li > a { 277 | text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); 278 | } 279 | .navbar-static-top, 280 | .navbar-fixed-top, 281 | .navbar-fixed-bottom { 282 | border-radius: 0; 283 | } 284 | @media (max-width: 767px) { 285 | .navbar .navbar-nav .open .dropdown-menu > .active > a, 286 | .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, 287 | .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { 288 | color: #fff; 289 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 290 | background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 291 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); 292 | background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); 293 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); 294 | background-repeat: repeat-x; 295 | } 296 | } 297 | .alert { 298 | text-shadow: 0 1px 0 rgba(255, 255, 255, .2); 299 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); 300 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); 301 | } 302 | .alert-success { 303 | background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); 304 | background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); 305 | background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); 306 | background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); 307 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); 308 | background-repeat: repeat-x; 309 | border-color: #b2dba1; 310 | } 311 | .alert-info { 312 | background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); 313 | background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); 314 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); 315 | background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); 316 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); 317 | background-repeat: repeat-x; 318 | border-color: #9acfea; 319 | } 320 | .alert-warning { 321 | background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); 322 | background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); 323 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); 324 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); 325 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); 326 | background-repeat: repeat-x; 327 | border-color: #f5e79e; 328 | } 329 | .alert-danger { 330 | background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); 331 | background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); 332 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); 333 | background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); 334 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); 335 | background-repeat: repeat-x; 336 | border-color: #dca7a7; 337 | } 338 | .progress { 339 | background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); 340 | background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); 341 | background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); 342 | background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); 343 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); 344 | background-repeat: repeat-x; 345 | } 346 | .progress-bar { 347 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); 348 | background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); 349 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); 350 | background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); 351 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); 352 | background-repeat: repeat-x; 353 | } 354 | .progress-bar-success { 355 | background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); 356 | background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); 357 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); 358 | background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); 359 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); 360 | background-repeat: repeat-x; 361 | } 362 | .progress-bar-info { 363 | background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); 364 | background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); 365 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); 366 | background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); 367 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); 368 | background-repeat: repeat-x; 369 | } 370 | .progress-bar-warning { 371 | background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); 372 | background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); 373 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); 374 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); 375 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); 376 | background-repeat: repeat-x; 377 | } 378 | .progress-bar-danger { 379 | background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); 380 | background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); 381 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); 382 | background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); 383 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); 384 | background-repeat: repeat-x; 385 | } 386 | .progress-bar-striped { 387 | 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); 388 | 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); 389 | 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); 390 | } 391 | .list-group { 392 | border-radius: 4px; 393 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 394 | box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 395 | } 396 | .list-group-item.active, 397 | .list-group-item.active:hover, 398 | .list-group-item.active:focus { 399 | text-shadow: 0 -1px 0 #286090; 400 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); 401 | background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); 402 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); 403 | background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); 404 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); 405 | background-repeat: repeat-x; 406 | border-color: #2b669a; 407 | } 408 | .list-group-item.active .badge, 409 | .list-group-item.active:hover .badge, 410 | .list-group-item.active:focus .badge { 411 | text-shadow: none; 412 | } 413 | .panel { 414 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); 415 | box-shadow: 0 1px 2px rgba(0, 0, 0, .05); 416 | } 417 | .panel-default > .panel-heading { 418 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 419 | background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 420 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); 421 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); 422 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); 423 | background-repeat: repeat-x; 424 | } 425 | .panel-primary > .panel-heading { 426 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 427 | background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 428 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); 429 | background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); 430 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); 431 | background-repeat: repeat-x; 432 | } 433 | .panel-success > .panel-heading { 434 | background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); 435 | background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); 436 | background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); 437 | background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); 438 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); 439 | background-repeat: repeat-x; 440 | } 441 | .panel-info > .panel-heading { 442 | background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); 443 | background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); 444 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); 445 | background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); 446 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); 447 | background-repeat: repeat-x; 448 | } 449 | .panel-warning > .panel-heading { 450 | background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); 451 | background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); 452 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); 453 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); 454 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); 455 | background-repeat: repeat-x; 456 | } 457 | .panel-danger > .panel-heading { 458 | background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); 459 | background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); 460 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); 461 | background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); 462 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); 463 | background-repeat: repeat-x; 464 | } 465 | .well { 466 | background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); 467 | background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); 468 | background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); 469 | background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); 470 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); 471 | background-repeat: repeat-x; 472 | border-color: #dcdcdc; 473 | -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); 474 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); 475 | } 476 | /*# sourceMappingURL=bootstrap-theme.css.map */ 477 | -------------------------------------------------------------------------------- /wcc/static/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.5 (http://getbootstrap.com) 3 | * Copyright 2011-2015 Twitter, Inc. 4 | * Licensed under the MIT license 5 | */ 6 | if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.5",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.5",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.5",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.5",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.5",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.5",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.5",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); -------------------------------------------------------------------------------- /wcc/static/css/bootstrap-theme.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","bootstrap-theme.css","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"AAcA;;;;;;EAME,0CAAA;ECgDA,6FAAA;EACQ,qFAAA;EC5DT;AFgBC;;;;;;;;;;;;EC2CA,0DAAA;EACQ,kDAAA;EC7CT;AFVD;;;;;;EAiBI,mBAAA;EECH;AFiCC;;EAEE,wBAAA;EE/BH;AFoCD;EGnDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EAgC2C,2BAAA;EAA2B,oBAAA;EEzBvE;AFLC;;EAEE,2BAAA;EACA,8BAAA;EEOH;AFJC;;EAEE,2BAAA;EACA,uBAAA;EEMH;AFHC;;;EAGE,2BAAA;EACA,wBAAA;EEKH;AFUD;EGpDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EEgCD;AF9BC;;EAEE,2BAAA;EACA,8BAAA;EEgCH;AF7BC;;EAEE,2BAAA;EACA,uBAAA;EE+BH;AF5BC;;;EAGE,2BAAA;EACA,wBAAA;EE8BH;AFdD;EGrDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EEyDD;AFvDC;;EAEE,2BAAA;EACA,8BAAA;EEyDH;AFtDC;;EAEE,2BAAA;EACA,uBAAA;EEwDH;AFrDC;;;EAGE,2BAAA;EACA,wBAAA;EEuDH;AFtCD;EGtDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EEkFD;AFhFC;;EAEE,2BAAA;EACA,8BAAA;EEkFH;AF/EC;;EAEE,2BAAA;EACA,uBAAA;EEiFH;AF9EC;;;EAGE,2BAAA;EACA,wBAAA;EEgFH;AF9DD;EGvDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EE2GD;AFzGC;;EAEE,2BAAA;EACA,8BAAA;EE2GH;AFxGC;;EAEE,2BAAA;EACA,uBAAA;EE0GH;AFvGC;;;EAGE,2BAAA;EACA,wBAAA;EEyGH;AFtFD;EGxDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EEoID;AFlIC;;EAEE,2BAAA;EACA,8BAAA;EEoIH;AFjIC;;EAEE,2BAAA;EACA,uBAAA;EEmIH;AFhIC;;;EAGE,2BAAA;EACA,wBAAA;EEkIH;AFxGD;;EChBE,oDAAA;EACQ,4CAAA;EC4HT;AFnGD;;EGzEI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EHwEF,2BAAA;EEyGD;AFvGD;;;EG9EI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH8EF,2BAAA;EE6GD;AFpGD;EG3FI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ECnBF,qEAAA;EJ6GA,oBAAA;EC/CA,6FAAA;EACQ,qFAAA;EC0JT;AF/GD;;EG3FI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EF2CF,0DAAA;EACQ,kDAAA;ECoKT;AF5GD;;EAEE,gDAAA;EE8GD;AF1GD;EG9GI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ECnBF,qEAAA;EF+OD;AFlHD;;EG9GI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EF2CF,yDAAA;EACQ,iDAAA;EC0LT;AF5HD;;EAYI,2CAAA;EEoHH;AF/GD;;;EAGE,kBAAA;EEiHD;AF5FD;EAfI;;;IAGE,aAAA;IG3IF,0EAAA;IACA,qEAAA;IACA,+FAAA;IAAA,wEAAA;IACA,6BAAA;IACA,wHAAA;ID0PD;EACF;AFxGD;EACE,+CAAA;ECzGA,4FAAA;EACQ,oFAAA;ECoNT;AFhGD;EGpKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH4JF,uBAAA;EE4GD;AFvGD;EGrKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH4JF,uBAAA;EEoHD;AF9GD;EGtKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH4JF,uBAAA;EE4HD;AFrHD;EGvKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH4JF,uBAAA;EEoID;AFrHD;EG/KI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDuSH;AFlHD;EGzLI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED8SH;AFxHD;EG1LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDqTH;AF9HD;EG3LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED4TH;AFpID;EG5LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDmUH;AF1ID;EG7LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED0UH;AF7ID;EGhKI,+MAAA;EACA,0MAAA;EACA,uMAAA;EDgTH;AFzID;EACE,oBAAA;EC5JA,oDAAA;EACQ,4CAAA;ECwST;AF1ID;;;EAGE,+BAAA;EGjNE,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH+MF,uBAAA;EEgJD;AFrJD;;;EAQI,mBAAA;EEkJH;AFxID;ECjLE,mDAAA;EACQ,2CAAA;EC4TT;AFlID;EG1OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED+WH;AFxID;EG3OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDsXH;AF9ID;EG5OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED6XH;AFpJD;EG7OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDoYH;AF1JD;EG9OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED2YH;AFhKD;EG/OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDkZH;AFhKD;EGtPI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EHoPF,uBAAA;ECzMA,2FAAA;EACQ,mFAAA;ECgXT","file":"bootstrap-theme.css","sourcesContent":["\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &:disabled,\n &[disabled] {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n",".btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default:disabled,\n.btn-default[disabled] {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary:disabled,\n.btn-primary[disabled] {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success:disabled,\n.btn-success[disabled] {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info:disabled,\n.btn-info[disabled] {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning:disabled,\n.btn-warning[disabled] {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger:disabled,\n.btn-danger[disabled] {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} --------------------------------------------------------------------------------