diff --git a/.hgignore b/.hgignore deleted file mode 100644 index 719fed9..0000000 --- a/.hgignore +++ /dev/null @@ -1,11 +0,0 @@ -syntax: regexp -Application/start_businessWorker.php -Application/start_crontab.php -Application/start_gateway.php -Application/start_gateway_text.php -Application/start_register.php -Config/Db.php -Config/Mem.php -Config/Site.php -workerman.log -_home_ChatRoomDev_start.php.pid diff --git a/Application/AdminClient.php b/Application/AdminClient.php deleted file mode 100644 index e9621f0..0000000 --- a/Application/AdminClient.php +++ /dev/null @@ -1,531 +0,0 @@ -array('length'=>15,'time'=>10), - 1=>array('length'=>50,'time'=>8), - 2=>array('length'=>50,'time'=>5), - 3=>array('length'=>50,'time'=>5), - 4=>array('length'=>50,'time'=>3), - 5=>array('length'=>50,'time'=>3), - 6=>array('length'=>50,'time'=>3), - 7=>array('length'=>50,'time'=>3), - 8=>array('length'=>50,'time'=>3), - 9=>array('length'=>50,'time'=>3), - 10=>array('length'=>50,'time'=>3), - 11=>array('length'=>80,'time'=>1), - 12=>array('length'=>80,'time'=>1), - 13=>array('length'=>80,'time'=>1), - 14=>array('length'=>80,'time'=>1), - 15=>array('length'=>80,'time'=>1), - 16=>array('length'=>80,'time'=>1), - 17=>array('length'=>80,'time'=>1), - 18=>array('length'=>80,'time'=>1), - 19=>array('length'=>80,'time'=>1), - 20=>array('length'=>80,'time'=>1), - 21=>array('length'=>80,'time'=>1), - 22=>array('length'=>80,'time'=>1), - 23=>array('length'=>80,'time'=>1), - 24=>array('length'=>80,'time'=>1), - 25=>array('length'=>80,'time'=>1), - 26=>array('length'=>80,'time'=>1), - 27=>array('length'=>80,'time'=>1), - 28=>array('length'=>80,'time'=>1), - 29=>array('length'=>80,'time'=>1), - //房主/管理 - 100=>array('length'=>80,'time'=>1) - ); - /** - * 添加系统管理员 - */ - public static function addSysAdminer($room_id, $user_id) - { - $_SESSION['role'] = 'sysAdminer'; - RoomStatus::addSysAdminer($user_id); - Gateway::sendToGroup($room_id, json_encode(array('type'=>'right.adminer', 'user_id'=>$user_id,'vip'=>$_SESSION['vip'],'levelid'=>$_SESSION['levelid']))); - } - - /** - * 删除系统管理员 - */ - public static function removeSysAdminer($room_id, $user_id) - { - if (isset($_SESSION['role']) && strcmp('sysAdminer', $_SESSION['role']) === 0) { - unset($_SESSION['role']); - RoomStatus::removeSysAdminer($user_id); - Gateway::sendToGroup($room_id, json_encode(array('type'=>'right.removeAdminer', 'user_id'=>$user_id,'vip'=>$_SESSION['vip'],'levelid'=>$_SESSION['levelid']))); - } - } - /** - * 添加管理员 - */ - public static function adminer($room_id, $managed_user_id, $managed_client_id_array, $managed_client_name, $self = false, $upDb = true) - { - if ($upDb) { - // 写入数据库 - $ret = Db::instance('dbDefault')->query("select id as uid from ss_member where curroomnum={$room_id}"); - if (!empty($ret[0])) { - $uid = $ret[0]['uid']; - $time = time(); - $exist = Db::instance('dbDefault')->query("select id from ss_roomadmin where uid='{$uid}' and adminuid='{$managed_user_id}'"); - if (empty($exist)) { - Db::instance('dbDefault')->query("insert into ss_roomadmin value (null,{$uid},{$managed_user_id},{$time})"); - } - } - } - Gateway::sendToGroup($room_id, json_encode(array('type'=>'right.adminer', 'user_id'=>$managed_user_id,'vip'=>$_SESSION['vip'],'levelid'=>$_SESSION['levelid']))); - if ($self) { - $_SESSION['role'] = 'adminer'; - } else { - $session_for_update = array('role'=>'adminer'); - foreach ($managed_client_id_array as $managed_client_id) { - \GatewayWorker\Lib\Gateway::updateSession($managed_client_id, $session_for_update); - } - } - return RoomStatus::addAdminer($room_id, $managed_user_id); - } - - /** - * 删除管理员 - */ - public static function removeAdminer($room_id, $managed_user_id, $managed_client_id_array, $managed_client_name, $self = false, $upDb = true) - { - if ($upDb) { - // 从数据库删除 - $ret = Db::instance('dbDefault')->query("select id as uid from ss_member where curroomnum={$room_id}"); - if (!empty($ret[0])) { - $uid = $ret[0]['uid']; - Db::instance('dbDefault')->query("delete from ss_roomadmin where uid={$uid} and adminuid={$managed_user_id}"); - } - } - - Gateway::sendToGroup($room_id, json_encode(array('type'=>'right.removeAdminer', 'user_id'=>$managed_user_id,'vip'=>$_SESSION['vip'],'levelid'=>$_SESSION['levelid']))); - if ($self) { - unset($_SESSION['role']); - } else { - foreach ($managed_client_id_array as $managed_client_id) { - $session = \GatewayWorker\Lib\Gateway::getSession($managed_client_id); - if($session) { - unset($session['role']); - \GatewayWorker\Lib\Gateway::setSession($managed_client_id, $session); - } - } - } - return RoomStatus::removeAdminer($room_id, $managed_user_id); - } - - public static function addKicked($room_id, $managed_user_id, $managed_client_id_array, $managed_client_name) - { - // 踢人,让该用户退出房间,并广播至所有人 - RoomStatus::addKicked($room_id, $managed_user_id, time()+3600); - foreach( $managed_client_id_array as $managed_client_id) { - Gateway::sendToClient($managed_client_id, json_encode(array('type'=>'error.kicked','content'=>'您已被踢出房间 1 小时'))); - Gateway::closeClient($managed_client_id); - } - - // $new_message = array( - // "type"=>"error", - // "kicked_client_id" => $managed_client_id, - // 'kicked_client_name' => $managed_client_name, - // "content"=>"$managed_client_name 已被踢出房间", - // ); - // return Gateway::sendToGroup($room_id, json_encode($new_message)); - } - - public static function removeKicked($room_id, $managed_user_id, $managed_client_id_array, $managed_client_name) - { - return RoomStatus::removeKicked($room_id, $managed_user_id); - } - - public static function disableMsg($room_id, $managed_user_id, $managed_client_id_array, $managed_client_name) - { - // 禁言,并广播至所有人 - $expire = time() + 300; - RoomStatus::disableMsg($room_id, $managed_user_id, $expire); - $session_for_update = array( - 'disableMsg' => true, - 'expire' => $expire - ); - // Gateway::sendToClient($managed_client_id, json_encode(array("type"=>"error.disableMsg","content"=>"您已被管理员禁言"))); - - foreach ($managed_client_id_array as $managed_client_id) { - \GatewayWorker\Lib\Gateway::updateSession($managed_client_id, $session_for_update); - } - - $new_message = array( - "type" => "sysmsg", - "content" => "$managed_client_name 已被管理员禁言5分钟", - ); - Gateway::sendToGroup($room_id, json_encode($new_message)); - } - - public static function enableMsg($room_id, $managed_user_id, $managed_client_id_array, $managed_client_name) - { - // 允许发言 - RoomStatus::enableMsg($room_id, $managed_user_id); - - foreach ($managed_client_id_array as $managed_client_id) { - $session = \GatewayWorker\Lib\Gateway::getSession($managed_client_id); - if($session){ - unset($session['disableMsg']); - unset($session['expire']); - \GatewayWorker\Lib\Gateway::setSession($managed_client_id, $session); - } - } - } - - /** - * 判断用户角色 - */ - public static function getClientRole($room_id, $user_id, &$expire = 0) - { - $role = null; - //TODO 从MEM中获取当前房间信息 - $roomStatus = RoomStatus::getRoomStatus($room_id); - $sysAdminer = RoomStatus::getSysAdminer(); - if (strcmp($user_id, $roomStatus['owner']) === 0) { - return 'owner'; - } - if (in_array($user_id, $sysAdminer)) { - return 'sysAdminer'; - } - if (is_null($roomStatus)) { - return $role; - } - /* - $roomStatus = array( - 'owner' => 0000, - 'adminer' => array( - 790=>790 - ), - 'kicked' => array( - // 790=>1453909804, - ), - 'disableMsg' => array( - 790 => 1453909804, - ), - ); - */ - else if (in_array($user_id, $roomStatus['adminer'])) { - $role = 'adminer'; - } else if (isset($roomStatus['kicked'][$user_id])) { - $role = 'kicked'; - $expire = $roomStatus['kicked'][$user_id]; - } else if (isset($roomStatus['disableMsg'][$user_id])) { - $expire = $roomStatus['disableMsg'][$user_id]; - if ($expire >= time()) { - $role = 'disableMsg'; - } - } - - return $role; - } - - public static function isEnableMsg() - { - if (isset($_SESSION['role']) && strcmp($_SESSION['role'], 'adminer') === 0) { - return true; - } - if (isset($_SESSION['disableMsg'])) { - if ($_SESSION['expire'] >= time()) { - // 解禁发言时间未到 - return false; - } else { - // 禁言时间已过 - unset($_SESSION['disableMsg']); - unset($_SESSION['expire']); - return true; - } - } - return true; - } - - /** - *是否从网页端登录,并且没有被踢出房间 - */ - public static function isLogged($user_id, $token) - { - if (!is_null($token) && !empty($token) && strcmp(RoomStatus::getUserSession($user_id, $token), $token) === 0) { - return true; - } - return false; - } - - public static function hasVipPrivilete($user_id) - { - $privilete = RoomStatus::getVipStatus($user_id); - if (is_null($privilete)) { - return 0; - } - if (isset($privilete['vip']) && ($privilete['vip'] == 1 || $privilete['vip'] == 2)) { - return $privilete['vip']; - } - return 0; - } - /** - *是否能管理该用户 - */ - public static function ableToManage($user_id, $room_id) - { - return RoomStatus::ableToManage($user_id, $room_id); - } - - /** - *获取房间管理员 - */ - public static function getRoomAdminer($room_id) - { - $ret = array(); - $roomStatus = RoomStatus::getRoomStatus($room_id); - $ret['roomAdminer'] = isset($roomStatus['adminer']) ? $roomStatus['adminer'] : array(); - $ret['sysAdminer'] = RoomStatus::getSysAdminer(); - return $ret; - } - - public static function checkUserRoleChanged($user_id, $room_id, $role = null) - { - if (!empty(RoomStatus::$changedSysStatus)) { - if (isset(RoomStatus::$changedSysStatus['add'][$user_id])) { - unset(RoomStatus::$changedSysStatus['add'][$user_id]); - if (strcmp($role, 'sysAdminer') !== 0) { - return 'addSysAdminer'; - } - } - if (isset(RoomStatus::$changedSysStatus['remove'][$user_id])) { - unset(RoomStatus::$changedSysStatus['remove'][$user_id]); - if (strcmp($role, 'sysAdminer') === 0) { - return 'removeSysAdminer'; - } - } - } - - if (!empty(RoomStatus::$changedRoomStatus) && isset(RoomStatus::$changedRoomStatus[$room_id])) { - if (isset(RoomStatus::$changedRoomStatus[$room_id]['add'][$user_id])) { - unset(RoomStatus::$changedRoomStatus[$room_id]['add'][$user_id]); - if (!$role) { - return 'adminer'; - } - } - if (isset(RoomStatus::$changedRoomStatus[$room_id]['remove'][$user_id])) { - unset(RoomStatus::$changedRoomStatus[$room_id]['remove'][$user_id]); - if (strcmp($role, 'adminer') === 0) { - return 'removeAdminer'; - } - } - } - return null; - } - - /** - * 用户是否在当前房间 - * @param int $user_id - * @param int $room_id - * @return bool - */ - public static function inCurrentRoom($user_id, $room_id) - { - return false; - $clientList = Gateway::getClientInfoByGroup($room_id); - foreach($clientList as $client) { - if (!empty($client) && $client['user_id'] == $user_id) { - return true; - } - } - return false; - } - - /** - * 是否可以发私信 - */ - public static function ablePriMsg() - { - if (isset($_SESSION['role']) && in_array($_SESSION['role'],array('owner','adminer','sysAdminer'))) { - return true; - } - if ($_SESSION['levelid'] <= 2) { - return false; - } - return true; - } - - /** - * 限制发消息频率 - */ - public static function msgFrequency($length, &$msg) - { - $time = time(); - if (isset($_SESSION['role']) && in_array($_SESSION['role'],array('adminer','sysAdminer','owner'))) { - $msg = "房主/管理员每" . static::$frequency[100]['time'] . "秒发一次消息,每条消息不得超过" . static::$frequency[100]['length'] . "字"; - if ($_SESSION['msged']) { - if ($time - $_SESSION['time'] < static::$frequency[100]['time']) { - return false; - } else if ($length > static::$frequency[100]['length']) { - return false; - } - $_SESSION['time'] = $time; - return true; - } else if ($length > static::$frequency[100]['length']) { - $_SESSION['msged'] = true; - return false; - } - $_SESSION['msged'] = true; - return true; - } - if (isset(static::$frequency[$_SESSION['levelid']])) { - $msg = "富豪等级" . $_SESSION['levelid'] . "每" . static::$frequency[$_SESSION['levelid']]['time'] . "秒发一次消息,每条消息不得超过" . static::$frequency[$_SESSION['levelid']]['length'] . "字"; - if ($_SESSION['msged']) { - if ($time - $_SESSION['time'] < static::$frequency[$_SESSION['levelid']]['time']) { - return false; - } else if ($length > static::$frequency[$_SESSION['levelid']]['length']) { - return false; - } - $_SESSION['time'] = $time; - return true; - } else if ($length > static::$frequency[$_SESSION['levelid']]['length']) { - $_SESSION['msged'] = true; - return false; - } - $_SESSION['msged'] = true; - return true; - } - } - - // 判断房间是否满员 - public static function isRoomFull($room_id) - { - return false; - $status = RoomStatus::getRoomStatus($room_id); - var_dump($status); - return $status['maxonline'] == 0; - } - - // 获取房间在线在线人数 - public static function getClientNumByRoom($room_id) - { - $num = RoomStatus::getClientNum($room_id); - return !$num ? 0 : $num; - } - - public static function getSortedClientByRoom($room_id) - { - $sortedClient = RoomStatus::getSortedClient($room_id); - return is_null($sortedClient) ? array() : $sortedClient; - } - - public static function setAnchorOffLine($user_id) { - return ; - RoomStatus::updateAnchorOfflineToDb($user_id); - } - - public static function setAnchorOnlie($user_id) - { - RoomStatus::updateAnchorOnLineToDb($user_id); - } - - public static function getAvatar($uid) - { - - return "/style/avatar/".substr(md5($uid),0,3)."/{$uid}_small.jpg?t=".time(); - /* - $base = "/passport/avatar.php?uid={$ucuid}&size=small"; - $hash = self::getFileHash($ucuid); - return $hash ? $base . "&hash={$hash}" : $base; - */ - } - - /** - * 获取上传文件路径 - */ - public static function getUploadPath($uid) - { - $uid = abs(intval($uid)); - $uid = sprintf("%09d", $uid); - $dir1 = substr($uid, 0, 3); - $dir2 = substr($uid, 3, 2); - $dir3 = substr($uid, 5, 2); - return "/passport/data/avatar/".$dir1.'/'.$dir2.'/'.$dir3.'/'; - } - - public static function getFileHash($uid) - { - $path = Site::$host . self::getUploadPath($ucuid) . substr($ucuid, -2) . '_avatar_small.jpg'; - if (@fopen($path, 'r')) { - return hash_file('md5', $path); - } - return ''; - } - - /** - * 延迟关闭客户端连接,照顾低配置手机来不及响应问题 - * - * @param int $time - * @param string $client_id - */ - public static function delayCloseClient($time, $client_id) - { - \Workerman\Lib\Timer::add($time,function($client_id) { - Gateway::closeClient($client_id); - }, array($client_id), false); - } - - /** - * 发系统消息 - * - * @param $client_id - * @param string $lang 语言 - */ - public static function sendSysMsg($client_id = '', $lang = 'ch') - { - $Data = Db::instance('dbDefault')->query("select live_prompt from ss_siteconfig"); - $SysMsg = $Data[0]['live_prompt']; - if ($SysMsg == '') { - return ; - } - /* - if (AI::$SysMsg == '') { - return ; - } - - $message = array('type'=>'sysmsg', 'content'=>AI::$SysMsg);*/ - $SysMsg = !isset(AI::$SysMsgAther[$lang]) ? $SysMsg : AI::$SysMsgAther[$lang]; - $message = array('type'=>'sysmsg', 'content'=>$SysMsg); - if ($client_id == '') { - Gateway::sendToCurrentClient(json_encode($message)); - return ; - } - Gateway::sendToClient($client_id, json_encode($message)); - } - - public static function filter($content) - { - $keyWord = Db::instance('dbDefault')->query("select key_word from ss_keyword"); - $str = $content; - /*if (!empty(AI::$keyWord)) { - foreach (AI::$keyWord as $word) { - $content = str_replace($word, str_repeat("*", strlen($word)), $content); - } - }*/ - if (!empty($keyWord)) { - foreach ($keyWord as $word) { - $content = str_replace($word['key_word'], str_repeat("*", strlen($word['key_word'])), $content); - } - } - return $content; - } -} diff --git a/Application/Asset/AI.php b/Application/Asset/AI.php deleted file mode 100644 index db369d0..0000000 --- a/Application/Asset/AI.php +++ /dev/null @@ -1,39 +0,0 @@ -900, 'username'=>'AI_1','nickname'=>'机器人1号', 'ucuid'=>843, 'levelid'=>3,'vip'=>0,'AI'=>true), - // array('user_id'=>844, 'username'=>'AI_2','nickname'=>'机器人2号', 'ucuid'=>783, 'levelid'=>5,'vip'=>1,'AI'=>true), - array('user_id'=>868, 'username'=>'AI_3','nickname'=>'机器人3号', 'ucuid'=>807, 'levelid'=>16,'vip'=>0,'AI'=>true), - array('user_id'=>911, 'username'=>'AI_4','nickname'=>'机器人4号', 'ucuid'=>854, 'levelid'=>21,'vip'=>0,'AI'=>true), - array('user_id'=>788, 'username'=>'AI_5','nickname'=>'机器人5号', 'ucuid'=>911, 'levelid'=>4,'vip'=>2,'AI'=>true), - array('user_id'=>855, 'username'=>'AI_6','nickname'=>'机器人6号', 'ucuid'=>1077, 'levelid'=>24,'vip'=>0,'AI'=>true), - array('user_id'=>854, 'username'=>'AI_7','nickname'=>'机器人7号', 'ucuid'=>1033, 'levelid'=>2,'vip'=>0,'AI'=>true), - array('user_id'=>849, 'username'=>'AI_8','nickname'=>'机器人8号', 'ucuid'=>133, 'levelid'=>8,'vip'=>0,'AI'=>true), - // array('user_id'=>847, 'username'=>'AI_9','nickname'=>'机器人8号', 'ucuid'=>137, 'levelid'=>18,'vip'=>0,'AI'=>true), - // array('user_id'=>843, 'username'=>'AI_8','nickname'=>'机器人8号', 'ucuid'=>133, 'levelid'=>8,'vip'=>0,'AI'=>true), - ); - - /** - * 系统提示语【中文版】 - */ - public static $SysMsg = "系统提示:我们倡导绿色直播,封面及直播内容均不可包含抽烟、低俗、引诱、暴露等内容。如有发现将被封停账号,网警24小时在线巡查哦!"; - - /** - * 其他语言,系统提示语 - */ - public static $SysMsgAther = array( - 'en' => "System Tip: we advocate green video, cover and living content can not include smoking, vulgar, temptation, exposure and other content. If found will be closed. Police will watch for 24 hours...", - 'trad' => '系統提示:我們倡導綠色直播,封面及直播內容均不可包含抽煙、低俗、引誘、暴露等內容。如有發現將被封停賬號,網警24小時在線巡查哦!', - ); - - /** - * 关键字过滤 - */ - public static $keyWord = array( - "毛泽东","毛贼东","东泽毛","mzd","刘少奇","邓小平","平小邓","胡耀邦","耀邦","赵紫阳","江泽民","泽民","江贼","民泽江","胡锦涛","温家宝","习近平","江泽民" - ); -} \ No newline at end of file diff --git a/Application/Asset/AI.schema.php b/Application/Asset/AI.schema.php deleted file mode 100644 index cf61c65..0000000 --- a/Application/Asset/AI.schema.php +++ /dev/null @@ -1,17 +0,0 @@ -900, 'username'=>'AI_1','nickname'=>'机器人1号', 'ucuid'=>843, 'levelid'=>3,'vip'=>0,'AI'=>true), - array('user_id'=>844, 'username'=>'AI_2','nickname'=>'机器人2号', 'ucuid'=>783, 'levelid'=>5,'vip'=>1,'AI'=>true), - array('user_id'=>868, 'username'=>'AI_3','nickname'=>'机器人3号', 'ucuid'=>807, 'levelid'=>16,'vip'=>0,'AI'=>true), - array('user_id'=>911, 'username'=>'AI_4','nickname'=>'机器人4号', 'ucuid'=>854, 'levelid'=>21,'vip'=>0,'AI'=>true), - array('user_id'=>788, 'username'=>'AI_5','nickname'=>'机器人5号', 'ucuid'=>911, 'levelid'=>4,'vip'=>2,'AI'=>true), - ); - - public static $SysMsg = "#{meilibo.CHATROOM.SYSMSG}"; - -} \ No newline at end of file diff --git a/Application/Crontab.php b/Application/Crontab.php deleted file mode 100644 index 4297e42..0000000 --- a/Application/Crontab.php +++ /dev/null @@ -1,672 +0,0 @@ -query("select * from ss_member where is_robot=1"); - // //array('user_id'=>900, 'username'=>'AI_1','nickname'=>'机器人1号', 'ucuid'=>843, 'levelid'=>3,'vip'=>0,'AI'=>true), - // $AIUser = array(); - // $num = 0; - // foreach($AIArray as $key => $value) - // { - // $AIUser[$num]['user_id']=$value['id']; - // $AIUser[$num]['username']=$value['username']; - // $AIUser[$num]['nickname']=$value['nickname']; - // $AIUser[$num]['ucuid']=$value['ucuid']; - // $spendcoin=$value['spendcoin']; - // $levelid = Db::instance('dbDefault')->query("select levelid from ss_emceelevel where earnbean_low <=".$spendcoin." and earnbean_up >=".$spendcoin); - // $AIUser[$num]['levelid']=$levelid[0]['levelid']; - // $AIUser[$num]['vip']=$value['vip']; - // $AIUser[$num]['AI']=true; - // $num++; - // } - $UserSet = Db::instance('dbDefault')->query("select robot_max, robot_switch, robot_min,robot_change_min,robot_change_max from ss_siteconfig"); - static::$RobotMax = $UserSet[0]['robot_max']; - static::$RobotMin = $UserSet[0]['robot_min']; - static::$RobotChangeMin = $UserSet[0]['robot_change_min']; - static::$RobotChangeMax = $UserSet[0]['robot_change_max']; - static::$RobotOpen = $UserSet[0]['robot_switch']; - //static::$AIList = $AIUser; - - - if(count(static::$AIList) < static::$RobotMax) - { - static::$RobotMax = count(static::$AIList); - } - - if(count(static::$AIList) <= 0) - { - static::$RobotOpen = 0; - } - - if(static::$RobotMax <= 0) - { - static::$RobotOpen = 0; - } - - if(static::$RobotMin <= 0) - { - static::$RobotMin = 0; - } - } - - public static function getRandomAIFromDb($num) - { - //对机器人赋值 - //static::$AIList = AI::$AIUser; - $AIArray = Db::instance('dbDefault')->query("select * from ss_member where is_robot=1 and limit ".$num.",1"); - //array('user_id'=>900, 'username'=>'AI_1','nickname'=>'机器人1号', 'ucuid'=>843, 'levelid'=>3,'vip'=>0,'AI'=>true), - $AIUser = array(); - foreach($AIArray as $key => $value) - { - $AIUser['user_id']=$value['id']; - $AIUser['username']=$value['username']; - $AIUser['nickname']=$value['nickname']; - $AIUser['ucuid']=$value['ucuid']; - $spendcoin=$value['spendcoin']; - $levelid = Db::instance('dbDefault')->query("select levelid from ss_emceelevel where earnbean_low <=".$spendcoin." and earnbean_up >=".$spendcoin); - $AIUser['levelid']=$levelid[0]['levelid']; - $AIUser['vip']=$value['vip']; - $AIUser['AI']=true; - } - var_dump($AIUser); - return $AIUser; - } - - /** - * 获取随机AI用户 - * - * @return array - */ - public static function getRandomAI($room_id, $roomAI) - { - // 不要机器人 - if($roomAI == -1) - return array(); - - if (isset(static::$AIMap[$room_id]) && (time() - static::$AIMap[$room_id]['time']) < 8) { - return static::$AIMap[$room_id]['list']; - } - $AIUser = self::getRandomAIFromDb(0); - $tmpAI = array(); - $num = 1; - while(!empty($AIUser)) - { - if (isset($tmpAI[$AIUser['username']])) { - continue ; - } - - $tmpAI[$AIUser['username']] = $AIUser; - if(count($tmpAI) >= $roomAI) - { - break; - } - - if(count($tmpAI) >= static::$RobotMax) - { - break; - } - - $AIUser = self::getRandomAIFromDb($num); - $num++; - } - - // foreach(static::$AIList as $k=>$v) - // { - // if(count(static::$AIList) <= 0) - // { - // break; - // } - - // if(!$k) { - // continue; - // } - // $ai = $v; - // if (isset($tmpAI[$ai['username']])) { - // continue ; - // } - - // $tmpAI[$ai['username']] = $ai; - // if(count($tmpAI) >= $roomAI) - // { - // break; - // } - - // if(count($tmpAI) >= static::$RobotMax) - // { - // break; - // } - // } - //echo '1:'; - //var_dump(count($tmpAI)); - static::$AIMap[$room_id] = array('time'=>time(), 'list'=>$tmpAI); - return $tmpAI; - } - - public static function initAllRoom() - { - if (static::$cacheHotRoomFlag) { - arsort(static::$currentRoomList); - $tmp = count(static::$currentRoomList) <= 300 ? static::$currentRoomList : array_slice(static::$currentRoomList,0,300,true); - Mem::set(static::ROOM_SORTED_HOT_LIST, json_encode($tmp)); - } - Mem::set(static::ROOM_COUNT_ALL, count(static::$currentRoomList)); - - $onlineRooms = static::getAllOnLineRoom(); - /* - $allGroupInfo = \Gateway::getAllClientInfo(); - $tmp = array(); - foreach($allGroupInfo as $client_id => $status) { - if (empty($status)) { - continue ; - } - if (!isset($tmp[$status['room_id']])) { - $tmp[$status['room_id']] = array(); - } - $tmp[$status['room_id']][] = $status; - } - unset($allGroupInfo); - */ - // 删除不在直播房间的Timer - foreach (static::$allRoomTimer as $room_id => $timer) { - if (in_array($room_id,$onlineRooms)) { - continue ; - } - static::removeRoomTimer($room_id); - } - - $tmp = array(); - foreach ($onlineRooms as $room_id) { - $tmp[$room_id] = \Gateway::getClientInfoByGroup($room_id); - } - static::$currentRoomList = $group_info = array(); - foreach($tmp as $room_id => $group_client) { - static::$currentRoomList[$room_id] = 0; - if (count($group_client) == 0) { - self::removeRoomTimer($room_id); - continue; - } - if (isset(static::$allRoomTimer[$room_id])) { - $group_info[$room_id] = static::$allRoomTimer[$room_id]; - continue; - } - $group_info[$room_id] = \Workerman\Lib\Timer::add(2,array("\Application\Crontab","getClientList"),array($room_id),true); - } - - // if (!empty(static::$allRoomTimer)) { - // $roomOrignal = array_keys(static::$allRoomTimer); - // $roomNew = array_keys($group_info); - // $arrayDiff = array_diff($roomOrignal, $roomNew); - // foreach($arrayDiff as $room_id => $timer) { - // self::removeRoomTimer($room_id); - // } - // } - // unset($tmp); - static::$allRoomTimer = $group_info; - } - - public static function getAllOnLineRoom() - { - $group = RoomStatus::getOnlineRoom(); - $tmp = array(); - if ( !is_array($group) || empty($group)) { - return $tmp; - } - - foreach ($group as $room) { - if ($room['curroomnum'] <= 0) { - continue; - } - $tmp[] = $room['curroomnum']; - } - return $tmp; - } - - public static function removeRoomTimer($room_id) - { - if (!isset(static::$allRoomTimer[$room_id])) { - return ; - } - $Rebot_List = array(); - $list = json_decode(Mem::get(static::ROOM_ONLINE_PEPOLE_REBOT.$room_id),true); - $list_array = (array)$list; - $Rebot_List = $list_array['Rebot_List']; - Mem::set(static::ROOM_ONLINE_PEPOLE_REBOT.$room_id, json_encode(array('is_over'=>-1,'Rebot_List'=>$Rebot_List))); - \Workerman\Lib\Timer::del(static::$allRoomTimer[$room_id]); - //var_dump('exit'); - self::getClientList($room_id); - unset(static::$allRoomTimer[$room_id]); - //Mem::delete(self::ROOM_ONLINE_NUM_PREFIX.$room_id); - } - - public static function get_rand_ai($room_id, $roomAI,$Rebot_List) - { - // 不要机器人 - if($roomAI == -1) - return array(); - - if (isset(static::$AIMap[$room_id]) && (time() - static::$AIMap[$room_id]['time']) < 8) { - return static::$AIMap[$room_id]['list']; - } - - $AIUser = self::getRandomAIFromDb(0); - $tmpAI = array(); - $num = 1; - while(!empty($AIUser)) - { - $ai = $AIUser; - if (isset($tmpAI[$ai['username']])) { - continue ; - } - if (isset($Rebot_List[$ai['username']])) { - continue ; - } - $tmpAI[$ai['username']] = $ai; - if(count($tmpAI) >= $roomAI) - { - break; - } - - if(count($tmpAI) >= static::$RobotMax) - { - break; - } - $AIUser = self::getRandomAIFromDb($num); - $num++; - } - - // $tmpAI = array(); - // foreach(static::$AIList as $k=>$v) - // { - // if(count(static::$AIList) <= 0) - // { - // break; - // } - // if(!$k) { - // continue; - // } - // $ai = $v; - // if (isset($tmpAI[$ai['username']])) { - // continue ; - // } - // if (isset($Rebot_List[$ai['username']])) { - // continue ; - // } - // $tmpAI[$ai['username']] = $ai; - // if(count($tmpAI) >= $roomAI) - // { - // break; - // } - - // if(count($tmpAI) >= static::$RobotMax) - // { - // break; - // } - // } - - //echo '2:'; - //var_dump(count($tmpAI)); - static::$AIMap[$room_id] = array('time'=>time(), 'list'=>$tmpAI); - return $tmpAI; - } - - public static function get_ai_list($room_id,$room_info) - { - - var_dump('get_ai_list'); - self::initAI(); - if(!static::$RobotOpen) - { - var_dump('RobotOpen'); - Mem::set(static::ROOM_ONLINE_PEPOLE_REBOT.$room_id, json_encode(array('is_over'=>1,'Rebot_List'=>array()))); - return array(); - } - //默认配置 现在设置第一次初始化添加2个机器人 - $InitRebot = mt_rand(static::$RobotMin-1,static::$RobotMax-1); - var_dump($InitRebot); - //默认1:10 - if(static::$RobotChangeMax <= 0) - { - $Ratio = -1; - } - else{ - $Ratio = mt_rand(static::$RobotChangeMin-1,static::$RobotChangeMax-1); - - } - - // var_dump($Ratio); - //此处添加 - //将上次人数保存 - $room_people_num = count((array)$room_info); - $roomAI_list=array(); - if(!Mem::get(static::ROOM_ONLINE_PEPOLE_REBOT.$room_id)) - { - $roomAI = $InitRebot; - $roomAI_list = self::getRandomAI($room_id,$roomAI); - } - else - { - $list = json_decode(Mem::get(static::ROOM_ONLINE_PEPOLE_REBOT.$room_id),true); - $list_array = (array)$list; - if(empty($list_array)) - { - $roomAI = $InitRebot; - $roomAI_list = self::getRandomAI($room_id,$roomAI); - } - else - { - $is_over = $list_array['is_over']; - $Rebot_List = $list_array['Rebot_List']; - if($is_over == -1) - { - echo " is_over"; - $roomAI = $InitRebot; - $roomAI_list = self::getRandomAI($room_id,$roomAI); - } - else - { - echo " Ratio"; - $roomAI = $Ratio; - $roomAI_list_new = self::get_rand_ai($room_id,$roomAI,$Rebot_List); - - foreach($roomAI_list_new as $k=>$v) - { - $Rebot_List[$k] = $v; - } - $roomAI_list = $Rebot_List; - $room_people_num =$room_people_num + $roomAI; - } - - } - } - //var_dump(count($roomAI_list)); - Mem::set(static::ROOM_ONLINE_PEPOLE_REBOT.$room_id, json_encode(array('is_over'=>1,'Rebot_List'=>$roomAI_list))); - //echo "roomAI_list"; - //此处结束 - return $roomAI_list; - } - - public static function getClientList($room_id) - { - $room_info = \Gateway::getClientInfoByGroup($room_id); - //var_dump($room_info); - //$roomAI = self::get_ai_list($room_id,$room_info); - $list = json_decode(Mem::get(static::ROOM_ONLINE_PEPOLE_REBOT.$room_id),true); - //var_dump($list); - $list_array = (array)$list; - $Rebot_List=array(); - $is_over = -1; - $is_over = $list_array['is_over']; - $Rebot_List = $list_array['Rebot_List']; - if($is_over == -1) - { - //$roomAI = $Rebot_List; - if(count($room_info)!=0) - { - //$room_info = array_diff($room_info, $Rebot_List); - $room_info = array(); - } - //$room_info = array_diff($room_info, $Rebot_List); - }else - { - $roomAI = $Rebot_List; - $room_info = array_merge($room_info, $roomAI); - } - - //var_dump(count($room_info)); - // TODO 按规则排序,vip/等级 同时保留用户状态信息,便于前端显示 - $adminer_list = array(); - $client_list = array(); - foreach ($room_info as $client_id => $session) { - if (empty($session)) { - continue; - } - $session['avatar'] = AdminClient::getAvatar($session['user_id']); - if (isset($session['role'])) { - if (strcmp($session['role'], 'owner') === 0) { - continue; - } - $adminer_list[] = $session; - } else { - $client_list[] = $session; - } - } - - $viewer_num = 0; - $adminer_list = self::sortClient($adminer_list, true, $viewer_num); - $client_list = self::sortClient($client_list, false, $viewer_num); - $all_num = count($adminer_list) + count($client_list) + $viewer_num; - - $all_num = 50 + $all_num; - // if (Mem::get(self::ROOM_ANCHOR_ONLIE_PREFIX . $room_id) == 'online') { - static::$currentRoomList[$room_id] = $all_num; - // } - #$all_num = $all_num + 100; - RoomStatus::updateOnlineNumToDb($room_id, $all_num); - // $status_num_json = json_encode(array('all_num'=>$all_num, 'viewer_num'=>$viewer_num)); - // $status_client_list_json = json_encode(array('adminer_list'=>$adminer_list, 'client_list'=>$client_list)); - - // if ($status_num != Mem::get(static::ROOM_ONLINE_NUM_PREFIX . $room_id) && $status_client_list != Mem::get(static::ROOM_SORTED_CLIENTS_PREFIX . $room_id)) { - // 在线用户已改变,广播至客户端,并写入缓存 - self::BroadCast($room_id, $all_num, $viewer_num, $adminer_list, $client_list); - // } - return ; - } - - public static function sendOnLineList($room_id, $session) - { - //$num = json_decode(Mem::get(static::ROOM_ONLINE_NUM_PREFIX . $room_id), true); - // if (isset($session['role']) && strcmp($session['role'], 'owner') === 0) { - // Crontab::initAI(); - // Crontab::getClientList($room_id); - // return ; - // } - //echo 'sendOnLineList '; - $list = json_decode(Mem::get(static::ROOM_SORTED_CLIENTS_PREFIX . $room_id), true); - - //$list=NULL; - //var_dump($list); - unset($session['msged']); - unset($session['time']); - $session['avatar'] = AdminClient::getAvatar($session['user_id']); - - $viewer_num = 0; - $adminer_list = !$list ? array() : $list['adminer_list']; - $client_list = !$list ? array() : $list['client_list']; - - $AIList = self::get_ai_list($room_id, array_merge($adminer_list, $client_list)); - - $client_list = array_merge($client_list, $AIList); - if (isset($session['role'])) { - if ( strcmp($session['role'], 'owner') !== 0 && !self::inOnLineList($session['user_id'], $adminer_list)) { - $adminer_list[] = $session; - $useless = 0; - $adminer_list = self::sortClient($adminer_list, true, $useless); - } - } else if (!self::inOnLineList($session['user_id'], $client_list)) { - $client_list[] = $session; - $client_list = self::sortClient($client_list, false, $viewer_num); - } - - $message = array( - 'type' => 'onLineClient', - 'all_num' => count($adminer_list) + count($client_list) + $viewer_num, - 'viewer_num' => $viewer_num, - 'adminer_list' => $adminer_list, - 'client_list' => $client_list, - ); - $message['all_num'] =50 + $message['all_num']; - echo "room_id:".$room_id." client_list:"; - var_dump(count($client_list)); - \Gateway::sendToClient($session['client_id'],json_encode($message)); - return ; - /* - if (!$num || !$list || $num['all_num'] == 0) { - if (isset($session['role'])) { - if (strcmp($session['role'],'owner') !== 0) { - $message['all_num'] = 1; - $message['adminer_list'][0] = $session; - } - } else { - $message['all_num'] = 1; - $message['viewer_num'] = $session['user_id'] == -1 ? 1 : 0; - $message['client_list'][0] = $session; - } - \Gateway::sendToGroup($room_id, json_encode($message)); - return ; - } - $message['all_num'] = $num['all_num']; - $message['viewer_num'] = $num['viewer_num']; - $message['adminer_list'] = $list['adminer_list']; - $message['client_list'] = $list['client_list']; - */ - } - - public static function inOnLineList($user_id, $user_info) - { - foreach ($user_info as $key => $session) { - if ($session['user_id'] == $user_id) { - return true; - } - } - return false; - } - - public static function BroadCast($room_id, $all_num, $viewer_num,$adminer_list, $client_list) - { - $message = array( - 'type'=>'onLineClient', - 'all_num'=>$all_num, - 'viewer_num'=>$viewer_num, - 'adminer_list'=>$adminer_list, - 'client_list'=>$client_list, - ); - \Gateway::sendToGroup($room_id, json_encode($message)); - Mem::set(static::ROOM_ONLINE_NUM_PREFIX . $room_id, json_encode(array('all_num'=>$all_num,'viewer_num'=>$viewer_num))); - Mem::set(static::ROOM_SORTED_CLIENTS_PREFIX . $room_id, json_encode(array('adminer_list'=>$adminer_list,'client_list'=>$client_list))); - } - public static function sortClient($user_info, $adminer = false , &$viewer_num) - { - $room_owner = null; - $vip1_tmp = $vip2_tmp = $vip0_tmp = array(); - $hasLoginUser = array(); - foreach($user_info as $index => $session) { - if ($adminer && strcmp($session['role'],'owner') == 0) { - // $room_owner = $session; - continue ; - } - if (!$adminer && $session['user_id'] == -1 && (!isset($session['AI']) || !$session['AI'])) { - $viewer_num++; - continue ; - } - if (in_array($session['user_id'],$hasLoginUser)) { - // 在线列表踢出重复登录用户 - continue; - } - unset($session['time']); - unset($session['msged']); - switch ((int)$session['vip']) { - case 1: - if (!isset($vip1_tmp[$session['levelid']])) { - $vip1_tmp[$session['levelid']] = array(); - } - $vip1_tmp[$session['levelid']][] = $session; - break; - case 2: - if (!isset($vip2_tmp[$session['levelid']])) { - $vip2_tmp[$session['levelid']] = array(); - } - $vip2_tmp[$session['levelid']][] = $session; - break; - case 0: - if (!isset($vip0_tmp[$session['levelid']])) { - $vip0_tmp[$session['levelid']] = array(); - } - $vip0_tmp[$session['levelid']][] = $session; - default: - // do nothing - } - $hasLoginUser[] = $session['user_id']; - } - - unset($hasLoginUser); - krsort($vip1_tmp); - krsort($vip2_tmp); - krsort($vip0_tmp); - $vip1_list = $vip2_list = $vip0_list = array(); - foreach($vip1_tmp as $levelid => $list) { - $vip1_list = array_merge($vip1_list, $list); - } - foreach ($vip2_tmp as $levelid => $list) { - $vip2_list = array_merge($vip2_list, $list); - } - foreach($vip0_tmp as $levelid => $list) { - $vip0_list = array_merge($vip0_list, $list); - } - - $all_client_list = $room_owner != null ? array_merge(array($room_owner), array_merge($vip1_list, array_merge($vip2_list, $vip0_list))) : array_merge($vip1_list, array_merge($vip2_list, $vip0_list)); - return count($all_client_list) <= 200 ? $all_client_list : array_slice($all_client_list, 0, 200, true); - } -} diff --git a/Application/Events.php b/Application/Events.php deleted file mode 100644 index 549d3f3..0000000 --- a/Application/Events.php +++ /dev/null @@ -1,463 +0,0 @@ - - * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ - -/** -*可能存在的问题 -* sendToClient 可能发送给不是当前房间的用户 -*/ -/** - * 聊天主逻辑 - * 主要是处理 onMessage onClose - */ -use \GatewayWorker\Lib\Gateway; -use \GatewayWorker\Lib\Store; -use \GatewayWorker\Lib\Memcache; -use \Application\AdminClient; -use \Application\Crontab; - -class Events - -{ - /** - * 有消息时 - * @param int $client_id - * @param string $message - */ - public static function onMessage($client_id, $message) - { - // debug - // echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']} client_id:$client_id session:".json_encode($_SESSION)." onMessage:".$message."\n"; - - // 客户端传递的是json数据 - $message_data = json_decode($message, true); - if(!$message_data) - { - return ; - } - - if (empty($_SESSION) && strcmp($message_data['_method_'], 'login') !== 0) { - return ; - } - //判断是否有登录。 - if (strcmp($message_data['_method_'], 'login') !== 0) { - if ($_SESSION['user_id'] == -1 && in_array($message_data['_method_'], array('SendPubMsg','SendPrvMsg','sendGift','Manage'))) { - Gateway::sendToCurrentClient(json_encode(array('type'=>'sysmsg.alert','content'=>'请登录!'))); - return ; - } - // 查看当前用户权限是否修改 - $role = isset($_SESSION['role']) ? $_SESSION['role'] : null; - $action = AdminClient::checkUserRoleChanged($_SESSION['user_id'], $_SESSION['room_id'], $role); - if (!is_null($action)) { - if (in_array($action, array('addSysAdminer','removeSysAdminer'))) { - AdminClient::$action($_SESSION['room_id'], $_SESSION['user_id']); - } else if (in_array($action, array('adminer','removeAdminer'))) { - AdminClient::$action($_SESSION['room_id'], $_SESSION['user_id'], $client_id, $_SESSION['client_name'], true, false); - } - } - } - - - // 根据类型执行不同的业务 - switch($message_data['_method_']) - { - // 客户端回应服务端的心跳,代表在线。 - case 'pong': - if (isset($_SESSION['room_id']) && isset($_SESSION['role']) && strcmp($_SESSION['role'], 'owner') === 0) { //isset($message_data['device']) && strcmp($message_data['device'], 'android') - Crontab::setAnchorOnline($_SESSION['room_id'], $_SESSION['user_id']); - } - return; - // 客户端登录 message格式: {_method_ :login, name:xx, room_id:1} ,添加到客户端,广播给所有客户端xx进入聊天室 - case 'logout': - // 从房间的客户端列表中删除 - if(isset($_SESSION['room_id'])) - { - $room_id = $_SESSION['room_id']; - $new_message = array('type'=>'logout', 'from_client_id'=>$client_id, 'user_id'=>$_SESSION['user_id'], 'from_client_name'=>$_SESSION['client_name'], 'time'=>date('Y-m-d H:i:s')); - if (isset($_SESSION['role']) && strcmp($_SESSION['role'], 'owner') === 0) { - $new_message['role'] = 'owner'; - - } - - Gateway::unbindUid($client_id, $_SESSION['user_id']); //解除与uid的绑定。 - Gateway::leaveGroup($client_id, $room_id); //离开当前的用户住,代表当前房间 - Gateway::sendToGroup($room_id, json_encode($new_message)); //客户端断开连接需要执行此操作。 - $_SESSION = array(); - } - return ; - case 'login': - // 判断是否有房间号 - if(!isset($message_data['room_id'])) - { - return; - } - $viewer = false; - if (!isset($message_data['user_name']) || !isset($message_data['user_id']) || $message_data['user_id'] <= 0 || $message_data['user_name'] == "") { - $viewer = true; - $message_data['user_name'] = '游客'.rand(10000,99999); - $message_data['user_id'] = -1; - $message_data['levelid'] = 0; - $message_data['ucuid'] = -1; - $message_data['vip'] = 0; - } - $client_name = htmlspecialchars($message_data['user_name']); - $room_id = $message_data['room_id']; - $user_id = $message_data['user_id']; - - if (!$viewer) { - if (!AdminClient::isLogged($user_id, $message_data['token'])) { - // close this connection - Gateway::sendToCurrentClient(json_encode(array('type'=>'error' , 'content'=>'请先登录'))); - Gateway::closeClient($client_id); - return; - } - } - - $vip = $viewer ? 0 : AdminClient::hasVipPrivilete($user_id); - - if ( $vip == 0 && AdminClient::isRoomFull($room_id)) { - Gateway::sendToCurrentClient(json_encode(array('type'=>'error.kicked','content'=>"非VIP用户不能进入满员房间~"))); - // 延迟关闭连接 - AdminClient::delayCloseClient(5,$client_id); - // Gateway::closeClient($client_id); - return; - } - - $expire = 0; - $role = $viewer ? '' : AdminClient::getClientRole($room_id, $user_id, $expire); - if (!$vip &&strcmp($role, 'kicked') === 0 && $expire > time()) { - - //TODO 关闭连接 已被踢出房间 - $left = floor(($expire - time()) / 60); - Gateway::sendToCurrentClient(json_encode(array('type'=>'error.kicked','content'=>"您已被踢出房间, {$left}分钟后再进入房间"))); - // 延迟关闭连接 - AdminClient::delayCloseClient(5,$client_id); - // Gateway::closeClient($client_id); - return; - } - // 把房间号昵称放到session中 - $isAdminer = false; - if (!is_null($role) && (strcmp($role, 'adminer') === 0 || strcmp($role, 'owner') === 0) || strcmp($role, 'sysAdminer') === 0) { - $_SESSION['role'] = $role; - if (strcmp($role, 'owner') === 0) { - AdminClient::setAnchorOnlie($user_id); - } - $isAdminer = true; - } else if (!$vip && !is_null($role) && strcmp($role, 'disableMsg') === 0) { - $_SESSION['disableMsg'] = 1; - $_SESSION['expire'] = $expire; - } - - $ucuid = $message_data['ucuid']; - $_SESSION['client_name'] = $client_name; - $_SESSION['user_id'] = $user_id; - $_SESSION['room_id'] = $room_id; - $_SESSION['ucuid'] = $ucuid; - $_SESSION['client_id'] = $client_id; - $_SESSION['vip'] = $vip; - $_SESSION['levelid'] = $message_data['levelid']; - $_SESSION['time'] = 0; - $_SESSION['msged'] = false; - - - $new_message = array('type'=>$message_data['_method_'], 'client_id'=>$client_id, 'client_name'=>htmlspecialchars($client_name), 'user_id'=>$user_id, 'ucuid'=>$ucuid,'vip'=>$vip,'levelid'=>$_SESSION['levelid'], 'time'=>date('H:i')); - $new_message['levelid'] = $message_data['levelid']; - if ($isAdminer) { - $new_message['role'] = 'adminer'; - } - if (isset($message_data['daoju'])) { - $new_message['daoju'] = $message_data['daoju']; - } - - // if ((strcmp($role, 'owner') !== 0)) { - // Gateway::sendToGroup($room_id, json_encode($new_message)); - // } - Gateway::joinGroup($client_id, $room_id); - Gateway::bindUid($client_id, $user_id); - AdminClient::sendSysMsg($client_id, !isset($message_data['lang']) ? 'ch' : $message_data['lang']); - - print_r($_SESSION); - // For APP - Crontab::sendOnLineList($room_id, $_SESSION); - print_r($new_message) ; - // For PC - Gateway::sendToCurrentClient(json_encode($new_message)); - // Gateway::sendToGroup($room_id, json_encode($new_message)); - return; - - // 客户端发言 message: {_method_:SendPubMsg, to_client_id:xx, content:xx} - case 'LightHeart': - if(!isset($_SESSION['room_id'])) - { - return; - } - $new_message = array( - 'type'=>'LightHeart', - 'color'=> isset($message_data['color']) ? $message_data['color'] : 'red', - 'client_id'=>$client_id, - 'user_id'=>$_SESSION['user_id'], - 'client_name'=>$_SESSION['client_name'], - 'levelid'=>$_SESSION['levelid'], - 'vip'=>$_SESSION['vip'], - 'time'=>date('H:i'), - ); - - return Gateway::sendToGroup($_SESSION['room_id'], json_encode($new_message)); - case 'SendPubMsg': - // 非法请求 - if(!isset($_SESSION['room_id'])) - { - return; - } - if (trim($message_data['content']) == "") { - Gateway::sendToClient($client_id, json_encode(array("type"=>"error","content"=>"您不能发送空内容"))); - return ; - } - // 是否可以发言 - if (!AdminClient::isEnableMsg()) { - Gateway::sendToCurrentClient(json_encode(array("type"=>"error","content"=>"您已被管理员禁言"))); - return ; - } - $msg = ''; - if (!AdminClient::msgFrequency(strlen($message_data['content']), $msg)) { - Gateway::sendToCurrentClient(json_encode(array("type"=>"error","content"=>$msg))); - return ; - } - $room_id = $_SESSION['room_id']; - $client_name = $_SESSION['client_name']; - - - $new_message = array( - 'type'=>'SendPubMsg', - 'from_user_id'=>$_SESSION['user_id'], - 'from_client_name' =>$client_name, - 'vip'=>$_SESSION['vip'], - 'levelid'=>$_SESSION['levelid'], - 'avatar'=>AdminClient::getAvatar($_SESSION['user_id']), - // 'to_client_id'=>'all', - 'content'=>nl2br(htmlspecialchars(AdminClient::filter($message_data['content']))), - 'time'=>date('H:i'), - ); - // 飞屏特效 - $new_message['fly'] = isset($message_data['fly']) ? $message_data['fly'] : ''; - - return Gateway::sendToGroup($room_id ,json_encode($new_message)); - case 'SendPrvMsg': - // 非法请求 - if(!isset($_SESSION['room_id'])) - { - return; - } - if (trim($message_data['content']) == "") { - Gateway::sendToClient($client_id, json_encode(array("type"=>"error","content"=>"您不能发送空内容"))); - return ; - } - // 是否可以发言 - if (!AdminClient::isEnableMsg()) { - Gateway::sendToClient($client_id, json_encode(array("type"=>"error","content"=>"您已被管理员禁言"))); - return ; - } - if (!AdminClient::ablePriMsg()){ - Gateway::sendToClient($client_id, json_encode(array("type"=>"error","content"=>"富豪等级3以下不能发私信,快快升级吧"))); - return ; - } - $msg = ''; - if (!AdminClient::msgFrequency(strlen($message_data['content']), $msg)) { - Gateway::sendToCurrentClient(json_encode(array("type"=>"error","content"=>$msg))); - return ; - } - - $room_id = $_SESSION['room_id']; - $client_name = $_SESSION['client_name']; - - // 私聊 - $new_message = array( - 'type'=>'SendPrvMsg', - 'from_user_id'=>$_SESSION['user_id'], - 'from_client_name' =>$client_name, - 'vip'=>$_SESSION['vip'], - 'levelid'=>$_SESSION['levelid'], - 'avatar'=> AdminClient::getAvatar($_SESSION['user_id']), - 'to_client_name'=>$message_data['to_client_name'], - 'to_user_id'=>isset($message_data['to_user_id']) ? $message_data['to_user_id'] : 0, - 'pub'=>$message_data['pub'], - 'content'=>nl2br(htmlspecialchars(AdminClient::filter($message_data['content']))), - 'time'=>date('H:i'), - ); - // 飞屏特效 - // $new_message['fly'] = isset($message_data['fly']) ? $message_data['fly'] : ''; - - //可公开的私聊 - if ($message_data['pub']) { - return Gateway::sendToGroup($room_id ,json_encode($new_message)); - } else { - //私密聊天,不公开 - Gateway::sendToClient($message_data['to_client_id'], json_encode($new_message)); - // $new_message['content'] = nl2br(htmlspecialchars($message_data['content'])); - return Gateway::sendToCurrentClient(json_encode($new_message)); - } - case 'vodSong': - if (!isset($message_data['songName'])) { - Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'请填写歌曲!'))); - return ; - } - if ($_SESSION['user_id'] == -1) { - Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'游客不能点歌!'))); - return ; - } - $new_message = array('type'=>'vodSong'); - return Gateway::sendToGroup($_SESSION['room_id'] ,json_encode($new_message)); - case 'setBackground': - case 'cancelBackground': - $error = ""; - $new_message = array(); - if (!isset($_SESSION['role']) || !in_array($_SESSION['role'],array('owner','sysAdminer'))) { - $error = "您不是房主或系统管理员"; - } - if ( strcmp($message_data['_method_'],'setBackground') == 0 && (!isset($message_data['bgimg']) || $message_data['bgimg'] == "")) { - $error = "参数错误,请稍后尝试..."; - } - if ($error != "") { - return Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>$error))); - } - return Gateway::sendToGroup($_SESSION['room_id'], json_encode(array('type'=>$message_data['_method_'],'bgimg'=>$message_data['bgimg']))); - case 'setSongApply': - if (!isset($_SESSION['role']) || strcmp($_SESSION['role'],'owner') != 0) { - return Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'您不是房主哦!'))); - } - if (!isset($message_data['apply'])) { - return Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'参数错误'))); - } - return Gateway::sendToGroup($_SESSION['room_id'],json_encode(array('type'=>'setSongApply','apply'=>$message_data['apply']))); - case 'disAgreeSong': - case 'agreeSong': - if (!isset($_SESSION['role']) || strcmp($_SESSION['role'], 'owner') !== 0) { - // 当前用户不在该房间 - Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'您不是房主哦!'))); - return ; - } - $new_message = array('type'=>$message_data['_method_']); - if ($message_data['_method_'] == 'agreeSong') { - $new_message['client_name'] = $message_data['userName']; - $new_message['songName'] = $message_data['songName']; - } - return Gateway::sendToGroup($_SESSION['room_id'],json_encode($new_message)); - case 'sendGift': - // 此接口已废弃 - // Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'此接口已废弃'))); - // return ; - - // 非法请求 - if(!isset($_SESSION['room_id'])) - { - return; - } - $room_id = $_SESSION['room_id']; - $client_name = $_SESSION['client_name']; - - // 防止别人冒名发消息 - if (strcmp($client_name, $message_data['userName']) !== 0) { - Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'不能冒名发送礼物'))); - return ; - } - - unset($message_data['_method_']); - unset($message_data['userName']); - $message_data['from_client_name'] = $client_name; - $message_data['type'] = 'sendGift'; - $message_data['code'] = 0; - $message_data['time'] = date('H:i'); - $new_message = $message_data; - $new_message['from_client_id'] = $client_id; - $new_message['from_user_id'] = $_SESSION['user_id']; - $new_message['vip'] = $_SESSION['vip']; - $new_message['levelid'] = $_SESSION['levelid']; - - return Gateway::sendToGroup($room_id ,json_encode($new_message)); - case 'Manage': - // 非法请求 - if(!isset($_SESSION['room_id'])) - { - return; - } - // 是否有管理员权限 - if (!isset($_SESSION['role']) || !in_array($_SESSION['role'], array('adminer','owner','sysAdminer'))) { - Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'您没有管理员权限'))); - return; - } - - $room_id = $_SESSION['room_id']; - $client_name = $_SESSION['client_name']; - - $managed_user_id = $message_data['managed_user_id']; - // $managed_client_id = $message_data['managed_client_id']; - // $uidToClientArray = Gateway::getClientIdByUid($managed_user_id); - // $managed_client_id = array_shift($uidToClientArray); - $managed_client_id_array = Gateway::getClientIdByUid($managed_user_id); - $managed_user_name = $message_data['managed_user_name']; - $type = $message_data['_type_']; - if ( $managed_user_id == -1 && in_array($type, array('adminer','removeAdminer'))) { - Gateway::sendToCurrentClient(json_encode(array('type'=>'sysmsg.alert','content'=>'无法对游客做此操作!'))); - return ; - } - - // if (!Gateway::isUidOnline($managed_user_id)) { - // // 当前用户不在该房间 - // Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'当前用户不在该房间'))); - // return ; - // } - - if (in_array($type, array('adminer','removeAdminer','addKicked','removeKicked','disableMsg','enableMsg'))) { - if ( $managed_user_id == -1 && in_array($type, array(array('adminer','removeAdminer')))) { - Gateway::sendToCurrentClient(json_encode(array('type'=>'sysmsg.alert','content'=>'无法对游客做此操作!'))); - return ; - } - // 查看VIP状态 - if (in_array($type, array('addKicked','disableMsg')) && AdminClient::hasVipPrivilete($managed_user_id)) { - Gateway::sendToCurrentClient(json_encode(array('type'=>'sysmsg.alert','content'=>'该用户为 VIP 会员,操作失败!'))); - return ; - } - if (!AdminClient::ableToManage($managed_user_id, $room_id)) { - Gateway::sendToCurrentClient(json_encode(array('type'=>'error','content'=>'无法操作管理员'))); - return; - } - Gateway::sendToCurrentClient(json_encode(array('type'=>'sysmsg.alert','content'=>'操作成功!'))); - AdminClient::$type($room_id, $managed_user_id, $managed_client_id_array, $managed_user_name); - } - } - } - - /** - * 当客户端断开连接时 - * @param integer $client_id 客户端id - */ - public static function onClose($client_id) - { - // debug - // echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']} client_id:$client_id onClose:''\n"; - - // 从房间的客户端列表中删除 - if(isset($_SESSION['room_id'])) - { - /* - if (isset($_SESSION['role']) && strcmp($_SESSION['role'], 'owner') === 0) { - Crontab::delAnchorOnline($_SESSION['room_id']); - AdminClient::setAnchorOffLine($_SESSION['user_id']); - } - */ - $room_id = $_SESSION['room_id']; - $new_message = array('type'=>'logout', 'from_client_id'=>$client_id, 'user_id'=>$_SESSION['user_id'], 'from_client_name'=>$_SESSION['client_name'], 'time'=>date('Y-m-d H:i:s')); - Gateway::sendToGroup($room_id, json_encode($new_message)); - } - } -} diff --git a/Application/GatewayClient b/Application/GatewayClient deleted file mode 160000 index a8a24a0..0000000 --- a/Application/GatewayClient +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a8a24a0f0f5e0fcd4a8325d3960056c9b0b31ed3 diff --git a/Application/RoomStatus.php b/Application/RoomStatus.php deleted file mode 100644 index 2ef9379..0000000 --- a/Application/RoomStatus.php +++ /dev/null @@ -1,320 +0,0 @@ -query(static::INIT_SYS_ADMINER_SQL); - foreach ($status as $uid) { - $memToSysAdminer[$uid['id']] = $uid['id']; - } - self::setSysAdminer($memToSysAdminer); - - //初始化房间所有者 - $status = Db::instance('dbDefault')->query(static::INIT_ROOM_OWNMER_SQL); - foreach ($status as $value) { - if(!isset($memToRoomStatus[$value['num']])) { - $memToRoomStatus[$value['num']] = array(); - } - $memToRoomStatus[$value['num']]['owner'] = $value['uid']; - $memToRoomStatus[$value['num']]['adminer'] = array(); - $memToRoomStatus[$value['num']]['disableMsg'] = array(); - $memToRoomStatus[$value['num']]['kicked'] = array(); - $memToRoomStatus[$value['num']]['maxonline'] = $value['maxonline']; - } - - //初始化管理员 - $status = array(); - $status = Db::instance('dbDefault')->query(static::INIT_ROOM_ADMINER_SQL); - foreach ($status as $value) { - if (!isset($memToRoomStatus[$value['num']])) { - continue; - } - $memToRoomStatus[$value['num']]['adminer'][$value['adminuid']] = $value['adminuid']; - } - - Db::close('dbDefault'); - - foreach ($memToRoomStatus as $room_id => $roomStatus) { - self::setRoomStatus($room_id, $roomStatus); - } - } - - // 获取房间在在线人数 - public static function getClientNum($room_id) - { - return Mem::get(static::ROOM_ONLINE_NUM_PREFIX.$room_id); - } - - // 获取房间在线列表 - public static function getSortedClient($room_id) - { - return json_decode(Mem::get(static::ROOM_SORTED_CLIENTS_PREFIX.$room_id), true); - } - - public static function updateAnchorOfflineToDb($user_id) { - return ; - // Db::instance('dbDefault')->update('ss_member')->set('broadcasting','n')->where(array('id'=>$user_id))->execute(); - Db::instance('dbDefault')->query("update ss_member set broadcasting='n' where id={$user_id}"); - } - - public static function updateAnchorOnLineToDb($user_id) - { - Db::instance('dbDefault')->query("update ss_member set broadcasting='y' where id={$user_id}"); - } - - public static function getOnlineRoom() - { - return Db::instance('dbDefault')->query(static::GET_ONLINE_ANCHOR_LIST); - } - - /** - * 更新在线人数 - * - * @param int $num - */ - public static function updateOnlineNumToDb($room_id, $num = 0) - { - return Db::instance('dbDefault')->query("update ss_member set onlinenum={$num} where curroomnum={$room_id}"); - } -} \ No newline at end of file diff --git a/Application/start_businessWorker.php b/Application/start_businessWorker.php deleted file mode 100644 index 0917030..0000000 --- a/Application/start_businessWorker.php +++ /dev/null @@ -1,33 +0,0 @@ -name = 'ChatBusinessWorker'; -// bussinessWorker进程数量 -$worker->count = 4; -// 服务注册地址 -$worker->registerAddress = '127.0.0.1:1236'; - -//启动时初始化Mem -$worker->onWorkerStart = function() { - \Application\RoomStatus::init(); - // 定时任务 - \Workerman\Lib\Timer::add(10, function() { - \Application\RoomStatus::reloadChangedStatus(); - },array(),true); -}; -// 如果不是在根目录启动,则运行runAll方法 -if(!defined('GLOBAL_START')) -{ - Worker::runAll(); -} diff --git a/Application/start_crontab.php b/Application/start_crontab.php deleted file mode 100644 index 625c821..0000000 --- a/Application/start_crontab.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -use \Workerman\Worker; -use \Workerman\Autoloader; -use \Application\Crontab; - -// 自动加载类 -require_once __DIR__ . '/../Workerman/Autoloader.php'; - -// worker 进程 -$worker_cron = new worker("Websocket://0.0.0.0:4545"); -// 设置名称,方便status时查看 -$worker_cron->name = 'Crontabworker'; -// 设置进程数,worker进程数建议与cpu核数相同 -$worker_cron->count = 1; - -$worker_cron->onWorkerStart = function() { - Crontab::$cacheHotRoomFlag = true; - Crontab::initAI(); - \Workerman\Lib\Timer::add(3,function() { - Crontab::initAllRoom(); - },array(),true); - \Workerman\Lib\Timer::add(10,function() { - Crontab::initAI(); - },array(),true); -}; -// 如果不是在根目录启动,则运行runAll方法 -if(!defined('GLOBAL_START')) -{ - Worker::runAll(); -} diff --git a/Application/start_gateway.php b/Application/start_gateway.php deleted file mode 100644 index a19fb24..0000000 --- a/Application/start_gateway.php +++ /dev/null @@ -1,51 +0,0 @@ -name = 'ChatGateway'; -// 设置进程数,gateway进程数建议与cpu核数相同 -$gateway->count = 4; -// 分布式部署时请设置成内网ip(非127.0.0.1) -$gateway->lanIp = '10.27.184.251'; -// 内部通讯起始端口,假如$gateway->count=4,起始端口为4000 -// 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口 -$gateway->startPort = 2300; -// 心跳间隔 -$gateway->pingInterval = 15; -// 心跳数据 -$gateway->pingData = '{"type":"ping"}'; -// 服务注册地址 -$gateway->registerAddress = '127.0.0.1:1236'; - -/* -// 当客户端连接上来时,设置连接的onWebSocketConnect,即在websocket握手时的回调 -$gateway->onConnect = function($connection) -{ - $connection->onWebSocketConnect = function($connection , $http_header) - { - // 可以在这里判断连接来源是否合法,不合法就关掉连接 - // $_SERVER['HTTP_ORIGIN']标识来自哪个站点的页面发起的websocket链接 - if($_SERVER['HTTP_ORIGIN'] != 'http://chat.workerman.net') - { - $connection->close(); - } - // onWebSocketConnect 里面$_GET $_SERVER是可用的 - // var_dump($_GET, $_SERVER); - }; -}; -*/ - -// 如果不是在根目录启动,则运行runAll方法 -if(!defined('GLOBAL_START')) -{ - Worker::runAll(); -} - diff --git a/Application/start_gateway_text.php b/Application/start_gateway_text.php deleted file mode 100644 index c126f4e..0000000 --- a/Application/start_gateway_text.php +++ /dev/null @@ -1,51 +0,0 @@ -name = 'ChatGatewayText'; -// 设置进程数,gateway进程数建议与cpu核数相同 -$gateway_text->count = 4; -// 分布式部署时请设置成内网ip(非127.0.0.1) -$gateway_text->lanIp = '10.27.184.251'; -// 内部通讯起始端口,假如$gateway_text->count=4,起始端口为4000 -// 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口 -$gateway_text->startPort = 2400; -// 心跳间隔 -$gateway_text->pingInterval = 15; -// 心跳数据 -$gateway_text->pingData = '{"type":"ping"}'; -// 服务注册地址 -$gateway_text->registerAddress = '10.27.184.251:1236'; - -/* -// 当客户端连接上来时,设置连接的onWebSocketConnect,即在websocket握手时的回调 -$gateway_text->onConnect = function($connection) -{ - $connection->onWebSocketConnect = function($connection , $http_header) - { - // 可以在这里判断连接来源是否合法,不合法就关掉连接 - // $_SERVER['HTTP_ORIGIN']标识来自哪个站点的页面发起的websocket链接 - if($_SERVER['HTTP_ORIGIN'] != 'http://chat.workerman.net') - { - $connection->close(); - } - // onWebSocketConnect 里面$_GET $_SERVER是可用的 - // var_dump($_GET, $_SERVER); - }; -}; -*/ - -// 如果不是在根目录启动,则运行runAll方法 -if(!defined('GLOBAL_START')) -{ - Worker::runAll(); -} - diff --git a/Application/start_register.php b/Application/start_register.php deleted file mode 100644 index ae43c28..0000000 --- a/Application/start_register.php +++ /dev/null @@ -1,27 +0,0 @@ - - * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -use \Workerman\Worker; -use \GatewayWorker\Register; - -// 自动加载类 -require_once __DIR__ . '/../Workerman/Autoloader.php'; - -$register = new Register('text://0.0.0.0:1236'); - -// 如果不是在根目录启动,则运行runAll方法 -if(!defined('GLOBAL_START')) -{ - Worker::runAll(); -} - diff --git a/Config/Db.php b/Config/Db.php deleted file mode 100644 index c1835a1..0000000 --- a/Config/Db.php +++ /dev/null @@ -1,15 +0,0 @@ -'10.27.183.176 ', - 'port'=>'3306', - 'user'=>'root', - 'password'=>'a54647dad0', - 'dbname'=>'meilibo', - ); -} diff --git a/Config/Mem.php b/Config/Mem.php deleted file mode 100644 index 6477941..0000000 --- a/Config/Mem.php +++ /dev/null @@ -1,15 +0,0 @@ - - * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -namespace GatewayWorker; - -use Workerman\Connection\TcpConnection; - -use Workerman\Worker; -use Workerman\Lib\Timer; -use Workerman\Connection\AsyncTcpConnection; -use GatewayWorker\Protocols\GatewayProtocol; -use GatewayWorker\Lib\Context; - -/** - * - * BusinessWorker 用于处理Gateway转发来的数据 - * - * @author walkor - * - */ -class BusinessWorker extends Worker -{ - /** - * 保存与 gateway 的连接 connection 对象 - * - * @var array - */ - public $gatewayConnections = array(); - - /** - * 注册中心地址 - * - * @var string - */ - public $registerAddress = '127.0.0.1:1236'; - - /** - * 事件处理类,默认是 Event 类 - * - * @var string - */ - public $eventHandler = 'Events'; - - /** - * 业务超时时间,可用来定位程序卡在哪里 - * - * @var int - */ - public $processTimeout = 30; - - /** - * 业务超时时间,可用来定位程序卡在哪里 - * - * @var callable - */ - public $processTimeoutHandler = '\\Workerman\\Worker::log'; - - /** - * 秘钥 - * @var string - */ - public $secretKey = ''; - - /** - * 保存用户设置的 worker 启动回调 - * - * @var callback - */ - protected $_onWorkerStart = null; - - /** - * 保存用户设置的 workerReload 回调 - * - * @var callback - */ - protected $_onWorkerReload = null; - - /** - * 保存用户设置的 workerStop 回调 - * - * @var callback - */ - protected $_onWorkerStop= null; - - /** - * 到注册中心的连接 - * - * @var AsyncTcpConnection - */ - protected $_registerConnection = null; - - /** - * 处于连接状态的 gateway 通讯地址 - * - * @var array - */ - protected $_connectingGatewayAddresses = array(); - - /** - * 所有 geteway 内部通讯地址 - * - * @var array - */ - protected $_gatewayAddresses = array(); - - /** - * 等待连接个 gateway 地址 - * - * @var array - */ - protected $_waitingConnectGatewayAddresses = array(); - - /** - * Event::onConnect 回调 - * - * @var callback - */ - protected $_eventOnConnect = null; - - /** - * Event::onMessage 回调 - * - * @var callback - */ - protected $_eventOnMessage = null; - - /** - * Event::onClose 回调 - * - * @var callback - */ - protected $_eventOnClose = null; - - /** - * 用于保持长连接的心跳时间间隔 - * - * @var int - */ - const PERSISTENCE_CONNECTION_PING_INTERVAL = 25; - - /** - * 构造函数 - * - * @param string $socket_name - * @param array $context_option - */ - public function __construct($socket_name = '', $context_option = array()) - { - parent::__construct($socket_name, $context_option); - $backrace = debug_backtrace(); - $this->_autoloadRootPath = dirname($backrace[0]['file']); - } - - /** - * {@inheritdoc} - */ - public function run() - { - $this->_onWorkerStart = $this->onWorkerStart; - $this->_onWorkerReload = $this->onWorkerReload; - $this->_onWorkerStop = $this->onWorkerStop; - $this->onWorkerStart = array($this, 'onWorkerStart'); - $this->onWorkerReload = array($this, 'onWorkerReload'); - parent::run(); - } - - /** - * 当进程启动时一些初始化工作 - * - * @return void - */ - protected function onWorkerStart() - { - if (!class_exists('\Protocols\GatewayProtocol')) { - class_alias('GatewayWorker\Protocols\GatewayProtocol', 'Protocols\GatewayProtocol'); - } - $this->connectToRegister(); - \GatewayWorker\Lib\Gateway::setBusinessWorker($this); - \GatewayWorker\Lib\Gateway::$secretKey = $this->secretKey; - if ($this->_onWorkerStart) { - call_user_func($this->_onWorkerStart, $this); - } - - if (is_callable($this->eventHandler . '::onWorkerStart')) { - call_user_func($this->eventHandler . '::onWorkerStart', $this); - } - - if (function_exists('pcntl_signal')) { - // 业务超时信号处理 - pcntl_signal(SIGALRM, array($this, 'timeoutHandler'), false); - } else { - $this->processTimeout = 0; - } - - // 设置回调 - if (is_callable($this->eventHandler . '::onConnect')) { - $this->_eventOnConnect = $this->eventHandler . '::onConnect'; - } - - if (is_callable($this->eventHandler . '::onMessage')) { - $this->_eventOnMessage = $this->eventHandler . '::onMessage'; - } else { - echo "Waring: {$this->eventHandler}::onMessage is not callable\n"; - } - - if (is_callable($this->eventHandler . '::onClose')) { - $this->_eventOnClose = $this->eventHandler . '::onClose'; - } - - // 如果Register服务器不在本地服务器,则需要保持心跳 - if (strpos($this->registerAddress, '127.0.0.1') !== 0) { - Timer::add(self::PERSISTENCE_CONNECTION_PING_INTERVAL, array($this, 'pingRegister')); - } - } - - /** - * onWorkerReload 回调 - * - * @param Worker $worker - */ - protected function onWorkerReload($worker) - { - // 防止进程立刻退出 - $worker->reloadable = false; - // 延迟 0.01 秒退出,避免 BusinessWorker 瞬间全部退出导致没有可用的 BusinessWorker 进程 - Timer::add(0.05, array('Workerman\Worker', 'stopAll')); - // 执行用户定义的 onWorkerReload 回调 - if ($this->_onWorkerReload) { - call_user_func($this->_onWorkerReload, $this); - } - } - - /** - * 当进程关闭时一些清理工作 - * - * @return void - */ - protected function onWorkerStop() - { - if ($this->_onWorkerStop) { - call_user_func($this->_onWorkerStop, $this); - } - if (is_callable($this->eventHandler . '::onWorkerStop')) { - call_user_func($this->eventHandler . '::onWorkerStop', $this); - } - } - - /** - * 连接服务注册中心 - * - * @return void - */ - public function connectToRegister() - { - $this->_registerConnection = new AsyncTcpConnection("text://{$this->registerAddress}"); - $this->_registerConnection->send('{"event":"worker_connect","secret_key":"' . $this->secretKey . '"}'); - $this->_registerConnection->onClose = array($this, 'onRegisterConnectionClose'); - $this->_registerConnection->onMessage = array($this, 'onRegisterConnectionMessage'); - $this->_registerConnection->connect(); - } - - /** - * 与注册中心连接关闭时,定时重连 - * - * @return void - */ - public function onRegisterConnectionClose() - { - Timer::add(1, array($this, 'connectToRegister'), null, false); - } - - /** - * 当注册中心发来消息时 - * - * @return void - */ - public function onRegisterConnectionMessage($register_connection, $data) - { - $data = json_decode($data, true); - if (!isset($data['event'])) { - echo "Received bad data from Register\n"; - return; - } - $event = $data['event']; - switch ($event) { - case 'broadcast_addresses': - if (!is_array($data['addresses'])) { - echo "Received bad data from Register. Addresses empty\n"; - return; - } - $addresses = $data['addresses']; - $this->_gatewayAddresses = array(); - foreach ($addresses as $addr) { - $this->_gatewayAddresses[$addr] = $addr; - } - $this->checkGatewayConnections($addresses); - break; - default: - echo "Receive bad event:$event from Register.\n"; - } - } - - /** - * 当 gateway 转发来数据时 - * - * @param TcpConnection $connection - * @param mixed $data - */ - public function onGatewayMessage($connection, $data) - { - $cmd = $data['cmd']; - if ($cmd === GatewayProtocol::CMD_PING) { - return; - } - // 上下文数据 - Context::$client_ip = $data['client_ip']; - Context::$client_port = $data['client_port']; - Context::$local_ip = $data['local_ip']; - Context::$local_port = $data['local_port']; - Context::$connection_id = $data['connection_id']; - Context::$client_id = Context::addressToClientId($data['local_ip'], $data['local_port'], - $data['connection_id']); - // $_SERVER 变量 - $_SERVER = array( - 'REMOTE_ADDR' => long2ip($data['client_ip']), - 'REMOTE_PORT' => $data['client_port'], - 'GATEWAY_ADDR' => long2ip($data['local_ip']), - 'GATEWAY_PORT' => $data['gateway_port'], - 'GATEWAY_CLIENT_ID' => Context::$client_id, - ); - // 尝试解析 session - if ($data['ext_data'] != '') { - Context::$old_session = $_SESSION = Context::sessionDecode($data['ext_data']); - } else { - Context::$old_session = $_SESSION = null; - } - - if ($this->processTimeout) { - pcntl_alarm($this->processTimeout); - } - // 尝试执行 Event::onConnection、Event::onMessage、Event::onClose - switch ($cmd) { - case GatewayProtocol::CMD_ON_CONNECTION: - if ($this->_eventOnConnect) { - call_user_func($this->_eventOnConnect, Context::$client_id); - } - break; - case GatewayProtocol::CMD_ON_MESSAGE: - if ($this->_eventOnMessage) { - call_user_func($this->_eventOnMessage, Context::$client_id, $data['body']); - } - break; - case GatewayProtocol::CMD_ON_CLOSE: - if ($this->_eventOnClose) { - call_user_func($this->_eventOnClose, Context::$client_id); - } - break; - } - if ($this->processTimeout) { - pcntl_alarm(0); - } - - // session 必须是数组 - if ($_SESSION !== null && !is_array($_SESSION)) { - throw new \Exception('$_SESSION must be an array. But $_SESSION=' . var_export($_SESSION, true) . ' is not array.'); - } - - // 判断 session 是否被更改 - if ($_SESSION !== Context::$old_session) { - $session_str_now = $_SESSION !== null ? Context::sessionEncode($_SESSION) : ''; - \GatewayWorker\Lib\Gateway::setSocketSession(Context::$client_id, $session_str_now); - } - - Context::clear(); - } - - /** - * 当与 Gateway 的连接断开时触发 - * - * @param TcpConnection $connection - * @return void - */ - public function onGatewayClose($connection) - { - $addr = $connection->remoteAddress; - unset($this->gatewayConnections[$addr], $this->_connectingGatewayAddresses[$addr]); - if (isset($this->_gatewayAddresses[$addr]) && !isset($this->_waitingConnectGatewayAddresses[$addr])) { - Timer::add(1, array($this, 'tryToConnectGateway'), array($addr), false); - $this->_waitingConnectGatewayAddresses[$addr] = $addr; - } - } - - /** - * 尝试连接 Gateway 内部通讯地址 - * - * @param string $addr - */ - public function tryToConnectGateway($addr) - { - if (!isset($this->gatewayConnections[$addr]) && !isset($this->_connectingGatewayAddresses[$addr]) && isset($this->_gatewayAddresses[$addr])) { - $gateway_connection = new AsyncTcpConnection("GatewayProtocol://$addr"); - $gateway_connection->remoteAddress = $addr; - $gateway_connection->onConnect = array($this, 'onConnectGateway'); - $gateway_connection->onMessage = array($this, 'onGatewayMessage'); - $gateway_connection->onClose = array($this, 'onGatewayClose'); - $gateway_connection->onError = array($this, 'onGatewayError'); - if (TcpConnection::$defaultMaxSendBufferSize == $gateway_connection->maxSendBufferSize) { - $gateway_connection->maxSendBufferSize = 50 * 1024 * 1024; - } - $gateway_data = GatewayProtocol::$empty; - $gateway_data['cmd'] = GatewayProtocol::CMD_WORKER_CONNECT; - $gateway_data['body'] = json_encode(array( - 'worker_key' =>"{$this->name}:{$this->id}", - 'secret_key' => $this->secretKey, - )); - $gateway_connection->send($gateway_data); - $gateway_connection->connect(); - $this->_connectingGatewayAddresses[$addr] = $addr; - } - unset($this->_waitingConnectGatewayAddresses[$addr]); - } - - /** - * 检查 gateway 的通信端口是否都已经连 - * 如果有未连接的端口,则尝试连接 - * - * @param array $addresses_list - */ - public function checkGatewayConnections($addresses_list) - { - if (empty($addresses_list)) { - return; - } - foreach ($addresses_list as $addr) { - if (!isset($this->_waitingConnectGatewayAddresses[$addr])) { - $this->tryToConnectGateway($addr); - } - } - } - - /** - * 当连接上 gateway 的通讯端口时触发 - * 将连接 connection 对象保存起来 - * - * @param TcpConnection $connection - * @return void - */ - public function onConnectGateway($connection) - { - $this->gatewayConnections[$connection->remoteAddress] = $connection; - unset($this->_connectingGatewayAddresses[$connection->remoteAddress], $this->_waitingConnectGatewayAddresses[$connection->remoteAddress]); - } - - /** - * 当与 gateway 的连接出现错误时触发 - * - * @param TcpConnection $connection - * @param int $error_no - * @param string $error_msg - */ - public function onGatewayError($connection, $error_no, $error_msg) - { - echo "GatewayConnection Error : $error_no ,$error_msg\n"; - } - - /** - * 获取所有 Gateway 内部通讯地址 - * - * @return array - */ - public function getAllGatewayAddresses() - { - return $this->_gatewayAddresses; - } - - /** - * 业务超时回调 - * - * @param int $signal - * @throws \Exception - */ - public function timeoutHandler($signal) - { - switch ($signal) { - // 超时时钟 - case SIGALRM: - // 超时异常 - $e = new \Exception("process_timeout", 506); - $trace_str = $e->getTraceAsString(); - // 去掉第一行timeoutHandler的调用栈 - $trace_str = $e->getMessage() . ":\n" . substr($trace_str, strpos($trace_str, "\n") + 1) . "\n"; - // 开发者没有设置超时处理函数,或者超时处理函数返回空则执行退出 - if (!$this->processTimeoutHandler || !call_user_func($this->processTimeoutHandler, $trace_str, $e)) { - Worker::stopAll(); - } - break; - } - } - - /** - * 向 Register 发送心跳,用来保持长连接 - */ - public function pingRegister() - { - if ($this->_registerConnection) { - $this->_registerConnection->send('{"event":"ping"}'); - } - } -} diff --git a/GatewayWorker/Gateway.php b/GatewayWorker/Gateway.php deleted file mode 100644 index 83b5db5..0000000 --- a/GatewayWorker/Gateway.php +++ /dev/null @@ -1,836 +0,0 @@ - - * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -namespace GatewayWorker; - -use GatewayWorker\Lib\Context; - -use Workerman\Connection\TcpConnection; - -use Workerman\Worker; -use Workerman\Lib\Timer; -use Workerman\Autoloader; -use Workerman\Connection\AsyncTcpConnection; -use GatewayWorker\Protocols\GatewayProtocol; - -/** - * - * Gateway,基于Worker 开发 - * 用于转发客户端的数据给Worker处理,以及转发Worker的数据给客户端 - * - * @author walkor - * - */ -class Gateway extends Worker -{ - /** - * 版本 - * - * @var string - */ - const VERSION = '2.0.5'; - - /** - * 本机 IP - * 单机部署默认 127.0.0.1,如果是分布式部署,需要设置成本机 IP - * - * @var string - */ - public $lanIp = '127.0.0.1'; - - /** - * 本机端口 - * - * @var string - */ - public $lanPort = '127.0.0.1'; - - /** - * gateway 内部通讯起始端口,每个 gateway 实例应该都不同,步长1000 - * - * @var int - */ - public $startPort = 2000; - - /** - * 注册服务地址,用于注册 Gateway BusinessWorker,使之能够通讯 - * - * @var string - */ - public $registerAddress = '127.0.0.1:1236'; - - /** - * 是否可以平滑重启,gateway 不能平滑重启,否则会导致连接断开 - * - * @var bool - */ - public $reloadable = false; - - /** - * 心跳时间间隔 - * - * @var int - */ - public $pingInterval = 0; - - /** - * $pingNotResponseLimit * $pingInterval 时间内,客户端未发送任何数据,断开客户端连接 - * - * @var int - */ - public $pingNotResponseLimit = 0; - - /** - * 服务端向客户端发送的心跳数据 - * - * @var string - */ - public $pingData = ''; - - /** - * 秘钥 - * @var string - */ - public $secretKey = ''; - - /** - * 路由函数 - * - * @var callback - */ - public $router = null; - - /** - * 保存客户端的所有 connection 对象 - * - * @var array - */ - protected $_clientConnections = array(); - - /** - * uid 到 connection 的映射,一对多关系 - */ - protected $_uidConnections = array(); - - /** - * group 到 connection 的映射,一对多关系 - * - * @var array - */ - protected $_groupConnections = array(); - - /** - * 保存所有 worker 的内部连接的 connection 对象 - * - * @var array - */ - protected $_workerConnections = array(); - - /** - * gateway 内部监听 worker 内部连接的 worker - * - * @var Worker - */ - protected $_innerTcpWorker = null; - - /** - * 当 worker 启动时 - * - * @var callback - */ - protected $_onWorkerStart = null; - - /** - * 当有客户端连接时 - * - * @var callback - */ - protected $_onConnect = null; - - /** - * 当客户端发来消息时 - * - * @var callback - */ - protected $_onMessage = null; - - /** - * 当客户端连接关闭时 - * - * @var callback - */ - protected $_onClose = null; - - /** - * 当 worker 停止时 - * - * @var callback - */ - protected $_onWorkerStop = null; - - /** - * 进程启动时间 - * - * @var int - */ - protected $_startTime = 0; - - /** - * gateway 监听的端口 - * - * @var int - */ - protected $_gatewayPort = 0; - - /** - * 到注册中心的连接 - * - * @var AsyncTcpConnection - */ - protected $_registerConnection = null; - - /** - * connectionId 记录器 - * @var int - */ - protected static $_connectionIdRecorder = 1; - - /** - * 用于保持长连接的心跳时间间隔 - * - * @var int - */ - const PERSISTENCE_CONNECTION_PING_INTERVAL = 25; - - /** - * 构造函数 - * - * @param string $socket_name - * @param array $context_option - */ - public function __construct($socket_name, $context_option = array()) - { - parent::__construct($socket_name, $context_option); - list(, , $this->_gatewayPort) = explode(':', $socket_name); - $this->router = array("\\GatewayWorker\\Gateway", 'routerBind'); - - $backrace = debug_backtrace(); - $this->_autoloadRootPath = dirname($backrace[0]['file']); - } - - /** - * {@inheritdoc} - */ - public function run() - { - // 保存用户的回调,当对应的事件发生时触发 - $this->_onWorkerStart = $this->onWorkerStart; - $this->onWorkerStart = array($this, 'onWorkerStart'); - // 保存用户的回调,当对应的事件发生时触发 - $this->_onConnect = $this->onConnect; - $this->onConnect = array($this, 'onClientConnect'); - - // onMessage禁止用户设置回调 - $this->onMessage = array($this, 'onClientMessage'); - - // 保存用户的回调,当对应的事件发生时触发 - $this->_onClose = $this->onClose; - $this->onClose = array($this, 'onClientClose'); - // 保存用户的回调,当对应的事件发生时触发 - $this->_onWorkerStop = $this->onWorkerStop; - $this->onWorkerStop = array($this, 'onWorkerStop'); - - // 记录进程启动的时间 - $this->_startTime = time(); - // 运行父方法 - parent::run(); - } - - /** - * 当客户端发来数据时,转发给worker处理 - * - * @param TcpConnection $connection - * @param mixed $data - */ - public function onClientMessage($connection, $data) - { - $connection->pingNotResponseCount = -1; - $this->sendToWorker(GatewayProtocol::CMD_ON_MESSAGE, $connection, $data); - } - - /** - * 当客户端连接上来时,初始化一些客户端的数据 - * 包括全局唯一的client_id、初始化session等 - * - * @param TcpConnection $connection - */ - public function onClientConnect($connection) - { - $connection->id = self::generateConnectionId(); - // 保存该连接的内部通讯的数据包报头,避免每次重新初始化 - $connection->gatewayHeader = array( - 'local_ip' => ip2long($this->lanIp), - 'local_port' => $this->lanPort, - 'client_ip' => ip2long($connection->getRemoteIp()), - 'client_port' => $connection->getRemotePort(), - 'gateway_port' => $this->_gatewayPort, - 'connection_id' => $connection->id, - ); - // 连接的 session - $connection->session = ''; - // 该连接的心跳参数 - $connection->pingNotResponseCount = -1; - // 保存客户端连接 connection 对象 - $this->_clientConnections[$connection->id] = $connection; - - // 如果用户有自定义 onConnect 回调,则执行 - if ($this->_onConnect) { - call_user_func($this->_onConnect, $connection); - } - - $this->sendToWorker(GatewayProtocol::CMD_ON_CONNECTION, $connection); - } - - /** - * 生成connection id - * @return int - */ - protected function generateConnectionId() - { - if (self::$_connectionIdRecorder >= 4294967295) { - self::$_connectionIdRecorder = 1; - } - $id = self::$_connectionIdRecorder ++; - return $id; - } - - /** - * 发送数据给 worker 进程 - * - * @param int $cmd - * @param TcpConnection $connection - * @param mixed $body - * @return bool - */ - protected function sendToWorker($cmd, $connection, $body = '') - { - $gateway_data = $connection->gatewayHeader; - $gateway_data['cmd'] = $cmd; - $gateway_data['body'] = $body; - $gateway_data['ext_data'] = $connection->session; - if ($this->_workerConnections) { - // 调用路由函数,选择一个worker把请求转发给它 - /** @var TcpConnection $worker_connection */ - $worker_connection = call_user_func($this->router, $this->_workerConnections, $connection, $cmd, $body); - if (false === $worker_connection->send($gateway_data)) { - $msg = "SendBufferToWorker fail. May be the send buffer are overflow"; - $this->log($msg); - return false; - } - } // 没有可用的 worker - else { - // gateway 启动后 1-2 秒内 SendBufferToWorker fail 是正常现象,因为与 worker 的连接还没建立起来, - // 所以不记录日志,只是关闭连接 - $time_diff = 2; - if (time() - $this->_startTime >= $time_diff) { - $msg = 'SendBufferToWorker fail. The connections between Gateway and BusinessWorker are not ready'; - $this->log($msg); - } - $connection->destroy(); - return false; - } - return true; - } - - /** - * 随机路由,返回 worker connection 对象 - * - * @param array $worker_connections - * @param TcpConnection $client_connection - * @param int $cmd - * @param mixed $buffer - * @return TcpConnection - */ - public static function routerRand($worker_connections, $client_connection, $cmd, $buffer) - { - return $worker_connections[array_rand($worker_connections)]; - } - - /** - * client_id 与 worker 绑定 - * - * @param array $worker_connections - * @param TcpConnection $client_connection - * @param int $cmd - * @param mixed $buffer - * @return TcpConnection - */ - public static function routerBind($worker_connections, $client_connection, $cmd, $buffer) - { - if (!isset($client_connection->businessworker_address) || !isset($worker_connections[$client_connection->businessworker_address])) { - $client_connection->businessworker_address = array_rand($worker_connections); - } - return $worker_connections[$client_connection->businessworker_address]; - } - - /** - * 当客户端关闭时 - * - * @param TcpConnection $connection - */ - public function onClientClose($connection) - { - // 尝试通知 worker,触发 Event::onClose - $this->sendToWorker(GatewayProtocol::CMD_ON_CLOSE, $connection); - unset($this->_clientConnections[$connection->id]); - // 清理 uid 数据 - if (!empty($connection->uid)) { - $uid = $connection->uid; - unset($this->_uidConnections[$uid][$connection->id]); - if (empty($this->_uidConnections[$uid])) { - unset($this->_uidConnections[$uid]); - } - } - // 清理 group 数据 - if (!empty($connection->groups)) { - foreach ($connection->groups as $group) { - unset($this->_groupConnections[$group][$connection->id]); - if (empty($this->_groupConnections[$group])) { - unset($this->_groupConnections[$group]); - } - } - } - // 触发 onClose - if ($this->_onClose) { - call_user_func($this->_onClose, $connection); - } - } - - /** - * 当 Gateway 启动的时候触发的回调函数 - * - * @return void - */ - public function onWorkerStart() - { - // 分配一个内部通讯端口 - $this->lanPort = $this->startPort + $this->id; - - // 如果有设置心跳,则定时执行 - if ($this->pingInterval > 0) { - $timer_interval = $this->pingNotResponseLimit > 0 ? $this->pingInterval / 2 : $this->pingInterval; - Timer::add($timer_interval, array($this, 'ping')); - } - - // 如果BusinessWorker ip不是127.0.0.1,则需要加gateway到BusinessWorker的心跳 - if ($this->lanIp !== '127.0.0.1') { - Timer::add(self::PERSISTENCE_CONNECTION_PING_INTERVAL, array($this, 'pingBusinessWorker')); - } - - // 如果 Register 服务器不在本地服务器,则需要保持心跳 - if (strpos($this->registerAddress, '127.0.0.1') !== 0) { - Timer::add(self::PERSISTENCE_CONNECTION_PING_INTERVAL, array($this, 'pingRegister')); - } - - if (!class_exists('\Protocols\GatewayProtocol')) { - class_alias('GatewayWorker\Protocols\GatewayProtocol', 'Protocols\GatewayProtocol'); - } - - // 初始化 gateway 内部的监听,用于监听 worker 的连接已经连接上发来的数据 - $this->_innerTcpWorker = new Worker("GatewayProtocol://{$this->lanIp}:{$this->lanPort}"); - $this->_innerTcpWorker->listen(); - - // 重新设置自动加载根目录 - Autoloader::setRootPath($this->_autoloadRootPath); - - // 设置内部监听的相关回调 - $this->_innerTcpWorker->onMessage = array($this, 'onWorkerMessage'); - - $this->_innerTcpWorker->onConnect = array($this, 'onWorkerConnect'); - $this->_innerTcpWorker->onClose = array($this, 'onWorkerClose'); - - // 注册 gateway 的内部通讯地址,worker 去连这个地址,以便 gateway 与 worker 之间建立起 TCP 长连接 - $this->registerAddress(); - - if ($this->_onWorkerStart) { - call_user_func($this->_onWorkerStart, $this); - } - } - - - /** - * 当 worker 通过内部通讯端口连接到 gateway 时 - * - * @param TcpConnection $connection - */ - public function onWorkerConnect($connection) - { - if (TcpConnection::$defaultMaxSendBufferSize === $connection->maxSendBufferSize) { - $connection->maxSendBufferSize = 50 * 1024 * 1024; - } - $connection->authorized = $this->secretKey ? false : true; - } - - /** - * 当 worker 发来数据时 - * - * @param TcpConnection $connection - * @param mixed $data - * @throws \Exception - */ - public function onWorkerMessage($connection, $data) - { - $cmd = $data['cmd']; - if (empty($connection->authorized) && $cmd !== GatewayProtocol::CMD_WORKER_CONNECT && $cmd !== GatewayProtocol::CMD_GATEWAY_CLIENT_CONNECT) { - echo "Unauthorized request from " . $connection->getRemoteIp() . ":" . $connection->getRemotePort() . "\n"; - return $connection->close(); - } - switch ($cmd) { - // BusinessWorker连接Gateway - case GatewayProtocol::CMD_WORKER_CONNECT: - $worker_info = json_decode($data['body'], true); - if ($worker_info['secret_key'] !== $this->secretKey) { - echo "Gateway: Worker key does not match $secret_key !== {$this->secretKey}\n"; - return $connection->close(); - } - $connection->key = $connection->getRemoteIp() . ':' . $worker_info['worker_key']; - $this->_workerConnections[$connection->key] = $connection; - $connection->authorized = true; - return; - // GatewayClient连接Gateway - case GatewayProtocol::CMD_GATEWAY_CLIENT_CONNECT: - $worker_info = json_decode($data['body'], true); - if ($worker_info['secret_key'] !== $this->secretKey) { - echo "Gateway: GatewayClient key does not match $secret_key !== {$this->secretKey}\n"; - return $connection->close(); - } - $connection->authorized = true; - return; - // 向某客户端发送数据,Gateway::sendToClient($client_id, $message); - case GatewayProtocol::CMD_SEND_TO_ONE: - if (isset($this->_clientConnections[$data['connection_id']])) { - $this->_clientConnections[$data['connection_id']]->send($data['body']); - } - return; - // 关闭客户端连接,Gateway::closeClient($client_id); - case GatewayProtocol::CMD_KICK: - if (isset($this->_clientConnections[$data['connection_id']])) { - $this->_clientConnections[$data['connection_id']]->destroy(); - } - return; - // 广播, Gateway::sendToAll($message, $client_id_array) - case GatewayProtocol::CMD_SEND_TO_ALL: - // $client_id_array 不为空时,只广播给 $client_id_array 指定的客户端 - if ($data['ext_data']) { - $connection_id_array = unpack('N*', $data['ext_data']); - foreach ($connection_id_array as $connection_id) { - if (isset($this->_clientConnections[$connection_id])) { - $this->_clientConnections[$connection_id]->send($data['body']); - } - } - } // $client_id_array 为空时,广播给所有在线客户端 - else { - foreach ($this->_clientConnections as $client_connection) { - $client_connection->send($data['body']); - } - } - return; - // 重新赋值 session - case GatewayProtocol::CMD_SET_SESSION: - if (isset($this->_clientConnections[$data['connection_id']])) { - $this->_clientConnections[$data['connection_id']]->session = $data['ext_data']; - } - return; - // session合并 - case GatewayProtocol::CMD_UPDATE_SESSION: - if (!isset($this->_clientConnections[$data['connection_id']])) { - return; - } else { - if (!$this->_clientConnections[$data['connection_id']]->session) { - $this->_clientConnections[$data['connection_id']]->session = $data['ext_data']; - return; - } - $session = Context::sessionDecode($this->_clientConnections[$data['connection_id']]->session); - $session_for_merge = Context::sessionDecode($data['ext_data']); - $session = $session_for_merge + $session; - $this->_clientConnections[$data['connection_id']]->session = Context::sessionEncode($session); - } - return; - case GatewayProtocol::CMD_GET_SESSION_BY_CLIENT_ID: - if (!isset($this->_clientConnections[$data['connection_id']])) { - $session = serialize(null); - } else { - if (!$this->_clientConnections[$data['connection_id']]->session) { - $session = serialize(array()); - } else { - $session = $this->_clientConnections[$data['connection_id']]->session; - } - } - $connection->send(pack('N', strlen($session)) . $session, true); - return; - // 获得客户端在线状态 Gateway::getALLClientInfo() - case GatewayProtocol::CMD_GET_ALL_CLIENT_INFO: - $client_info_array = array(); - foreach ($this->_clientConnections as $connection_id => $client_connection) { - $client_info_array[$connection_id] = $client_connection->session; - } - $buffer = serialize($client_info_array); - $connection->send(pack('N', strlen($buffer)) . $buffer, true); - return; - // 判断某个 client_id 是否在线 Gateway::isOnline($client_id) - case GatewayProtocol::CMD_IS_ONLINE: - $buffer = serialize((int)isset($this->_clientConnections[$data['connection_id']])); - $connection->send(pack('N', strlen($buffer)) . $buffer, true); - return; - // 将 client_id 与 uid 绑定 - case GatewayProtocol::CMD_BIND_UID: - $uid = $data['ext_data']; - if (empty($uid)) { - echo "uid empty" . var_export($uid, true); - return; - } - $connection_id = $data['connection_id']; - if (!isset($this->_clientConnections[$connection_id])) { - return; - } - $client_connection = $this->_clientConnections[$connection_id]; - if (isset($client_connection->uid)) { - $current_uid = $client_connection->uid; - unset($this->_uidConnections[$current_uid][$connection_id]); - if (empty($this->_uidConnections[$current_uid])) { - unset($this->_uidConnections[$current_uid]); - } - } - $client_connection->uid = $uid; - $this->_uidConnections[$uid][$connection_id] = $client_connection; - return; - // client_id 与 uid 解绑 Gateway::unbindUid($client_id, $uid); - case GatewayProtocol::CMD_UNBIND_UID: - $connection_id = $data['connection_id']; - if (!isset($this->_clientConnections[$connection_id])) { - return; - } - $client_connection = $this->_clientConnections[$connection_id]; - if (isset($client_connection->uid)) { - $current_uid = $client_connection->uid; - unset($this->_uidConnections[$current_uid][$connection_id]); - if (empty($this->_uidConnections[$current_uid])) { - unset($this->_uidConnections[$current_uid]); - } - $client_connection->uid_info = ''; - $client_connection->uid = null; - } - return; - // 发送数据给 uid Gateway::sendToUid($uid, $msg); - case GatewayProtocol::CMD_SEND_TO_UID: - $uid_array = json_decode($data['ext_data'], true); - foreach ($uid_array as $uid) { - if (!empty($this->_uidConnections[$uid])) { - foreach ($this->_uidConnections[$uid] as $connection) { - /** @var TcpConnection $connection */ - $connection->send($data['body']); - } - } - } - return; - // 将 $client_id 加入用户组 Gateway::joinGroup($client_id, $group); - case GatewayProtocol::CMD_JOIN_GROUP: - $group = $data['ext_data']; - if (empty($group)) { - echo "group empty" . var_export($group, true); - return; - } - $connection_id = $data['connection_id']; - if (!isset($this->_clientConnections[$connection_id])) { - return; - } - $client_connection = $this->_clientConnections[$connection_id]; - if (!isset($client_connection->groups)) { - $client_connection->groups = array(); - } - $client_connection->groups[$group] = $group; - $this->_groupConnections[$group][$connection_id] = $client_connection; - return; - // 将 $client_id 从某个用户组中移除 Gateway::leaveGroup($client_id, $group); - case GatewayProtocol::CMD_LEAVE_GROUP: - $group = $data['ext_data']; - if (empty($group)) { - echo "leave group empty" . var_export($group, true); - return; - } - $connection_id = $data['connection_id']; - if (!isset($this->_clientConnections[$connection_id])) { - return; - } - $client_connection = $this->_clientConnections[$connection_id]; - if (!isset($client_connection->groups[$group])) { - return; - } - unset($client_connection->groups[$group], $this->_groupConnections[$group][$connection_id]); - return; - // 向某个用户组发送消息 Gateway::sendToGroup($group, $msg); - case GatewayProtocol::CMD_SEND_TO_GROUP: - $group_array = json_decode($data['ext_data'], true); - foreach ($group_array as $group) { - if (!empty($this->_groupConnections[$group])) { - foreach ($this->_groupConnections[$group] as $connection) { - /** @var TcpConnection $connection */ - $connection->send($data['body']); - } - } - } - return; - // 获取某用户组成员信息 Gateway::getClientInfoByGroup($group); - case GatewayProtocol::CMD_GET_CLINET_INFO_BY_GROUP: - $group = $data['ext_data']; - if (!isset($this->_groupConnections[$group])) { - $buffer = serialize(array()); - $connection->send(pack('N', strlen($buffer)) . $buffer, true); - return; - } - $client_info_array = array(); - foreach ($this->_groupConnections[$group] as $connection_id => $client_connection) { - $client_info_array[$connection_id] = $client_connection->session; - } - $buffer = serialize($client_info_array); - $connection->send(pack('N', strlen($buffer)) . $buffer, true); - return; - // 获取用户组成员数 Gateway::getClientCountByGroup($group); - case GatewayProtocol::CMD_GET_CLIENT_COUNT_BY_GROUP: - $group = $data['ext_data']; - $count = 0; - if ($group !== '') { - if (isset($this->_groupConnections[$group])) { - $count = count($this->_groupConnections[$group]); - } - } else { - $count = count($this->_clientConnections); - } - $buffer = serialize($count); - $connection->send(pack('N', strlen($buffer)) . $buffer, true); - return; - // 获取与某个 uid 绑定的所有 client_id Gateway::getClientIdByUid($uid); - case GatewayProtocol::CMD_GET_CLIENT_ID_BY_UID: - $uid = $data['ext_data']; - if (empty($this->_uidConnections[$uid])) { - $buffer = serialize(array()); - } else { - $buffer = serialize(array_keys($this->_uidConnections[$uid])); - } - $connection->send(pack('N', strlen($buffer)) . $buffer, true); - return; - default : - $err_msg = "gateway inner pack err cmd=$cmd"; - throw new \Exception($err_msg); - } - } - - /** - * 当worker连接关闭时 - * - * @param TcpConnection $connection - */ - public function onWorkerClose($connection) - { - // $this->log("{$connection->key} CLOSE INNER_CONNECTION\n"); - if (isset($connection->key)) { - unset($this->_workerConnections[$connection->key]); - } - } - - /** - * 存储当前 Gateway 的内部通信地址 - * - * @return bool - */ - public function registerAddress() - { - $address = $this->lanIp . ':' . $this->lanPort; - $this->_registerConnection = new AsyncTcpConnection("text://{$this->registerAddress}"); - $this->_registerConnection->send('{"event":"gateway_connect", "address":"' . $address . '", "secret_key":"' . $this->secretKey . '"}'); - $this->_registerConnection->onClose = array($this, 'onRegisterConnectionClose'); - $this->_registerConnection->connect(); - } - - public function onRegisterConnectionClose() - { - Timer::add(1, array($this, 'registerAddress'), null, false); - } - - /** - * 心跳逻辑 - * - * @return void - */ - public function ping() - { - $ping_data = $this->pingData ? (string)$this->pingData : null; - // 遍历所有客户端连接 - foreach ($this->_clientConnections as $connection) { - // 上次发送的心跳还没有回复次数大于限定值就断开 - if ($this->pingNotResponseLimit > 0 && - $connection->pingNotResponseCount >= $this->pingNotResponseLimit * 2 - ) { - $connection->destroy(); - continue; - } - // $connection->pingNotResponseCount 为 -1 说明最近客户端有发来消息,则不给客户端发送心跳 - $connection->pingNotResponseCount++; - if ($ping_data) { - if ($connection->pingNotResponseCount === 0 || - ($this->pingNotResponseLimit > 0 && $connection->pingNotResponseCount % 2 === 0) - ) { - continue; - } - $connection->send($ping_data); - } - } - } - - /** - * 向 BusinessWorker 发送心跳数据,用于保持长连接 - * - * @return void - */ - public function pingBusinessWorker() - { - $gateway_data = GatewayProtocol::$empty; - $gateway_data['cmd'] = GatewayProtocol::CMD_PING; - foreach ($this->_workerConnections as $connection) { - $connection->send($gateway_data); - } - } - - /** - * 向 Register 发送心跳,用来保持长连接 - */ - public function pingRegister() - { - if ($this->_registerConnection) { - $this->_registerConnection->send('{"event":"ping"}'); - } - } - - /** - * 当 gateway 关闭时触发,清理数据 - * - * @return void - */ - public function onWorkerStop() - { - // 尝试触发用户设置的回调 - if ($this->_onWorkerStop) { - call_user_func($this->_onWorkerStop, $this); - } - } -} diff --git a/GatewayWorker/Lib/Context.php b/GatewayWorker/Lib/Context.php deleted file mode 100644 index 0fbd547..0000000 --- a/GatewayWorker/Lib/Context.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -namespace GatewayWorker\Lib; - -use Exception; - -/** - * 上下文 包含当前用户 uid, 内部通信 local_ip local_port socket_id,以及客户端 client_ip client_port - */ -class Context -{ - /** - * 内部通讯 id - * - * @var string - */ - public static $local_ip; - - /** - * 内部通讯端口 - * - * @var int - */ - public static $local_port; - - /** - * 客户端 ip - * - * @var string - */ - public static $client_ip; - - /** - * 客户端端口 - * - * @var int - */ - public static $client_port; - - /** - * client_id - * - * @var string - */ - public static $client_id; - - /** - * 连接 connection->id - * - * @var int - */ - public static $connection_id; - - /** - * 旧的session - * - * @var string - */ - public static $old_session; - - /** - * 编码 session - * - * @param mixed $session_data - * @return string - */ - public static function sessionEncode($session_data = '') - { - if ($session_data !== '') { - return serialize($session_data); - } - return ''; - } - - /** - * 解码 session - * - * @param string $session_buffer - * @return mixed - */ - public static function sessionDecode($session_buffer) - { - return unserialize($session_buffer); - } - - /** - * 清除上下文 - * - * @return void - */ - public static function clear() - { - self::$local_ip = self::$local_port = self::$client_ip = self::$client_port = - self::$client_id = self::$connection_id = self::$old_session = null; - } - - /** - * 通讯地址到 client_id 的转换 - * - * @param int $local_ip - * @param int $local_port - * @param int $connection_id - * @return string - */ - public static function addressToClientId($local_ip, $local_port, $connection_id) - { - return bin2hex(pack('NnN', $local_ip, $local_port, $connection_id)); - } - - /** - * client_id 到通讯地址的转换 - * - * @param string $client_id - * @return array - * @throws Exception - */ - public static function clientIdToAddress($client_id) - { - if (strlen($client_id) !== 20) { - throw new Exception("client_id $client_id is invalid"); - } - return unpack('Nlocal_ip/nlocal_port/Nconnection_id', pack('H*', $client_id)); - } -} diff --git a/GatewayWorker/Lib/Db.php b/GatewayWorker/Lib/Db.php deleted file mode 100644 index bd03203..0000000 --- a/GatewayWorker/Lib/Db.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -namespace GatewayWorker\Lib; - -use Config\Db as DbConfig; -use Exception; - -/** - * 数据库类 - */ -class Db -{ - /** - * 实例数组 - * - * @var array - */ - protected static $instance = array(); - - /** - * 获取实例 - * - * @param string $config_name - * @return DbConnection - * @throws Exception - */ - public static function instance($config_name) - { - if (!isset(DbConfig::$$config_name)) { - echo "\\Config\\Db::$config_name not set\n"; - throw new Exception("\\Config\\Db::$config_name not set\n"); - } - - if (empty(self::$instance[$config_name])) { - $config = DbConfig::$$config_name; - self::$instance[$config_name] = new DbConnection($config['host'], $config['port'], - $config['user'], $config['password'], $config['dbname']); - } - return self::$instance[$config_name]; - } - - /** - * 关闭数据库实例 - * - * @param string $config_name - */ - public static function close($config_name) - { - if (isset(self::$instance[$config_name])) { - self::$instance[$config_name]->closeConnection(); - self::$instance[$config_name] = null; - } - } - /** - * 关闭所有数据库实例 - */ - public static function closeAll() - { - foreach (self::$instance as $connection) { - $connection->closeConnection(); - } - self::$instance = array(); - } -} diff --git a/GatewayWorker/Lib/DbConnection.php b/GatewayWorker/Lib/DbConnection.php deleted file mode 100644 index 4786c11..0000000 --- a/GatewayWorker/Lib/DbConnection.php +++ /dev/null @@ -1,1951 +0,0 @@ -type = 'SELECT'; - if (!is_array($cols)) { - $cols = array($cols); - } - $this->cols($cols); - return $this; - } - - /** - * 从哪个表删除 - * - * @param string $table - * @return self - */ - public function delete($table) - { - $this->type = 'DELETE'; - $this->table = $this->quoteName($table); - $this->fromRaw($this->quoteName($table)); - return $this; - } - - /** - * 更新哪个表 - * - * @param string $table - * @return self - */ - public function update($table) - { - $this->type = 'UPDATE'; - $this->table = $this->quoteName($table); - return $this; - } - - /** - * 向哪个表插入 - * - * @param string $table - * @return self - */ - public function insert($table) - { - $this->type = 'INSERT'; - $this->table = $this->quoteName($table); - return $this; - } - - /** - * - * 设置 SQL_CALC_FOUND_ROWS 标记. - * - * @param bool $enable - * @return self - */ - public function calcFoundRows($enable = true) - { - $this->setFlag('SQL_CALC_FOUND_ROWS', $enable); - return $this; - } - - /** - * 设置 SQL_CACHE 标记 - * - * @param bool $enable - * @return self - */ - public function cache($enable = true) - { - $this->setFlag('SQL_CACHE', $enable); - return $this; - } - - /** - * 设置 SQL_NO_CACHE 标记 - * - * @param bool $enable - * @return self - */ - public function noCache($enable = true) - { - $this->setFlag('SQL_NO_CACHE', $enable); - return $this; - } - - /** - * 设置 STRAIGHT_JOIN 标记. - * - * @param bool $enable - * @return self - */ - public function straightJoin($enable = true) - { - $this->setFlag('STRAIGHT_JOIN', $enable); - return $this; - } - - /** - * 设置 HIGH_PRIORITY 标记 - * - * @param bool $enable - * @return self - */ - public function highPriority($enable = true) - { - $this->setFlag('HIGH_PRIORITY', $enable); - return $this; - } - - /** - * 设置 SQL_SMALL_RESULT 标记 - * - * @param bool $enable - * @return self - */ - public function smallResult($enable = true) - { - $this->setFlag('SQL_SMALL_RESULT', $enable); - return $this; - } - - /** - * 设置 SQL_BIG_RESULT 标记 - * - * @param bool $enable - * @return self - */ - public function bigResult($enable = true) - { - $this->setFlag('SQL_BIG_RESULT', $enable); - return $this; - } - - /** - * 设置 SQL_BUFFER_RESULT 标记 - * - * @param bool $enable - * @return self - */ - public function bufferResult($enable = true) - { - $this->setFlag('SQL_BUFFER_RESULT', $enable); - return $this; - } - - /** - * 设置 FOR UPDATE 标记 - * - * @param bool $enable - * @return self - */ - public function forUpdate($enable = true) - { - $this->for_update = (bool)$enable; - return $this; - } - - /** - * 设置 DISTINCT 标记 - * - * @param bool $enable - * @return self - */ - public function distinct($enable = true) - { - $this->setFlag('DISTINCT', $enable); - return $this; - } - - /** - * 设置 LOW_PRIORITY 标记 - * - * @param bool $enable - * @return self - */ - public function lowPriority($enable = true) - { - $this->setFlag('LOW_PRIORITY', $enable); - return $this; - } - - /** - * 设置 IGNORE 标记 - * - * @param bool $enable - * @return self - */ - public function ignore($enable = true) - { - $this->setFlag('IGNORE', $enable); - return $this; - } - - /** - * 设置 QUICK 标记 - * - * @param bool $enable - * @return self - */ - public function quick($enable = true) - { - $this->setFlag('QUICK', $enable); - return $this; - } - - /** - * 设置 DELAYED 标记 - * - * @param bool $enable - * @return self - */ - public function delayed($enable = true) - { - $this->setFlag('DELAYED', $enable); - return $this; - } - - /** - * 序列化 - * - * @return string - */ - public function __toString() - { - $union = ''; - if ($this->union) { - $union = implode(' ', $this->union) . ' '; - } - return $union . $this->build(); - } - - /** - * 设置每页多少条记录 - * - * @param int $paging - * @return self - */ - public function setPaging($paging) - { - $this->paging = (int)$paging; - return $this; - } - - /** - * 获取每页多少条记录 - * - * @return int - */ - public function getPaging() - { - return $this->paging; - } - - /** - * 获取绑定在占位符上的值 - */ - public function getBindValues() - { - switch ($this->type) { - case 'SELECT': - return $this->getBindValuesSELECT(); - case 'DELETE': - case 'UPDATE': - case 'INSERT': - return $this->getBindValuesCOMMON(); - default : - throw new Exception("type err"); - } - } - - /** - * 获取绑定在占位符上的值 - * - * @return array - */ - public function getBindValuesSELECT() - { - $bind_values = $this->bind_values; - $i = 1; - foreach ($this->bind_where as $val) { - $bind_values[$i] = $val; - $i++; - } - foreach ($this->bind_having as $val) { - $bind_values[$i] = $val; - $i++; - } - return $bind_values; - } - - /** - * - * SELECT选择哪些列 - * - * @param mixed $key - * @param string $val - * @return void - */ - protected function addColSELECT($key, $val) - { - if (is_string($key)) { - $this->cols[$val] = $key; - } else { - $this->addColWithAlias($val); - } - } - - /** - * SELECT 增加选择的列 - * - * @param string $spec - */ - protected function addColWithAlias($spec) - { - $parts = explode(' ', $spec); - $count = count($parts); - if ($count == 2) { - $this->cols[$parts[1]] = $parts[0]; - } elseif ($count == 3 && strtoupper($parts[1]) == 'AS') { - $this->cols[$parts[2]] = $parts[0]; - } else { - $this->cols[] = $spec; - } - } - - /** - * from 哪个表 - * - * @param string $table - * @return self - */ - public function from($table) - { - return $this->fromRaw($this->quoteName($table)); - } - - /** - * from的表 - * - * @param string $table - * @return self - */ - public function fromRaw($table) - { - $this->from[] = array($table); - $this->from_key++; - return $this; - } - - /** - * - * 子查询 - * - * @param string $table - * @param string $name The alias name for the sub-select. - * @return self - */ - public function fromSubSelect($table, $name) - { - $this->from[] = array("($table) AS " . $this->quoteName($name)); - $this->from_key++; - return $this; - } - - - /** - * 增加 join 语句 - * - * @param string $table - * @param string $cond - * @param string $type - * @return self - * @throws Exception - */ - public function join($table, $cond = null, $type = '') - { - return $this->joinInternal($type, $table, $cond); - } - - /** - * 增加 join 语句 - * - * @param string $join inner, left, natural - * @param string $table - * @param string $cond - * @return self - * @throws Exception - */ - protected function joinInternal($join, $table, $cond = null) - { - if (!$this->from) { - throw new Exception('Cannot join() without from()'); - } - - $join = strtoupper(ltrim("$join JOIN")); - $table = $this->quoteName($table); - $cond = $this->fixJoinCondition($cond); - $this->from[$this->from_key][] = rtrim("$join $table $cond"); - return $this; - } - - /** - * quote - * - * @param string $cond - * @return string - * - */ - protected function fixJoinCondition($cond) - { - if (!$cond) { - return ''; - } - - $cond = $this->quoteNamesIn($cond); - - if (strtoupper(substr(ltrim($cond), 0, 3)) == 'ON ') { - return $cond; - } - - if (strtoupper(substr(ltrim($cond), 0, 6)) == 'USING ') { - return $cond; - } - - return 'ON ' . $cond; - } - - /** - * inner join - * - * @param string $table - * @param string $cond - * @return self - * @throws Exception - */ - public function innerJoin($table, $cond = null) - { - return $this->joinInternal('INNER', $table, $cond); - } - - /** - * left join - * - * @param string $table - * @param string $cond - * @return self - * @throws Exception - */ - public function leftJoin($table, $cond = null) - { - return $this->joinInternal('LEFT', $table, $cond); - } - - /** - * right join - * - * @param string $table - * @param string $cond - * @return self - * @throws Exception - */ - public function rightJoin($table, $cond = null) - { - return $this->joinInternal('RIGHT', $table, $cond); - } - - /** - * joinSubSelect - * - * @param string $join inner, left, natural - * @param string $spec - * @param string $name sub-select 的别名 - * @param string $cond - * @return self - * @throws Exception - */ - public function joinSubSelect($join, $spec, $name, $cond = null) - { - if (!$this->from) { - throw new \Exception('Cannot join() without from() first.'); - } - - $join = strtoupper(ltrim("$join JOIN")); - $name = $this->quoteName($name); - $cond = $this->fixJoinCondition($cond); - $this->from[$this->from_key][] = rtrim("$join ($spec) AS $name $cond"); - return $this; - } - - /** - * group by 语句 - * - * @param array $cols - * @return self - */ - public function groupBy(array $cols) - { - foreach ($cols as $col) { - $this->group_by[] = $this->quoteNamesIn($col); - } - return $this; - } - - /** - * having 语句 - * - * @param string $cond - * @return self - */ - public function having($cond) - { - $this->addClauseCondWithBind('having', 'AND', func_get_args()); - return $this; - } - - /** - * or having 语句 - * - * @param string $cond The HAVING condition. - * @return self - */ - public function orHaving($cond) - { - $this->addClauseCondWithBind('having', 'OR', func_get_args()); - return $this; - } - - /** - * 设置每页的记录数量 - * - * @param int $page - * @return self - */ - public function page($page) - { - $this->limit = 0; - $this->offset = 0; - - $page = (int)$page; - if ($page > 0) { - $this->limit = $this->paging; - $this->offset = $this->paging * ($page - 1); - } - return $this; - } - - /** - * union - * - * @return self - */ - public function union() - { - $this->union[] = $this->build() . ' UNION'; - $this->reset(); - return $this; - } - - /** - * unionAll - * - * @return self - */ - public function unionAll() - { - $this->union[] = $this->build() . ' UNION ALL'; - $this->reset(); - return $this; - } - - /** - * 重置 - */ - protected function reset() - { - $this->resetFlags(); - $this->cols = array(); - $this->from = array(); - $this->from_key = -1; - $this->where = array(); - $this->group_by = array(); - $this->having = array(); - $this->order_by = array(); - $this->limit = 0; - $this->offset = 0; - $this->for_update = false; - } - - /** - * 清除所有数据 - */ - protected function resetAll() - { - $this->union = array(); - $this->for_update = false; - $this->cols = array(); - $this->from = array(); - $this->from_key = -1; - $this->group_by = array(); - $this->having = array(); - $this->bind_having = array(); - $this->paging = 10; - $this->bind_values = array(); - $this->where = array(); - $this->bind_where = array(); - $this->order_by = array(); - $this->limit = 0; - $this->offset = 0; - $this->flags = array(); - $this->table = ''; - $this->last_insert_id_names = array(); - $this->col_values = array(); - $this->returning = array(); - $this->parameters = array(); - } - - /** - * 创建 SELECT SQL - * - * @return string - */ - protected function buildSELECT() - { - return 'SELECT' - . $this->buildFlags() - . $this->buildCols() - . $this->buildFrom() - . $this->buildWhere() - . $this->buildGroupBy() - . $this->buildHaving() - . $this->buildOrderBy() - . $this->buildLimit() - . $this->buildForUpdate(); - } - - /** - * 创建 DELETE SQL - */ - protected function buildDELETE() - { - return 'DELETE' - . $this->buildFlags() - . $this->buildFrom() - . $this->buildWhere() - . $this->buildOrderBy() - . $this->buildLimit() - . $this->buildReturning(); - } - - /** - * 生成 SELECT 列语句 - * - * @return string - * @throws Exception - */ - protected function buildCols() - { - if (!$this->cols) { - throw new Exception('No columns in the SELECT.'); - } - - $cols = array(); - foreach ($this->cols as $key => $val) { - if (is_int($key)) { - $cols[] = $this->quoteNamesIn($val); - } else { - $cols[] = $this->quoteNamesIn("$val AS $key"); - } - } - - return $this->indentCsv($cols); - } - - /** - * 生成 FROM 语句. - * - * @return string - */ - protected function buildFrom() - { - if (!$this->from) { - return ''; - } - - $refs = array(); - foreach ($this->from as $from) { - $refs[] = implode(' ', $from); - } - return ' FROM' . $this->indentCsv($refs); - } - - /** - * 生成 GROUP BY 语句. - * - * @return string - */ - protected function buildGroupBy() - { - if (!$this->group_by) { - return ''; - } - return ' GROUP BY' . $this->indentCsv($this->group_by); - } - - /** - * 生成 HAVING 语句. - * - * @return string - */ - protected function buildHaving() - { - if (!$this->having) { - return ''; - } - return ' HAVING' . $this->indent($this->having); - } - - /** - * 生成 FOR UPDATE 语句 - * - * @return string - */ - protected function buildForUpdate() - { - if (!$this->for_update) { - return ''; - } - return ' FOR UPDATE'; - } - - /** - * where - * - * @param string|array $cond - * @return self - */ - public function where($cond) - { - if (is_array($cond)) { - foreach ($cond as $key => $val) { - if (is_string($key)) { - $this->addWhere('AND', array($key, $val)); - } else { - $this->addWhere('AND', array($val)); - } - } - } else { - $this->addWhere('AND', func_get_args()); - } - return $this; - } - - /** - * or where - * - * @param string|array $cond - * @return self - */ - public function orWhere($cond) - { - if (is_array($cond)) { - foreach ($cond as $key => $val) { - if (is_string($key)) { - $this->addWhere('OR', array($key, $val)); - } else { - $this->addWhere('OR', array($val)); - } - } - } else { - $this->addWhere('OR', func_get_args()); - } - return $this; - } - - /** - * limit - * - * @param int $limit - * @return self - */ - public function limit($limit) - { - $this->limit = (int)$limit; - return $this; - } - - /** - * limit offset - * - * @param int $offset - * @return self - */ - public function offset($offset) - { - $this->offset = (int)$offset; - return $this; - } - - /** - * orderby. - * - * @param array $cols - * @return self - */ - public function orderBy(array $cols) - { - return $this->addOrderBy($cols); - } - - /** - * order by ASC OR DESC - * - * @param array $cols - * @param bool $order_asc - * @return self - */ - public function orderByASC(array $cols, $order_asc = true) - { - $this->order_asc = $order_asc; - return $this->addOrderBy($cols); - } - - // -------------abstractquery---------- - /** - * 返回逗号分隔的字符串 - * - * @param array $list - * @return string - */ - protected function indentCsv(array $list) - { - return ' ' . implode(',', $list); - } - - /** - * 返回空格分隔的字符串 - * - * @param array $list - * @return string - */ - protected function indent(array $list) - { - return ' ' . implode(' ', $list); - } - - /** - * 批量为占位符绑定值 - * - * @param array $bind_values - * @return self - * - */ - public function bindValues(array $bind_values) - { - foreach ($bind_values as $key => $val) { - $this->bindValue($key, $val); - } - return $this; - } - - /** - * 单个为占位符绑定值 - * - * @param string $name - * @param mixed $value - * @return self - */ - public function bindValue($name, $value) - { - $this->bind_values[$name] = $value; - return $this; - } - - /** - * 生成 flag - * - * @return string - */ - protected function buildFlags() - { - if (!$this->flags) { - return ''; - } - return ' ' . implode(' ', array_keys($this->flags)); - } - - /** - * 设置 flag. - * - * @param string $flag - * @param bool $enable - */ - protected function setFlag($flag, $enable = true) - { - if ($enable) { - $this->flags[$flag] = true; - } else { - unset($this->flags[$flag]); - } - } - - /** - * 重置 flag - */ - protected function resetFlags() - { - $this->flags = array(); - } - - /** - * - * 添加 where 语句 - * - * @param string $andor 'AND' or 'OR - * @param array $conditions - * @return self - * - */ - protected function addWhere($andor, $conditions) - { - $this->addClauseCondWithBind('where', $andor, $conditions); - return $this; - } - - /** - * 添加条件和绑定值 - * - * @param string $clause where 、having等 - * @param string $andor AND、OR等 - * @param array $conditions - */ - protected function addClauseCondWithBind($clause, $andor, $conditions) - { - $cond = array_shift($conditions); - $cond = $this->quoteNamesIn($cond); - - $bind =& $this->{"bind_{$clause}"}; - foreach ($conditions as $value) { - $bind[] = $value; - } - - $clause =& $this->$clause; - if ($clause) { - $clause[] = "$andor $cond"; - } else { - $clause[] = $cond; - } - } - - /** - * 生成 where 语句 - * - * @return string - */ - protected function buildWhere() - { - if (!$this->where) { - return ''; - } - return ' WHERE' . $this->indent($this->where); - } - - /** - * 增加 order by - * - * @param array $spec The columns and direction to order by. - * @return self - */ - protected function addOrderBy(array $spec) - { - foreach ($spec as $col) { - $this->order_by[] = $this->quoteNamesIn($col); - } - return $this; - } - - /** - * 生成 order by 语句 - * - * @return string - */ - protected function buildOrderBy() - { - if (!$this->order_by) { - return ''; - } - - if ($this->order_asc) { - return ' ORDER BY' . $this->indentCsv($this->order_by) . ' ASC'; - } else { - return ' ORDER BY' . $this->indentCsv($this->order_by) . ' DESC'; - } - } - - /** - * 生成 limit 语句 - * - * @return string - */ - protected function buildLimit() - { - $has_limit = $this->type == 'DELETE' || $this->type == 'UPDATE'; - $has_offset = $this->type == 'SELECT'; - - if ($has_offset && $this->limit) { - $clause = " LIMIT {$this->limit}"; - if ($this->offset) { - $clause .= " OFFSET {$this->offset}"; - } - return $clause; - } elseif ($has_limit && $this->limit) { - return " LIMIT {$this->limit}"; - } - return ''; - } - - /** - * Quotes - * - * @param string $spec - * @return string|array - */ - public function quoteName($spec) - { - $spec = trim($spec); - $seps = array(' AS ', ' ', '.'); - foreach ($seps as $sep) { - $pos = strripos($spec, $sep); - if ($pos) { - return $this->quoteNameWithSeparator($spec, $sep, $pos); - } - } - return $this->replaceName($spec); - } - - /** - * 指定分隔符的 Quotes - * - * @param string $spec - * @param string $sep - * @param int $pos - * @return string - */ - protected function quoteNameWithSeparator($spec, $sep, $pos) - { - $len = strlen($sep); - $part1 = $this->quoteName(substr($spec, 0, $pos)); - $part2 = $this->replaceName(substr($spec, $pos + $len)); - return "{$part1}{$sep}{$part2}"; - } - - /** - * Quotes "table.col" 格式的字符串 - * - * @param string $text - * @return string|array - */ - public function quoteNamesIn($text) - { - $list = $this->getListForQuoteNamesIn($text); - $last = count($list) - 1; - $text = null; - foreach ($list as $key => $val) { - if (($key + 1) % 3) { - $text .= $this->quoteNamesInLoop($val, $key == $last); - } - } - return $text; - } - - /** - * 返回 quote 元素列表 - * - * @param string $text - * @return array - */ - protected function getListForQuoteNamesIn($text) - { - $apos = "'"; - $quot = '"'; - return preg_split( - "/(($apos+|$quot+|\\$apos+|\\$quot+).*?\\2)/", - $text, - -1, - PREG_SPLIT_DELIM_CAPTURE - ); - } - - /** - * 循环 quote - * - * @param string $val - * @param bool $is_last - * @return string - */ - protected function quoteNamesInLoop($val, $is_last) - { - if ($is_last) { - return $this->replaceNamesAndAliasIn($val); - } - return $this->replaceNamesIn($val); - } - - /** - * 替换成别名 - * - * @param string $val - * @return string - */ - protected function replaceNamesAndAliasIn($val) - { - $quoted = $this->replaceNamesIn($val); - $pos = strripos($quoted, ' AS '); - if ($pos) { - $alias = $this->replaceName(substr($quoted, $pos + 4)); - $quoted = substr($quoted, 0, $pos) . " AS $alias"; - } - return $quoted; - } - - /** - * Quotes name - * - * @param string $name - * @return string - */ - protected function replaceName($name) - { - $name = trim($name); - if ($name == '*') { - return $name; - } - return '`' . $name . '`'; - } - - /** - * Quotes - * - * @param string $text - * @return string|array - */ - protected function replaceNamesIn($text) - { - $is_string_literal = strpos($text, "'") !== false - || strpos($text, '"') !== false; - if ($is_string_literal) { - return $text; - } - - $word = '[a-z_][a-z0-9_]+'; - - $find = "/(\\b)($word)\\.($word)(\\b)/i"; - - $repl = '$1`$2`.`$3`$4'; - - $text = preg_replace($find, $repl, $text); - - return $text; - } - - // ---------- insert -------------- - /** - * 设置 `table.column` 与 last-insert-id 的映射 - * - * @param array $last_insert_id_names - */ - public function setLastInsertIdNames(array $last_insert_id_names) - { - $this->last_insert_id_names = $last_insert_id_names; - } - - /** - * insert into. - * - * @param string $table - * @return self - */ - public function into($table) - { - $this->table = $this->quoteName($table); - return $this; - } - - /** - * 生成 INSERT 语句 - * - * @return string - */ - protected function buildINSERT() - { - return 'INSERT' - . $this->buildFlags() - . $this->buildInto() - . $this->buildValuesForInsert() - . $this->buildReturning(); - } - - /** - * 生成 INTO 语句 - * - * @return string - */ - protected function buildInto() - { - return " INTO " . $this->table; - } - - /** - * PDO::lastInsertId() - * - * @param string $col - * @return mixed - */ - public function getLastInsertIdName($col) - { - $key = str_replace('`', '', $this->table) . '.' . $col; - if (isset($this->last_insert_id_names[$key])) { - return $this->last_insert_id_names[$key]; - } - - return null; - } - - /** - * 设置一列,如果有第二各参数,则把第二个参数绑定在占位符上 - * - * @param string $col - * @return self - */ - public function col($col) - { - return call_user_func_array(array($this, 'addCol'), func_get_args()); - } - - /** - * 设置多列 - * - * @param array $cols - * @return self - */ - public function cols(array $cols) - { - if ($this->type == 'SELECT') { - foreach ($cols as $key => $val) { - $this->addColSELECT($key, $val); - } - return $this; - } - return $this->addCols($cols); - } - - /** - * 直接设置列的值 - * - * @param string $col - * @param string $value - * @return self - */ - public function set($col, $value) - { - return $this->setCol($col, $value); - } - - /** - * 为 INSERT 语句绑定值 - * - * @return string - */ - protected function buildValuesForInsert() - { - return ' (' . $this->indentCsv(array_keys($this->col_values)) . ') VALUES (' . - $this->indentCsv(array_values($this->col_values)) . ')'; - } - - // ------update------- - /** - * 更新哪个表 - * - * @param string $table - * @return self - */ - public function table($table) - { - $this->table = $this->quoteName($table); - return $this; - } - - /** - * 生成完整 SQL 语句 - * - * @return string - * @throws Exception - */ - protected function build() - { - switch ($this->type) { - case 'DELETE': - return $this->buildDELETE(); - case 'INSERT': - return $this->buildINSERT(); - case 'UPDATE': - return $this->buildUPDATE(); - case 'SELECT': - return $this->buildSELECT(); - } - throw new Exception("type empty"); - } - - /** - * 生成更新的 SQL 语句 - */ - protected function buildUPDATE() - { - return 'UPDATE' - . $this->buildFlags() - . $this->buildTable() - . $this->buildValuesForUpdate() - . $this->buildWhere() - . $this->buildOrderBy() - . $this->buildLimit() - . $this->buildReturning(); - } - - /** - * 哪个表 - * - * @return string - */ - protected function buildTable() - { - return " {$this->table}"; - } - - /** - * 为更新语句绑定值 - * - * @return string - */ - protected function buildValuesForUpdate() - { - $values = array(); - foreach ($this->col_values as $col => $value) { - $values[] = "{$col} = {$value}"; - } - return ' SET' . $this->indentCsv($values); - } - - // ----------Dml--------------- - /** - * 获取绑定的值 - * - * @return array - */ - public function getBindValuesCOMMON() - { - $bind_values = $this->bind_values; - $i = 1; - foreach ($this->bind_where as $val) { - $bind_values[$i] = $val; - $i++; - } - return $bind_values; - } - - /** - * 设置列 - * - * @param string $col - * @return self - */ - protected function addCol($col) - { - $key = $this->quoteName($col); - $this->col_values[$key] = ":$col"; - $args = func_get_args(); - if (count($args) > 1) { - $this->bindValue($col, $args[1]); - } - return $this; - } - - /** - * 设置多个列 - * - * @param array $cols - * @return self - */ - protected function addCols(array $cols) - { - foreach ($cols as $key => $val) { - if (is_int($key)) { - $this->addCol($val); - } else { - $this->addCol($key, $val); - } - } - return $this; - } - - /** - * 设置单列的值 - * - * @param string $col . - * @param string $value - * @return self - */ - protected function setCol($col, $value) - { - if ($value === null) { - $value = 'NULL'; - } - - $key = $this->quoteName($col); - $value = $this->quoteNamesIn($value); - $this->col_values[$key] = $value; - return $this; - } - - /** - * 增加返回的列 - * - * @param array $cols - * @return self - * - */ - protected function addReturning(array $cols) - { - foreach ($cols as $col) { - $this->returning[] = $this->quoteNamesIn($col); - } - return $this; - } - - /** - * 生成 RETURNING 语句 - * - * @return string - */ - protected function buildReturning() - { - if (!$this->returning) { - return ''; - } - return ' RETURNING' . $this->indentCsv($this->returning); - } - - /** - * 构造函数 - * - * @param string $host - * @param int $port - * @param string $user - * @param string $password - * @param string $db_name - * @param string $charset - */ - public function __construct($host, $port, $user, $password, $db_name, $charset = 'utf8') - { - $this->settings = array( - 'host' => $host, - 'port' => $port, - 'user' => $user, - 'password' => $password, - 'dbname' => $db_name, - 'charset' => $charset, - ); - $this->connect(); - } - - /** - * 创建 PDO 实例 - */ - protected function connect() - { - $dsn = 'mysql:dbname=' . $this->settings["dbname"] . ';host=' . - $this->settings["host"] . ';port=' . $this->settings['port']; - $this->pdo = new PDO($dsn, $this->settings["user"], $this->settings["password"], - array( - PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . (!empty($this->settings['charset']) ? - $this->settings['charset'] : 'utf8') - )); - $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); - } - - /** - * 关闭连接 - */ - public function closeConnection() - { - $this->pdo = null; - } - - /** - * 执行 - * - * @param string $query - * @param string $parameters - * @throws PDOException - */ - protected function execute($query, $parameters = "") - { - try { - $this->sQuery = $this->pdo->prepare($query); - $this->bindMore($parameters); - if (!empty($this->parameters)) { - foreach ($this->parameters as $param) { - $parameters = explode("\x7F", $param); - $this->sQuery->bindParam($parameters[0], $parameters[1]); - } - } - $this->success = $this->sQuery->execute(); - } catch (PDOException $e) { - // 服务端断开时重连一次 - if ($e->errorInfo[1] == 2006 || $e->errorInfo[1] == 2013) { - $this->closeConnection(); - $this->connect(); - - try { - $this->sQuery = $this->pdo->prepare($query); - $this->bindMore($parameters); - if (!empty($this->parameters)) { - foreach ($this->parameters as $param) { - $parameters = explode("\x7F", $param); - $this->sQuery->bindParam($parameters[0], $parameters[1]); - } - } - $this->success = $this->sQuery->execute(); - } catch (PDOException $ex) { - $this->rollBackTrans(); - throw $ex; - } - } else { - $this->rollBackTrans(); - throw $e; - } - } - $this->parameters = array(); - } - - /** - * 绑定 - * - * @param string $para - * @param string $value - */ - public function bind($para, $value) - { - if (is_string($para)) { - $this->parameters[sizeof($this->parameters)] = ":" . $para . "\x7F" . $value; - } else { - $this->parameters[sizeof($this->parameters)] = $para . "\x7F" . $value; - } - } - - /** - * 绑定多个 - * - * @param array $parray - */ - public function bindMore($parray) - { - if (empty($this->parameters) && is_array($parray)) { - $columns = array_keys($parray); - foreach ($columns as $i => &$column) { - $this->bind($column, $parray[$column]); - } - } - } - - /** - * 执行 SQL - * - * @param string $query - * @param array $params - * @param int $fetchmode - * @return mixed - */ - public function query($query = '', $params = null, $fetchmode = PDO::FETCH_ASSOC) - { - $query = trim($query); - if (empty($query)) { - $query = $this->build(); - if (!$params) { - $params = $this->getBindValues(); - } - } - - $this->resetAll(); - $this->lastSql = $query; - - $this->execute($query, $params); - - $rawStatement = explode(" ", $query); - - $statement = strtolower(trim($rawStatement[0])); - if ($statement === 'select' || $statement === 'show') { - return $this->sQuery->fetchAll($fetchmode); - } elseif ($statement === 'update' || $statement === 'delete') { - return $this->sQuery->rowCount(); - } elseif ($statement === 'insert') { - if ($this->sQuery->rowCount() > 0) { - return $this->lastInsertId(); - } - } else { - return null; - } - - return null; - } - - /** - * 返回一列 - * - * @param string $query - * @param array $params - * @return array - */ - public function column($query = '', $params = null) - { - $query = trim($query); - if (empty($query)) { - $query = $this->build(); - if (!$params) { - $params = $this->getBindValues(); - } - } - - $this->resetAll(); - $this->lastSql = $query; - - $this->execute($query, $params); - $columns = $this->sQuery->fetchAll(PDO::FETCH_NUM); - $column = null; - foreach ($columns as $cells) { - $column[] = $cells[0]; - } - return $column; - } - - /** - * 返回一行 - * - * @param string $query - * @param array $params - * @param int $fetchmode - * @return array - */ - public function row($query = '', $params = null, $fetchmode = PDO::FETCH_ASSOC) - { - $query = trim($query); - if (empty($query)) { - $query = $this->build(); - if (!$params) { - $params = $this->getBindValues(); - } - } - - $this->resetAll(); - $this->lastSql = $query; - - $this->execute($query, $params); - return $this->sQuery->fetch($fetchmode); - } - - /** - * 返回单个值 - * - * @param string $query - * @param array $params - * @return string - */ - public function single($query = '', $params = null) - { - $query = trim($query); - if (empty($query)) { - $query = $this->build(); - if (!$params) { - $params = $this->getBindValues(); - } - } - - $this->resetAll(); - $this->lastSql = $query; - - $this->execute($query, $params); - return $this->sQuery->fetchColumn(); - } - - /** - * 返回 lastInsertId - * - * @return string - */ - public function lastInsertId() - { - return $this->pdo->lastInsertId(); - } - - /** - * 返回最后一条直行的 sql - * - * @return string - */ - public function lastSQL() - { - return $this->lastSql; - } - - /** - * 开始事务 - */ - public function beginTrans() - { - $this->pdo->beginTransaction(); - } - - /** - * 提交事务 - */ - public function commitTrans() - { - $this->pdo->commit(); - } - - /** - * 事务回滚 - */ - public function rollBackTrans() - { - if ($this->pdo->inTransaction()) { - $this->pdo->rollBack(); - } - } -} diff --git a/GatewayWorker/Lib/Gateway.php b/GatewayWorker/Lib/Gateway.php deleted file mode 100644 index ec18382..0000000 --- a/GatewayWorker/Lib/Gateway.php +++ /dev/null @@ -1,693 +0,0 @@ - - * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -namespace GatewayWorker\Lib; - -use Exception; -use GatewayWorker\Protocols\GatewayProtocol; -use Workerman\Connection\TcpConnection; - -/** - * 数据发送相关 - */ -class Gateway -{ - /** - * gateway 实例 - * - * @var object - */ - protected static $businessWorker = null; - - /** - * 注册中心地址 - * - * @var string - */ - public static $registerAddress = '127.0.0.1:1236'; - - /** - * 秘钥 - * @var string - */ - public static $secretKey = ''; - - /** - * 向所有客户端连接(或者 client_id_array 指定的客户端连接)广播消息 - * - * @param string $message 向客户端发送的消息 - * @param array $client_id_array 客户端 id 数组 - * @return void - */ - public static function sendToAll($message, $client_id_array = null) - { - $gateway_data = GatewayProtocol::$empty; - $gateway_data['cmd'] = GatewayProtocol::CMD_SEND_TO_ALL; - $gateway_data['body'] = $message; - - if ($client_id_array) { - $data_array = array(); - foreach ($client_id_array as $client_id) { - $address = Context::clientIdToAddress($client_id); - - $key = long2ip($address['local_ip']) . ":{$address['local_port']}"; - $data_array[$key][$address['connection_id']] = $address['connection_id']; - } - foreach ($data_array as $addr => $connection_id_list) { - $the_gateway_data = $gateway_data; - $the_gateway_data['ext_data'] = call_user_func_array('pack', - array_merge(array('N*'), $connection_id_list)); - self::sendToGateway($addr, $the_gateway_data); - } - return; - } elseif (empty($client_id_array) && is_array($client_id_array)) { - return; - } - - self::sendToAllGateway($gateway_data); - } - - /** - * 向某个客户端连接发消息 - * - * @param int $client_id - * @param string $message - * @return bool - */ - public static function sendToClient($client_id, $message) - { - return self::sendCmdAndMessageToClient($client_id, GatewayProtocol::CMD_SEND_TO_ONE, $message); - } - - /** - * 向当前客户端连接发送消息 - * - * @param string $message - * @return bool - */ - public static function sendToCurrentClient($message) - { - return self::sendCmdAndMessageToClient(null, GatewayProtocol::CMD_SEND_TO_ONE, $message); - } - - /** - * 判断某个uid是否在线 - * - * @param string $uid - * @return int 0|1 - */ - public static function isUidOnline($uid) - { - return (int)self::getClientIdByUid($uid); - } - - /** - * 判断某个客户端连接是否在线 - * - * @param int $client_id - * @return int 0|1 - */ - public static function isOnline($client_id) - { - $address_data = Context::clientIdToAddress($client_id); - $address = long2ip($address_data['local_ip']) . ":{$address_data['local_port']}"; - if (isset(self::$businessWorker)) { - if (!isset(self::$businessWorker->gatewayConnections[$address])) { - return 0; - } - } - $gateway_data = GatewayProtocol::$empty; - $gateway_data['cmd'] = GatewayProtocol::CMD_IS_ONLINE; - $gateway_data['connection_id'] = $address_data['connection_id']; - return (int)self::sendAndRecv($address, $gateway_data); - } - - /** - * 获取在线状态,目前返回一个在线 client_id 数组,client_id为 key - * - * @param string $group - * @return array - */ - public static function getAllClientInfo($group = null) - { - $gateway_data = GatewayProtocol::$empty; - if (!$group) { - $gateway_data['cmd'] = GatewayProtocol::CMD_GET_ALL_CLIENT_INFO; - } else { - $gateway_data['cmd'] = GatewayProtocol::CMD_GET_CLINET_INFO_BY_GROUP; - $gateway_data['ext_data'] = $group; - } - $status_data = array(); - $all_buffer_array = self::getBufferFromAllGateway($gateway_data); - foreach ($all_buffer_array as $local_ip => $buffer_array) { - foreach ($buffer_array as $local_port => $data) { - if ($data) { - foreach ($data as $connection_id => $session_buffer) { - $client_id = Context::addressToClientId($local_ip, $local_port, $connection_id); - if ($client_id === Context::$client_id) { - $status_data[$client_id] = (array)$_SESSION; - } else { - $status_data[$client_id] = $session_buffer ? Context::sessionDecode($session_buffer) : array(); - } - } - } - } - } - return $status_data; - } - - /** - * 获取某个组的连接信息 - * - * @param string $group - * @return array - */ - public static function getClientInfoByGroup($group) - { - return self::getAllClientInfo($group); - } - - /** - * 获取所有连接数 - * - * @return int - */ - public static function getAllClientCount() - { - return self::getClientCountByGroup(); - } - - /** - * 获取某个组的在线连接数 - * - * @param string $group - * @return int - */ - public static function getClientCountByGroup($group = '') - { - $gateway_data = GatewayProtocol::$empty; - $gateway_data['cmd'] = GatewayProtocol::CMD_GET_CLIENT_COUNT_BY_GROUP; - $gateway_data['ext_data'] = $group; - $total_count = 0; - $all_buffer_array = self::getBufferFromAllGateway($gateway_data); - foreach ($all_buffer_array as $local_ip => $buffer_array) { - foreach ($buffer_array as $local_port => $count) { - if ($count) { - $total_count += $count; - } - } - } - return $total_count; - } - - /** - * 获取与 uid 绑定的 client_id 列表 - * - * @param string $uid - * @return array - */ - public static function getClientIdByUid($uid) - { - $gateway_data = GatewayProtocol::$empty; - $gateway_data['cmd'] = GatewayProtocol::CMD_GET_CLIENT_ID_BY_UID; - $gateway_data['ext_data'] = $uid; - $client_list = array(); - $all_buffer_array = self::getBufferFromAllGateway($gateway_data); - foreach ($all_buffer_array as $local_ip => $buffer_array) { - foreach ($buffer_array as $local_port => $connection_id_array) { - if ($connection_id_array) { - foreach ($connection_id_array as $connection_id) { - $client_list[] = Context::addressToClientId($local_ip, $local_port, $connection_id); - } - } - } - } - return $client_list; - } - - /** - * 生成验证包,用于验证此客户端的合法性 - * - * @return string - */ - protected static function generateAuthBuffer() - { - $gateway_data = GatewayProtocol::$empty; - $gateway_data['cmd'] = GatewayProtocol::CMD_GATEWAY_CLIENT_CONNECT; - $gateway_data['body'] = json_encode(array( - 'secret_key' => self::$secretKey, - )); - return GatewayProtocol::encode($gateway_data); - } - - /** - * 批量向所有 gateway 发包,并得到返回数组 - * - * @param string $gateway_data - * @return array - * @throws Exception - */ - protected static function getBufferFromAllGateway($gateway_data) - { - $gateway_buffer = GatewayProtocol::encode($gateway_data); - $gateway_buffer = self::$secretKey ? self::generateAuthBuffer() . $gateway_buffer : $gateway_buffer; - if (isset(self::$businessWorker)) { - $all_addresses = self::$businessWorker->getAllGatewayAddresses(); - if (empty($all_addresses)) { - throw new Exception('businessWorker::getAllGatewayAddresses return empty'); - } - } else { - $all_addresses = self::getAllGatewayAddressesFromRegister(); - if (empty($all_addresses)) { - return array(); - } - } - $client_array = $status_data = $client_address_map = $receive_buffer_array = $recv_length_array = array(); - // 批量向所有gateway进程发送请求数据 - foreach ($all_addresses as $address) { - $client = stream_socket_client("tcp://$address", $errno, $errmsg); - if ($client && strlen($gateway_buffer) === stream_socket_sendto($client, $gateway_buffer)) { - $socket_id = (int)$client; - $client_array[$socket_id] = $client; - $client_address_map[$socket_id] = explode(':', $address); - $receive_buffer_array[$socket_id] = ''; - } - } - // 超时1秒 - $timeout = 1; - $time_start = microtime(true); - // 批量接收请求 - while (count($client_array) > 0) { - $write = $except = array(); - $read = $client_array; - if (@stream_select($read, $write, $except, $timeout)) { - foreach ($read as $client) { - $socket_id = (int)$client; - $buffer = stream_socket_recvfrom($client, 65535); - if ($buffer !== '' && $buffer !== false) { - $receive_buffer_array[$socket_id] .= $buffer; - $receive_length = strlen($receive_buffer_array[$socket_id]); - if (empty($recv_length_array[$socket_id]) && $receive_length >= 4) { - $recv_length_array[$socket_id] = current(unpack('N', $receive_buffer_array[$socket_id])); - } - if (!empty($recv_length_array[$socket_id]) && $receive_length >= $recv_length_array[$socket_id] + 4) { - unset($client_array[$socket_id]); - } - } elseif (feof($client)) { - unset($client_array[$socket_id]); - } - } - } - if (microtime(true) - $time_start > $timeout) { - break; - } - } - $format_buffer_array = array(); - foreach ($receive_buffer_array as $socket_id => $buffer) { - $local_ip = ip2long($client_address_map[$socket_id][0]); - $local_port = $client_address_map[$socket_id][1]; - $format_buffer_array[$local_ip][$local_port] = unserialize(substr($buffer, 4)); - } - return $format_buffer_array; - } - - /** - * 关闭某个客户端 - * - * @param int $client_id - * @return bool - */ - public static function closeClient($client_id) - { - if ($client_id === Context::$client_id) { - return self::closeCurrentClient(); - } // 不是发给当前用户则使用存储中的地址 - else { - $address_data = Context::clientIdToAddress($client_id); - $address = long2ip($address_data['local_ip']) . ":{$address_data['local_port']}"; - return self::kickAddress($address, $address_data['connection_id']); - } - } - - /** - * 踢掉当前客户端 - * - * @return bool - * @throws Exception - */ - public static function closeCurrentClient() - { - if (!Context::$connection_id) { - throw new Exception('closeCurrentClient can not be called in async context'); - } - return self::kickAddress(long2ip(Context::$local_ip) . ':' . Context::$local_port, Context::$connection_id); - } - - /** - * 将 client_id 与 uid 绑定 - * - * @param int $client_id - * @param int|string $uid - * @return bool - */ - public static function bindUid($client_id, $uid) - { - return self::sendCmdAndMessageToClient($client_id, GatewayProtocol::CMD_BIND_UID, '', $uid); - } - - /** - * 将 client_id 与 uid 解除绑定 - * - * @param int $client_id - * @param int|string $uid - * @return bool - */ - public static function unbindUid($client_id, $uid) - { - return self::sendCmdAndMessageToClient($client_id, GatewayProtocol::CMD_UNBIND_UID, '', $uid); - } - - /** - * 将 client_id 加入组 - * - * @param int $client_id - * @param int|string $group - * @return bool - */ - public static function joinGroup($client_id, $group) - { - return self::sendCmdAndMessageToClient($client_id, GatewayProtocol::CMD_JOIN_GROUP, '', $group); - } - - /** - * 将 client_id 离开组 - * - * @param int $client_id - * @param int|string $group - * @return bool - */ - public static function leaveGroup($client_id, $group) - { - return self::sendCmdAndMessageToClient($client_id, GatewayProtocol::CMD_LEAVE_GROUP, '', $group); - } - - /** - * 向所有 uid 发送 - * - * @param int|string|array $uid - * @param string $message - */ - public static function sendToUid($uid, $message) - { - $gateway_data = GatewayProtocol::$empty; - $gateway_data['cmd'] = GatewayProtocol::CMD_SEND_TO_UID; - $gateway_data['body'] = $message; - - if (!is_array($uid)) { - $uid = array($uid); - } - - $gateway_data['ext_data'] = json_encode($uid); - - self::sendToAllGateway($gateway_data); - } - - /** - * 向 group 发送 - * - * @param int|string|array $group - * @param string $message - */ - public static function sendToGroup($group, $message) - { - $gateway_data = GatewayProtocol::$empty; - $gateway_data['cmd'] = GatewayProtocol::CMD_SEND_TO_GROUP; - $gateway_data['body'] = $message; - - if (!is_array($group)) { - $group = array($group); - } - - $gateway_data['ext_data'] = json_encode($group); - - self::sendToAllGateway($gateway_data); - } - - /** - * 更新 session,框架自动调用,开发者不要调用 - * - * @param int $client_id - * @param string $session_str - * @return bool - */ - public static function setSocketSession($client_id, $session_str) - { - return self::sendCmdAndMessageToClient($client_id, GatewayProtocol::CMD_SET_SESSION, '', $session_str); - } - - /** - * 设置 session,原session值会被覆盖 - * - * @param int $client_id - * @param array $session - */ - public static function setSession($client_id, array $session) - { - if (Context::$client_id === $client_id) { - $_SESSION = $session; - Context::$old_session = $_SESSION; - } - return self::setSocketSession($client_id, Context::sessionEncode($session)); - } - - /** - * 更新 session,实际上是与老的session合并 - * - * @param int $client_id - * @param array $session - */ - public static function updateSession($client_id, array $session) - { - if (Context::$client_id === $client_id) { - $_SESSION = $session + (array)$_SESSION; - Context::$old_session = $_SESSION; - } - return self::sendCmdAndMessageToClient($client_id, GatewayProtocol::CMD_UPDATE_SESSION, '', Context::sessionEncode($session)); - } - - /** - * 获取某个client_id的session - * - * @param int $client_id - * @return mixed false表示出错、null表示用户不存在、array表示具体的session信息 - */ - public static function getSession($client_id) - { - $address_data = Context::clientIdToAddress($client_id); - $address = long2ip($address_data['local_ip']) . ":{$address_data['local_port']}"; - if (isset(self::$businessWorker)) { - if (!isset(self::$businessWorker->gatewayConnections[$address])) { - return null; - } - } - $gateway_data = GatewayProtocol::$empty; - $gateway_data['cmd'] = GatewayProtocol::CMD_GET_SESSION_BY_CLIENT_ID; - $gateway_data['connection_id'] = $address_data['connection_id']; - return self::sendAndRecv($address, $gateway_data); - } - - /** - * 想某个用户网关发送命令和消息 - * - * @param int $client_id - * @param int $cmd - * @param string $message - * @param string $ext_data - * @return boolean - */ - protected static function sendCmdAndMessageToClient($client_id, $cmd, $message, $ext_data = '') - { - // 如果是发给当前用户则直接获取上下文中的地址 - if ($client_id === Context::$client_id || $client_id === null) { - $address = long2ip(Context::$local_ip) . ':' . Context::$local_port; - $connection_id = Context::$connection_id; - } else { - $address_data = Context::clientIdToAddress($client_id); - $address = long2ip($address_data['local_ip']) . ":{$address_data['local_port']}"; - $connection_id = $address_data['connection_id']; - } - $gateway_data = GatewayProtocol::$empty; - $gateway_data['cmd'] = $cmd; - $gateway_data['connection_id'] = $connection_id; - $gateway_data['body'] = $message; - if (!empty($ext_data)) { - $gateway_data['ext_data'] = $ext_data; - } - - return self::sendToGateway($address, $gateway_data); - } - - /** - * 发送数据并返回 - * - * @param int $address - * @param mixed $data - * @return bool - * @throws Exception - */ - protected static function sendAndRecv($address, $data) - { - $buffer = GatewayProtocol::encode($data); - $buffer = self::$secretKey ? self::generateAuthBuffer() . $buffer : $buffer; - $client = stream_socket_client("tcp://$address", $errno, $errmsg); - if (!$client) { - throw new Exception("can not connect to tcp://$address $errmsg"); - } - if (strlen($buffer) === stream_socket_sendto($client, $buffer)) { - $timeout = 1; - // 阻塞读 - stream_set_blocking($client, 1); - // 1秒超时 - stream_set_timeout($client, 1); - $all_buffer = ''; - $time_start = microtime(true); - $pack_len = 0; - while (1) { - $buf = stream_socket_recvfrom($client, 655350); - if ($buf !== '' && $buf !== false) { - $all_buffer .= $buf; - } else { - if (feof($client)) { - throw new Exception("connection close tcp://$address"); - } elseif (microtime(true) - $time_start > $timeout) { - break; - } - continue; - } - $recv_len = strlen($all_buffer); - if (!$pack_len && $recv_len >= 4) { - $pack_len= current(unpack('N', $all_buffer)); - } - // 回复的数据都是以\n结尾 - if (($pack_len && $recv_len >= $pack_len + 4) || microtime(true) - $time_start > $timeout) { - break; - } - } - // 返回结果 - return unserialize(substr($all_buffer, 4)); - } else { - throw new Exception("sendAndRecv($address, \$bufer) fail ! Can not send data!", 502); - } - } - - /** - * 发送数据到网关 - * - * @param string $address - * @param mixed $gateway_data - * @return bool - */ - protected static function sendToGateway($address, $gateway_data) - { - // 有$businessWorker说明是workerman环境,使用$businessWorker发送数据 - if (self::$businessWorker) { - if (!isset(self::$businessWorker->gatewayConnections[$address])) { - return false; - } - return self::$businessWorker->gatewayConnections[$address]->send($gateway_data); - } - // 非workerman环境 - $gateway_buffer = GatewayProtocol::encode($gateway_data); - $gateway_buffer = self::$secretKey ? self::generateAuthBuffer() . $gateway_buffer : $gateway_buffer; - $client = stream_socket_client("tcp://$address", $errno, $errmsg); - return strlen($gateway_buffer) == stream_socket_sendto($client, $gateway_buffer); - } - - /** - * 向所有 gateway 发送数据 - * - * @param string $gateway_data - * @throws Exception - */ - protected static function sendToAllGateway($gateway_data) - { - // 如果有businessWorker实例,说明运行在workerman环境中,通过businessWorker中的长连接发送数据 - if (self::$businessWorker) { - foreach (self::$businessWorker->gatewayConnections as $gateway_connection) { - /** @var TcpConnection $gateway_connection */ - $gateway_connection->send($gateway_data); - } - } // 运行在其它环境中,通过注册中心得到gateway地址 - else { - $all_addresses = self::getAllGatewayAddressesFromRegister(); - if (!$all_addresses) { - throw new Exception('Gateway::getAllGatewayAddressesFromRegister() with registerAddress:' . - self::$registerAddress . ' return ' . var_export($all_addresses, true)); - } - foreach ($all_addresses as $address) { - self::sendToGateway($address, $gateway_data); - } - } - } - - /** - * 踢掉某个网关的 socket - * - * @param string $address - * @param int $connection_id - * @return bool - */ - protected static function kickAddress($address, $connection_id) - { - $gateway_data = GatewayProtocol::$empty; - $gateway_data['cmd'] = GatewayProtocol::CMD_KICK; - $gateway_data['connection_id'] = $connection_id; - return self::sendToGateway($address, $gateway_data); - } - - /** - * 设置 gateway 实例 - * - * @param \GatewayWorker\BusinessWorker $business_worker_instance - */ - public static function setBusinessWorker($business_worker_instance) - { - self::$businessWorker = $business_worker_instance; - } - - /** - * 获取通过注册中心获取所有 gateway 通讯地址 - * - * @return array - * @throws Exception - */ - protected static function getAllGatewayAddressesFromRegister() - { - $client = stream_socket_client('tcp://' . self::$registerAddress, $errno, $errmsg, 1); - if (!$client) { - throw new Exception('Can not connect to tcp://' . self::$registerAddress . ' ' . $errmsg); - } - fwrite($client, '{"event":"worker_connect","secret_key":"' . self::$secretKey . '"}' . "\n"); - stream_set_timeout($client, 1); - $ret = fgets($client, 65535); - if (!$ret || !$data = json_decode(trim($ret), true)) { - throw new Exception('getAllGatewayAddressesFromRegister fail. tcp://' . - self::$registerAddress . ' return ' . var_export($ret, true)); - } - return $data['addresses']; - } -} - -if (!class_exists('\Protocols\GatewayProtocol')) { - class_alias('GatewayWorker\Protocols\GatewayProtocol', 'Protocols\GatewayProtocol'); -} diff --git a/GatewayWorker/Lib/Mem.php b/GatewayWorker/Lib/Mem.php deleted file mode 100644 index cbbfb18..0000000 --- a/GatewayWorker/Lib/Mem.php +++ /dev/null @@ -1,56 +0,0 @@ -connect(static::$config['mem_host'], static::$config['mem_port']); - } catch(\Exception $e) { } - } - - public static function __callStatic($method, $params) - { - if (!static::$instance) { - self::init(); - } - try { - $ret = call_user_func_array(array(static::$instance, $method),$params); - return $ret; - } catch(\Exception $e) { - echo $e->getMessage(); - } - } -} \ No newline at end of file diff --git a/GatewayWorker/Protocols/GatewayProtocol.php b/GatewayWorker/Protocols/GatewayProtocol.php deleted file mode 100644 index 80ad505..0000000 --- a/GatewayWorker/Protocols/GatewayProtocol.php +++ /dev/null @@ -1,195 +0,0 @@ - - * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -namespace GatewayWorker\Protocols; - -/** - * Gateway 与 Worker 间通讯的二进制协议 - * - * struct GatewayProtocol - * { - * unsigned int pack_len, - * unsigned char cmd,//命令字 - * unsigned int local_ip, - * unsigned short local_port, - * unsigned int client_ip, - * unsigned short client_port, - * unsigned int connection_id, - * unsigned char flag, - * unsigned short gateway_port, - * unsigned int ext_len, - * char[ext_len] ext_data, - * char[pack_length-HEAD_LEN] body//包体 - * } - * NCNnNnNCnN - */ -class GatewayProtocol -{ - // 发给worker,gateway有一个新的连接 - const CMD_ON_CONNECTION = 1; - - // 发给worker的,客户端有消息 - const CMD_ON_MESSAGE = 3; - - // 发给worker上的关闭链接事件 - const CMD_ON_CLOSE = 4; - - // 发给gateway的向单个用户发送数据 - const CMD_SEND_TO_ONE = 5; - - // 发给gateway的向所有用户发送数据 - const CMD_SEND_TO_ALL = 6; - - // 发给gateway的踢出用户 - const CMD_KICK = 7; - - // 发给gateway,通知用户session更新 - const CMD_UPDATE_SESSION = 9; - - // 获取在线状态 - const CMD_GET_ALL_CLIENT_INFO = 10; - - // 判断是否在线 - const CMD_IS_ONLINE = 11; - - // client_id绑定到uid - const CMD_BIND_UID = 12; - - // 解绑 - const CMD_UNBIND_UID = 13; - - // 向uid发送数据 - const CMD_SEND_TO_UID = 14; - - // 根据uid获取绑定的clientid - const CMD_GET_CLIENT_ID_BY_UID = 15; - - // 加入组 - const CMD_JOIN_GROUP = 20; - - // 离开组 - const CMD_LEAVE_GROUP = 21; - - // 向组成员发消息 - const CMD_SEND_TO_GROUP = 22; - - // 获取组成员 - const CMD_GET_CLINET_INFO_BY_GROUP = 23; - - // 获取组成员数 - const CMD_GET_CLIENT_COUNT_BY_GROUP = 24; - - // worker连接gateway事件 - const CMD_WORKER_CONNECT = 200; - - // 心跳 - const CMD_PING = 201; - - // GatewayClient连接gateway事件 - const CMD_GATEWAY_CLIENT_CONNECT = 202; - - // 根据client_id获取session - const CMD_GET_SESSION_BY_CLIENT_ID = 203; - - // 发给gateway,覆盖session - const CMD_SET_SESSION = 204; - - // 包体是标量 - const FLAG_BODY_IS_SCALAR = 0x01; - - /** - * 包头长度 - * - * @var int - */ - const HEAD_LEN = 28; - - public static $empty = array( - 'cmd' => 0, - 'local_ip' => 0, - 'local_port' => 0, - 'client_ip' => 0, - 'client_port' => 0, - 'connection_id' => 0, - 'flag' => 0, - 'gateway_port' => 0, - 'ext_data' => '', - 'body' => '', - ); - - /** - * 返回包长度 - * - * @param string $buffer - * @return int return current package length - */ - public static function input($buffer) - { - if (strlen($buffer) < self::HEAD_LEN) { - return 0; - } - - $data = unpack("Npack_len", $buffer); - return $data['pack_len']; - } - - /** - * 获取整个包的 buffer - * - * @param mixed $data - * @return string - */ - public static function encode($data) - { - $flag = (int)is_scalar($data['body']); - if (!$flag) { - $data['body'] = serialize($data['body']); - } - $ext_len = strlen($data['ext_data']); - $package_len = self::HEAD_LEN + $ext_len + strlen($data['body']); - return pack("NCNnNnNCnN", $package_len, - $data['cmd'], $data['local_ip'], - $data['local_port'], $data['client_ip'], - $data['client_port'], $data['connection_id'], - $flag, $data['gateway_port'], - $ext_len) . $data['ext_data'] . $data['body']; - } - - /** - * 从二进制数据转换为数组 - * - * @param string $buffer - * @return array - */ - public static function decode($buffer) - { - $data = unpack("Npack_len/Ccmd/Nlocal_ip/nlocal_port/Nclient_ip/nclient_port/Nconnection_id/Cflag/ngateway_port/Next_len", - $buffer); - if ($data['ext_len'] > 0) { - $data['ext_data'] = substr($buffer, self::HEAD_LEN, $data['ext_len']); - if ($data['flag'] & self::FLAG_BODY_IS_SCALAR) { - $data['body'] = substr($buffer, self::HEAD_LEN + $data['ext_len']); - } else { - $data['body'] = unserialize(substr($buffer, self::HEAD_LEN + $data['ext_len'])); - } - } else { - $data['ext_data'] = ''; - if ($data['flag'] & self::FLAG_BODY_IS_SCALAR) { - $data['body'] = substr($buffer, self::HEAD_LEN); - } else { - $data['body'] = unserialize(substr($buffer, self::HEAD_LEN)); - } - } - return $data; - } -} diff --git a/GatewayWorker/Register.php b/GatewayWorker/Register.php deleted file mode 100644 index c7977e1..0000000 --- a/GatewayWorker/Register.php +++ /dev/null @@ -1,182 +0,0 @@ - - * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ -namespace GatewayWorker; - -use Workerman\Worker; -use Workerman\Lib\Timer; - -/** - * - * 注册中心,用于注册 Gateway 和 BusinessWorker - * - * @author walkor - * - */ -class Register extends Worker -{ - /** - * {@inheritdoc} - */ - public $name = 'Register'; - - /** - * {@inheritdoc} - */ - public $reloadable = false; - - /** - * 秘钥 - * @var string - */ - public $secretKey = ''; - - /** - * 所有 gateway 的连接 - * - * @var array - */ - protected $_gatewayConnections = array(); - - /** - * 所有 worker 的连接 - * - * @var array - */ - protected $_workerConnections = array(); - - /** - * 进程启动时间 - * - * @var int - */ - protected $_startTime = 0; - - /** - * {@inheritdoc} - */ - public function run() - { - // 设置 onMessage 连接回调 - $this->onConnect = array($this, 'onConnect'); - - // 设置 onMessage 回调 - $this->onMessage = array($this, 'onMessage'); - - // 设置 onClose 回调 - $this->onClose = array($this, 'onClose'); - - // 记录进程启动的时间 - $this->_startTime = time(); - - // 运行父方法 - parent::run(); - } - - /** - * 设置个定时器,将未及时发送验证的连接关闭 - * - * @param \Workerman\Connection\ConnectionInterface $connection - * @return void - */ - public function onConnect($connection) - { - $connection->timeout_timerid = Timer::add(10, function () use ($connection) { - echo "auth timeout\n"; - $connection->close(); - }, null, false); - } - - /** - * 设置消息回调 - * - * @param \Workerman\Connection\ConnectionInterface $connection - * @param string $data - * @return void - */ - public function onMessage($connection, $data) - { - // 删除定时器 - Timer::del($connection->timeout_timerid); - $data = json_decode($data, true); - $event = $data['event']; - $secret_key = isset($data['secret_key']) ? $data['secret_key'] : ''; - // 开始验证 - switch ($event) { - // 是 gateway 连接 - case 'gateway_connect': - if (empty($data['address'])) { - echo "address not found\n"; - return $connection->close(); - } - if ($secret_key !== $this->secretKey) { - echo "Register: Key does not match $secret_key !== {$this->secretKey}\n"; - return $connection->close(); - } - $this->_gatewayConnections[$connection->id] = $data['address']; - $this->broadcastAddresses(); - break; - // 是 worker 连接 - case 'worker_connect': - if ($secret_key !== $this->secretKey) { - echo "Register: Key does not match $secret_key !== {$this->secretKey}\n"; - return $connection->close(); - } - $this->_workerConnections[$connection->id] = $connection; - $this->broadcastAddresses($connection); - break; - case 'ping': - break; - default: - echo "unknown event $event\n"; - $connection->close(); - } - } - - /** - * 连接关闭时 - * - * @param \Workerman\Connection\ConnectionInterface $connection - */ - public function onClose($connection) - { - if (isset($this->_gatewayConnections[$connection->id])) { - unset($this->_gatewayConnections[$connection->id]); - $this->broadcastAddresses(); - } - if (isset($this->_workerConnections[$connection->id])) { - unset($this->_workerConnections[$connection->id]); - } - } - - /** - * 向 BusinessWorker 广播 gateway 内部通讯地址 - * - * @param \Workerman\Connection\ConnectionInterface $connection - */ - public function broadcastAddresses($connection = null) - { - $data = array( - 'event' => 'broadcast_addresses', - 'addresses' => array_unique(array_values($this->_gatewayConnections)), - ); - $buffer = json_encode($data); - if ($connection) { - $connection->send($buffer); - return; - } - foreach ($this->_workerConnections as $con) { - $con->send($buffer); - } - } -} diff --git a/README.md b/README.md deleted file mode 100644 index 6ce0237..0000000 --- a/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# websocket -一个 PHP 的 websocket 的聊天室 - -具体设计可查看:[网页实时聊天之PHP实现websocket](http://www.cnblogs.com/zhenbianshu/p/6111257.html) diff --git a/Workerman b/Workerman deleted file mode 160000 index a1b5ac8..0000000 --- a/Workerman +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a1b5ac89441e20576cababecd08d955e18f5e59a diff --git a/_alidata_www_ChatRoomDemo_start.php.pid b/_alidata_www_ChatRoomDemo_start.php.pid deleted file mode 100644 index 6b02480..0000000 --- a/_alidata_www_ChatRoomDemo_start.php.pid +++ /dev/null @@ -1 +0,0 @@ -6377 \ No newline at end of file diff --git a/client.html b/client.html deleted file mode 100644 index e20e316..0000000 --- a/client.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - - - -
-

websocket聊天室

-
-
-

当前在线:0

-
- -
-
-
-
-
-
-
- -
- - - - \ No newline at end of file diff --git a/html/LICENSE b/html/LICENSE deleted file mode 100644 index 8dada3e..0000000 --- a/html/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/html/README.md b/html/README.md deleted file mode 100644 index 0f00e3d..0000000 --- a/html/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# HappyChat -又一个php实现的聊天室 -目前为最初版本。有如下功能: -1. 上线通知 -2. 下线通知 -3. 群聊 - -# 依赖 -需要php开启 socket 扩展,php 版本 大于 5.4, 浏览器 支持 websocket,localstorage   - -# 运行方法 -1.在cmd下执行 index.php 文件 -2.浏览器打开 index.html,打开多个浏览器即可实现群聊 diff --git a/html/favicon.ico b/html/favicon.ico deleted file mode 100644 index de1c1c2..0000000 Binary files a/html/favicon.ico and /dev/null differ diff --git a/html/index.html b/html/index.html deleted file mode 100644 index a9c9556..0000000 --- a/html/index.html +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - 快乐聊天室 - - - - - - - - -
-
-
-
-
-
- 退出 - 聊天窗口 -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/html/static/css/animate.min.css b/html/static/css/animate.min.css deleted file mode 100644 index 81b04ee..0000000 --- a/html/static/css/animate.min.css +++ /dev/null @@ -1,12 +0,0 @@ -@charset "UTF-8";/*! -Animate.css - http://daneden.me/animate -Licensed under the MIT license - -Copyright (c) 2013 Daniel Eden - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both;z-index:100}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}@-webkit-keyframes bounce{0%,100%,20%,50%,80%{-webkit-transform:translateY(0);transform:translateY(0)}40%{-webkit-transform:translateY(-30px);transform:translateY(-30px)}60%{-webkit-transform:translateY(-15px);transform:translateY(-15px)}}@keyframes bounce{0%,100%,20%,50%,80%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}40%{-webkit-transform:translateY(-30px);-ms-transform:translateY(-30px);transform:translateY(-30px)}60%{-webkit-transform:translateY(-15px);-ms-transform:translateY(-15px);transform:translateY(-15px)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce}@-webkit-keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scale(1);transform:scale(1)}50%{-webkit-transform:scale(1.1);transform:scale(1.1)}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes pulse{0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}50%{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{0%{-webkit-transform:scale(1);transform:scale(1)}30%{-webkit-transform:scaleX(1.25) scaleY(0.75);transform:scaleX(1.25) scaleY(0.75)}40%{-webkit-transform:scaleX(0.75) scaleY(1.25);transform:scaleX(0.75) scaleY(1.25)}60%{-webkit-transform:scaleX(1.15) scaleY(0.85);transform:scaleX(1.15) scaleY(0.85)}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes rubberBand{0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}30%{-webkit-transform:scaleX(1.25) scaleY(0.75);-ms-transform:scaleX(1.25) scaleY(0.75);transform:scaleX(1.25) scaleY(0.75)}40%{-webkit-transform:scaleX(0.75) scaleY(1.25);-ms-transform:scaleX(0.75) scaleY(1.25);transform:scaleX(0.75) scaleY(1.25)}60%{-webkit-transform:scaleX(1.15) scaleY(0.85);-ms-transform:scaleX(1.15) scaleY(0.85);transform:scaleX(1.15) scaleY(0.85)}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}100%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes swing{20%{-webkit-transform:rotate(15deg);-ms-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);-ms-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);-ms-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);-ms-transform:rotate(-5deg);transform:rotate(-5deg)}100%{-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg)}}.swing{-webkit-transform-origin:top center;-ms-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{0%{-webkit-transform:scale(1);transform:scale(1)}10%,20%{-webkit-transform:scale(0.9) rotate(-3deg);transform:scale(0.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale(1.1) rotate(3deg);transform:scale(1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale(1.1) rotate(-3deg);transform:scale(1.1) rotate(-3deg)}100%{-webkit-transform:scale(1) rotate(0);transform:scale(1) rotate(0)}}@keyframes tada{0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}10%,20%{-webkit-transform:scale(0.9) rotate(-3deg);-ms-transform:scale(0.9) rotate(-3deg);transform:scale(0.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale(1.1) rotate(3deg);-ms-transform:scale(1.1) rotate(3deg);transform:scale(1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale(1.1) rotate(-3deg);-ms-transform:scale(1.1) rotate(-3deg);transform:scale(1.1) rotate(-3deg)}100%{-webkit-transform:scale(1) rotate(0);-ms-transform:scale(1) rotate(0);transform:scale(1) rotate(0)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:translateX(0%);transform:translateX(0%)}15%{-webkit-transform:translateX(-25%) rotate(-5deg);transform:translateX(-25%) rotate(-5deg)}30%{-webkit-transform:translateX(20%) rotate(3deg);transform:translateX(20%) rotate(3deg)}45%{-webkit-transform:translateX(-15%) rotate(-3deg);transform:translateX(-15%) rotate(-3deg)}60%{-webkit-transform:translateX(10%) rotate(2deg);transform:translateX(10%) rotate(2deg)}75%{-webkit-transform:translateX(-5%) rotate(-1deg);transform:translateX(-5%) rotate(-1deg)}100%{-webkit-transform:translateX(0%);transform:translateX(0%)}}@keyframes wobble{0%{-webkit-transform:translateX(0%);-ms-transform:translateX(0%);transform:translateX(0%)}15%{-webkit-transform:translateX(-25%) rotate(-5deg);-ms-transform:translateX(-25%) rotate(-5deg);transform:translateX(-25%) rotate(-5deg)}30%{-webkit-transform:translateX(20%) rotate(3deg);-ms-transform:translateX(20%) rotate(3deg);transform:translateX(20%) rotate(3deg)}45%{-webkit-transform:translateX(-15%) rotate(-3deg);-ms-transform:translateX(-15%) rotate(-3deg);transform:translateX(-15%) rotate(-3deg)}60%{-webkit-transform:translateX(10%) rotate(2deg);-ms-transform:translateX(10%) rotate(2deg);transform:translateX(10%) rotate(2deg)}75%{-webkit-transform:translateX(-5%) rotate(-1deg);-ms-transform:translateX(-5%) rotate(-1deg);transform:translateX(-5%) rotate(-1deg)}100%{-webkit-transform:translateX(0%);-ms-transform:translateX(0%);transform:translateX(0%)}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.3);transform:scale(.3)}50%{opacity:1;-webkit-transform:scale(1.05);transform:scale(1.05)}70%{-webkit-transform:scale(.9);transform:scale(.9)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.3);-ms-transform:scale(.3);transform:scale(.3)}50%{opacity:1;-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}70%{-webkit-transform:scale(.9);-ms-transform:scale(.9);transform:scale(.9)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}60%{opacity:1;-webkit-transform:translateY(30px);transform:translateY(30px)}80%{-webkit-transform:translateY(-10px);transform:translateY(-10px)}100%{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes bounceInDown{0%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}60%{opacity:1;-webkit-transform:translateY(30px);-ms-transform:translateY(30px);transform:translateY(30px)}80%{-webkit-transform:translateY(-10px);-ms-transform:translateY(-10px);transform:translateY(-10px)}100%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}60%{opacity:1;-webkit-transform:translateX(30px);transform:translateX(30px)}80%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes bounceInLeft{0%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}60%{opacity:1;-webkit-transform:translateX(30px);-ms-transform:translateX(30px);transform:translateX(30px)}80%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}60%{opacity:1;-webkit-transform:translateX(-30px);transform:translateX(-30px)}80%{-webkit-transform:translateX(10px);transform:translateX(10px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes bounceInRight{0%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}60%{opacity:1;-webkit-transform:translateX(-30px);-ms-transform:translateX(-30px);transform:translateX(-30px)}80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}60%{opacity:1;-webkit-transform:translateY(-30px);transform:translateY(-30px)}80%{-webkit-transform:translateY(10px);transform:translateY(10px)}100%{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes bounceInUp{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}60%{opacity:1;-webkit-transform:translateY(-30px);-ms-transform:translateY(-30px);transform:translateY(-30px)}80%{-webkit-transform:translateY(10px);-ms-transform:translateY(10px);transform:translateY(10px)}100%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{0%{-webkit-transform:scale(1);transform:scale(1)}25%{-webkit-transform:scale(.95);transform:scale(.95)}50%{opacity:1;-webkit-transform:scale(1.1);transform:scale(1.1)}100%{opacity:0;-webkit-transform:scale(.3);transform:scale(.3)}}@keyframes bounceOut{0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}25%{-webkit-transform:scale(.95);-ms-transform:scale(.95);transform:scale(.95)}50%{opacity:1;-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}100%{opacity:0;-webkit-transform:scale(.3);-ms-transform:scale(.3);transform:scale(.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{0%{-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(-20px);transform:translateY(-20px)}100%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}}@keyframes bounceOutDown{0%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px)}100%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{0%{-webkit-transform:translateX(0);transform:translateX(0)}20%{opacity:1;-webkit-transform:translateX(20px);transform:translateX(20px)}100%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}}@keyframes bounceOutLeft{0%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}20%{opacity:1;-webkit-transform:translateX(20px);-ms-transform:translateX(20px);transform:translateX(20px)}100%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{0%{-webkit-transform:translateX(0);transform:translateX(0)}20%{opacity:1;-webkit-transform:translateX(-20px);transform:translateX(-20px)}100%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}}@keyframes bounceOutRight{0%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}20%{opacity:1;-webkit-transform:translateX(-20px);-ms-transform:translateX(-20px);transform:translateX(-20px)}100%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{0%{-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(20px);transform:translateY(20px)}100%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}}@keyframes bounceOutUp{0%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(20px);-ms-transform:translateY(20px);transform:translateY(20px)}100%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-20px);transform:translateY(-20px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(-20px);transform:translateX(-20px)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(-20px);-ms-transform:translateX(-20px);transform:translateX(-20px)}100%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}100%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(20px);transform:translateX(20px)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(40px);-ms-transform:translateX(40px);transform:translateX(40px)}100%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}100%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(20px);transform:translateY(20px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(20px);-ms-transform:translateY(20px);transform:translateY(20px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(20px);transform:translateY(20px)}}@keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(20px);-ms-transform:translateY(20px);transform:translateY(20px)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}}@keyframes fadeOutDownBig{0%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-20px);transform:translateX(-20px)}}@keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-20px);-ms-transform:translateX(-20px);transform:translateX(-20px)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}}@keyframes fadeOutLeftBig{0%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(20px);transform:translateX(20px)}}@keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(20px);-ms-transform:translateX(20px);transform:translateX(20px)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}}@keyframes fadeOutRightBig{0%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-20px);transform:translateY(-20px)}}@keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}}@keyframes fadeOutUpBig{0%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px) translateZ(0) rotateY(0) scale(1);transform:perspective(400px) translateZ(0) rotateY(0) scale(1);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(170deg) scale(1);transform:perspective(400px) translateZ(150px) rotateY(170deg) scale(1);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(190deg) scale(1);transform:perspective(400px) translateZ(150px) rotateY(190deg) scale(1);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) translateZ(0) rotateY(360deg) scale(.95);transform:perspective(400px) translateZ(0) rotateY(360deg) scale(.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px) translateZ(0) rotateY(360deg) scale(1);transform:perspective(400px) translateZ(0) rotateY(360deg) scale(1);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{0%{-webkit-transform:perspective(400px) translateZ(0) rotateY(0) scale(1);-ms-transform:perspective(400px) translateZ(0) rotateY(0) scale(1);transform:perspective(400px) translateZ(0) rotateY(0) scale(1);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(170deg) scale(1);-ms-transform:perspective(400px) translateZ(150px) rotateY(170deg) scale(1);transform:perspective(400px) translateZ(150px) rotateY(170deg) scale(1);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(190deg) scale(1);-ms-transform:perspective(400px) translateZ(150px) rotateY(190deg) scale(1);transform:perspective(400px) translateZ(150px) rotateY(190deg) scale(1);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) translateZ(0) rotateY(360deg) scale(.95);-ms-transform:perspective(400px) translateZ(0) rotateY(360deg) scale(.95);transform:perspective(400px) translateZ(0) rotateY(360deg) scale(.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px) translateZ(0) rotateY(360deg) scale(1);-ms-transform:perspective(400px) translateZ(0) rotateY(360deg) scale(1);transform:perspective(400px) translateZ(0) rotateY(360deg) scale(1);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;-ms-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotateX(-10deg);transform:perspective(400px) rotateX(-10deg)}70%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg)}100%{-webkit-transform:perspective(400px) rotateX(0deg);transform:perspective(400px) rotateX(0deg);opacity:1}}@keyframes flipInX{0%{-webkit-transform:perspective(400px) rotateX(90deg);-ms-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotateX(-10deg);-ms-transform:perspective(400px) rotateX(-10deg);transform:perspective(400px) rotateX(-10deg)}70%{-webkit-transform:perspective(400px) rotateX(10deg);-ms-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg)}100%{-webkit-transform:perspective(400px) rotateX(0deg);-ms-transform:perspective(400px) rotateX(0deg);transform:perspective(400px) rotateX(0deg);opacity:1}}.flipInX{-webkit-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{0%{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotateY(-10deg);transform:perspective(400px) rotateY(-10deg)}70%{-webkit-transform:perspective(400px) rotateY(10deg);transform:perspective(400px) rotateY(10deg)}100%{-webkit-transform:perspective(400px) rotateY(0deg);transform:perspective(400px) rotateY(0deg);opacity:1}}@keyframes flipInY{0%{-webkit-transform:perspective(400px) rotateY(90deg);-ms-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}40%{-webkit-transform:perspective(400px) rotateY(-10deg);-ms-transform:perspective(400px) rotateY(-10deg);transform:perspective(400px) rotateY(-10deg)}70%{-webkit-transform:perspective(400px) rotateY(10deg);-ms-transform:perspective(400px) rotateY(10deg);transform:perspective(400px) rotateY(10deg)}100%{-webkit-transform:perspective(400px) rotateY(0deg);-ms-transform:perspective(400px) rotateY(0deg);transform:perspective(400px) rotateY(0deg);opacity:1}}.flipInY{-webkit-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px) rotateX(0deg);transform:perspective(400px) rotateX(0deg);opacity:1}100%{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px) rotateX(0deg);-ms-transform:perspective(400px) rotateX(0deg);transform:perspective(400px) rotateX(0deg);opacity:1}100%{-webkit-transform:perspective(400px) rotateX(90deg);-ms-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px) rotateY(0deg);transform:perspective(400px) rotateY(0deg);opacity:1}100%{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px) rotateY(0deg);-ms-transform:perspective(400px) rotateY(0deg);transform:perspective(400px) rotateY(0deg);opacity:1}100%{-webkit-transform:perspective(400px) rotateY(90deg);-ms-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translateX(100%) skewX(-30deg);transform:translateX(100%) skewX(-30deg);opacity:0}60%{-webkit-transform:translateX(-20%) skewX(30deg);transform:translateX(-20%) skewX(30deg);opacity:1}80%{-webkit-transform:translateX(0%) skewX(-15deg);transform:translateX(0%) skewX(-15deg);opacity:1}100%{-webkit-transform:translateX(0%) skewX(0deg);transform:translateX(0%) skewX(0deg);opacity:1}}@keyframes lightSpeedIn{0%{-webkit-transform:translateX(100%) skewX(-30deg);-ms-transform:translateX(100%) skewX(-30deg);transform:translateX(100%) skewX(-30deg);opacity:0}60%{-webkit-transform:translateX(-20%) skewX(30deg);-ms-transform:translateX(-20%) skewX(30deg);transform:translateX(-20%) skewX(30deg);opacity:1}80%{-webkit-transform:translateX(0%) skewX(-15deg);-ms-transform:translateX(0%) skewX(-15deg);transform:translateX(0%) skewX(-15deg);opacity:1}100%{-webkit-transform:translateX(0%) skewX(0deg);-ms-transform:translateX(0%) skewX(0deg);transform:translateX(0%) skewX(0deg);opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{-webkit-transform:translateX(0%) skewX(0deg);transform:translateX(0%) skewX(0deg);opacity:1}100%{-webkit-transform:translateX(100%) skewX(-30deg);transform:translateX(100%) skewX(-30deg);opacity:0}}@keyframes lightSpeedOut{0%{-webkit-transform:translateX(0%) skewX(0deg);-ms-transform:translateX(0%) skewX(0deg);transform:translateX(0%) skewX(0deg);opacity:1}100%{-webkit-transform:translateX(100%) skewX(-30deg);-ms-transform:translateX(100%) skewX(-30deg);transform:translateX(100%) skewX(-30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{-webkit-transform-origin:center center;transform-origin:center center;-webkit-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}100%{-webkit-transform-origin:center center;transform-origin:center center;-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateIn{0%{-webkit-transform-origin:center center;-ms-transform-origin:center center;transform-origin:center center;-webkit-transform:rotate(-200deg);-ms-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}100%{-webkit-transform-origin:center center;-ms-transform-origin:center center;transform-origin:center center;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);opacity:0}100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);opacity:0}100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{-webkit-transform-origin:center center;transform-origin:center center;-webkit-transform:rotate(0);transform:rotate(0);opacity:1}100%{-webkit-transform-origin:center center;transform-origin:center center;-webkit-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}@keyframes rotateOut{0%{-webkit-transform-origin:center center;-ms-transform-origin:center center;transform-origin:center center;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}100%{-webkit-transform-origin:center center;-ms-transform-origin:center center;transform-origin:center center;-webkit-transform:rotate(200deg);-ms-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(0);transform:rotate(0);opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}@keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(0);transform:rotate(0);opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}}@keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(0);transform:rotate(0);opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}}@keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(0);transform:rotate(0);opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}@keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes slideInDown{0%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}100%{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes slideInDown{0%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}100%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInLeft{0%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInRight{0%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}}@keyframes slideOutLeft{0%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}}@keyframes slideOutRight{0%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}}@keyframes slideOutUp{0%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}}@keyframes slideOutDown{0%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes hinge{0%{-webkit-transform:rotate(0);transform:rotate(0);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);transform:rotate(80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%{-webkit-transform:rotate(60deg);transform:rotate(60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}80%{-webkit-transform:rotate(60deg) translateY(0);transform:rotate(60deg) translateY(0);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translateY(700px);transform:translateY(700px);opacity:0}}@keyframes hinge{0%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);-webkit-transform-origin:top left;-ms-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);-ms-transform:rotate(80deg);transform:rotate(80deg);-webkit-transform-origin:top left;-ms-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%{-webkit-transform:rotate(60deg);-ms-transform:rotate(60deg);transform:rotate(60deg);-webkit-transform-origin:top left;-ms-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}80%{-webkit-transform:rotate(60deg) translateY(0);-ms-transform:rotate(60deg) translateY(0);transform:rotate(60deg) translateY(0);-webkit-transform-origin:top left;-ms-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translateY(700px);-ms-transform:translateY(700px);transform:translateY(700px);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0px) rotate(0deg);transform:translateX(0px) rotate(0deg)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0px) rotate(0deg);-ms-transform:translateX(0px) rotate(0deg);transform:translateX(0px) rotate(0deg)}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1;-webkit-transform:translateX(0px) rotate(0deg);transform:translateX(0px) rotate(0deg)}100%{opacity:0;-webkit-transform:translateX(100%) rotate(120deg);transform:translateX(100%) rotate(120deg)}}@keyframes rollOut{0%{opacity:1;-webkit-transform:translateX(0px) rotate(0deg);-ms-transform:translateX(0px) rotate(0deg);transform:translateX(0px) rotate(0deg)}100%{opacity:0;-webkit-transform:translateX(100%) rotate(120deg);-ms-transform:translateX(100%) rotate(120deg);transform:translateX(100%) rotate(120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut} diff --git a/html/static/css/bootstrap.min.css b/html/static/css/bootstrap.min.css deleted file mode 100644 index 1140f9a..0000000 --- a/html/static/css/bootstrap.min.css +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regulard41d.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{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);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{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)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{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)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{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)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{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)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} -/*# sourceMappingURL=bootstrap.min.css.map */ diff --git a/html/static/css/font-awesome.min.css b/html/static/css/font-awesome.min.css deleted file mode 100644 index 1f5eef9..0000000 --- a/html/static/css/font-awesome.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont93e3.eot?v=4.4.0);src:url(../fonts/fontawesome-webfontd41d.eot?#iefix&v=4.4.0) format('embedded-opentype'),url(../fonts/fontawesome-webfont93e3.woff2?v=4.4.0) format('woff2'),url(../fonts/fontawesome-webfont93e3.woff?v=4.4.0) format('woff'),url(../fonts/fontawesome-webfont93e3.ttf?v=4.4.0) format('truetype'),url(../fonts/fontawesome-webfont93e3.svg?v=4.4.0#fontawesomeregular) format('svg');font-weight:400;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-y-combinator:before,.fa-yc:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-television:before,.fa-tv:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"} diff --git a/html/static/css/style.min.css b/html/static/css/style.min.css deleted file mode 100644 index 4bbc4c7..0000000 --- a/html/static/css/style.min.css +++ /dev/null @@ -1 +0,0 @@ -h1,h2,h3,h4,h5,h6{font-weight:100}h1{font-size:30px}h2{font-size:24px}h3{font-size:16px}h4{font-size:14px}h5{font-size:12px}h6{font-size:10px}h3,h4,h5{margin-top:5px;font-weight:600}a:focus{outline:0}.nav>li>a{color:#a7b1c2;font-weight:600;padding:14px 20px 14px 25px}.nav li>a{display:block}.nav.navbar-right>li>a{color:#999c9e}.nav>li.active>a{color:#fff}.navbar-default .nav>li>a:focus,.navbar-default .nav>li>a:hover{background-color:#293846;color:#fff}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background:#fff}.nav>li>a i{margin-right:6px}.navbar{border:0}.navbar-default{background-color:transparent;border-color:#2f4050;position:relative}.navbar-top-links li{display:inline-block}.navbar-top-links li:last-child{margin-right:30px}body.body-small .navbar-top-links li:last-child{margin-right:10px}.navbar-top-links li a{padding:20px 10px;min-height:50px}.dropdown-menu{border:medium none;display:none;float:left;font-size:12px;left:0;list-style:none outside none;padding:0;position:absolute;text-shadow:none;top:100%;z-index:1000;border-radius:0;box-shadow:0 0 3px rgba(86,96,117,.3)}.dropdown-menu>li>a{border-radius:3px;color:inherit;line-height:25px;margin:4px;text-align:left;font-weight:400}.dropdown-menu>li>a.font-bold{font-weight:600}.navbar-top-links .dropdown-menu li{display:block}.navbar-top-links .dropdown-menu li:last-child{margin-right:0}.navbar-top-links .dropdown-menu li a{padding:3px 20px;min-height:0}.navbar-top-links .dropdown-menu li a div{white-space:normal}.navbar-top-links .dropdown-alerts,.navbar-top-links .dropdown-messages,.navbar-top-links .dropdown-tasks{width:310px;min-width:0}.navbar-top-links .dropdown-messages{margin-left:5px}.navbar-top-links .dropdown-tasks{margin-left:-59px}.navbar-top-links .dropdown-alerts{margin-left:-123px}.navbar-top-links .dropdown-user{right:0;left:auto}.dropdown-alerts,.dropdown-messages{padding:10px}.dropdown-alerts li a,.dropdown-messages li a{font-size:12px}.dropdown-alerts li em,.dropdown-messages li em{font-size:10px}.nav.navbar-top-links .dropdown-alerts a{font-size:12px}.nav-header{padding:33px 25px;background:url(patterns/header-profile.png) no-repeat}.nav>li.active{border-left:4px solid #19aa8d;background:#293846}.nav.nav-second-level>li.active{border:none}.nav.nav-second-level.collapse[style]{height:auto!important}.nav-header a{color:#DFE4ED}.nav-header .text-muted{color:#8095a8}.minimalize-styl-2{padding:4px 12px;margin:14px 5px 5px 20px;font-size:14px;float:left}.navbar-form-custom{float:left;height:50px;padding:0;width:200px;display:inline-table}.navbar-form-custom .form-group{margin-bottom:0}.nav.navbar-top-links a{font-size:14px}.navbar-form-custom .form-control{background:none repeat scroll 0 0 rgba(0,0,0,0);border:medium none;font-size:14px;height:60px;margin:0;z-index:2000}.count-info .label{line-height:12px;padding:1px 5px;position:absolute;right:6px;top:12px}.arrow{float:right;margin-top:2px}.fa.arrow:before{content:"\f104"}.active>a>.fa.arrow:before{content:"\f107"}.nav-second-level li,.nav-third-level li{border-bottom:none!important}.nav-second-level li a{padding:7px 15px 7px 10px;padding-left:52px}.nav-third-level li a{padding-left:62px}.nav-second-level li:last-child{margin-bottom:10px}.mini-navbar .nav li:focus>.nav-second-level,body:not(.fixed-sidebar):not(.canvas-menu).mini-navbar .nav li:hover>.nav-second-level{display:block;border-radius:0 2px 2px 0;min-width:140px;height:auto}body.mini-navbar .navbar-default .nav>li>.nav-second-level li a{font-size:12px;border-radius:0 2px 2px 0}.fixed-nav .slimScrollDiv #side-menu{padding-bottom:60px;position:relative}.slimScrollDiv >*{overflow:hidden}.mini-navbar .nav-second-level li a{padding:10px 10px 10px 15px}.canvas-menu.mini-navbar .nav-second-level{background:#293846}.mini-navbar li.active .nav-second-level{left:65px}.navbar-default .special_link a{background:#1ab394;color:#fff}.navbar-default .special_link a:hover{background:#17987e!important;color:#fff}.navbar-default .special_link a span.label{background:#fff;color:#1ab394}.navbar-default .landing_link a{background:#1cc09f;color:#fff}.navbar-default .landing_link a:hover{background:#1ab394!important;color:#fff}.navbar-default .landing_link a span.label{background:#fff;color:#1cc09f}.logo-element{text-align:center;font-size:18px;font-weight:600;color:#fff;display:none;padding:18px 0}.pace-done #page-wrapper,.pace-done .footer,.pace-done .nav-header,.pace-done .navbar-static-side,.pace-done li.active{-webkit-transition:all .5s;transition:all .5s}.navbar-fixed-top{-webkit-transition-duration:.5s;transition-duration:.5s;z-index:2030}.navbar-fixed-top,.navbar-static-top{background:#f3f3f4}.fixed-nav #wrapper{padding-top:60px;box-sizing:border-box}.fixed-nav .minimalize-styl-2{margin:14px 5px 5px 15px}.body-small .navbar-fixed-top{margin-left:0}body.mini-navbar .navbar-static-side{width:70px}body.mini-navbar .nav-label,body.mini-navbar .navbar-default .nav li a span,body.mini-navbar .profile-element{display:none}body.canvas-menu .profile-element{display:block}body:not(.fixed-sidebar):not(.canvas-menu).mini-navbar .nav-second-level{display:none}body.mini-navbar .navbar-default .nav>li>a{font-size:16px}body.mini-navbar .logo-element{display:block}body.canvas-menu .logo-element{display:none}body.mini-navbar .nav-header{padding:0;background-color:#1ab394}body.canvas-menu .nav-header{padding:33px 25px}body.mini-navbar #page-wrapper{margin:0 0 0 70px}body.canvas-menu.mini-navbar #page-wrapper,body.canvas-menu.mini-navbar .footer{margin:0}body.canvas-menu .navbar-static-side,body.fixed-sidebar .navbar-static-side{position:fixed;width:220px;z-index:2001;height:100%}body.fixed-sidebar.mini-navbar .navbar-static-side{width:70px}body.body-small.fixed-sidebar.mini-navbar #page-wrapper,body.fixed-sidebar.mini-navbar #page-wrapper{margin:0 0 0 70px}body.body-small.fixed-sidebar.mini-navbar .navbar-static-side{width:70px}.fixed-sidebar.mini-navbar .nav li> .nav-second-level{display:none}.fixed-sidebar.mini-navbar .nav li.active{border-left-width:0}.canvas-menu.mini-navbar .nav li:hover>.nav-second-level,.fixed-sidebar.mini-navbar .nav li:hover>.nav-second-level{position:absolute;left:70px;top:0;background-color:#2f4050;padding:10px 10px 0;font-size:12px;display:block;min-width:140px;border-radius:2px}body.fixed-sidebar.mini-navbar .navbar-default .nav>li>.nav-second-level li a{font-size:12px;border-radius:3px}body.canvas-menu.mini-navbar .navbar-default .nav>li>.nav-second-level li a{font-size:13px;border-radius:3px}.canvas-menu.mini-navbar .nav-second-level li a,.fixed-sidebar.mini-navbar .nav-second-level li a{padding:10px 10px 10px 15px}.canvas-menu.mini-navbar .nav-second-level,.fixed-sidebar.mini-navbar .nav-second-level{position:relative;padding:0;font-size:13px}.canvas-menu.mini-navbar li.active .nav-second-level,.fixed-sidebar.mini-navbar li.active .nav-second-level{left:0}body.canvas-menu nav.navbar-static-side{z-index:2001;background:#2f4050;height:100%;position:fixed;display:none}body.canvas-menu.mini-navbar nav.navbar-static-side{display:block;width:70px}.top-navigation #page-wrapper{margin-left:0}.top-navigation .navbar-nav .dropdown-menu>.active>a{background:#fff;color:#1ab394;font-weight:700}.white-bg .navbar-fixed-top,.white-bg .navbar-static-top{background:#fff}.top-navigation .navbar{margin-bottom:0}.top-navigation .nav>li>a{padding:15px 20px;color:#676a6c}.top-navigation .nav>li a:focus,.top-navigation .nav>li a:hover{background:#fff;color:#1ab394}.top-navigation .nav>li.active{background:#fff;border:none}.top-navigation .nav>li.active>a{color:#1ab394}.top-navigation .navbar-right{padding-right:10px}.top-navigation .navbar-nav .dropdown-menu{box-shadow:none;border:1px solid #e7eaec}.top-navigation .dropdown-menu>li>a{margin:0;padding:7px 20px}.navbar .dropdown-menu{margin-top:0}.top-navigation .navbar-brand{background:#1ab394;color:#fff;padding:15px 25px}.top-navigation .navbar-top-links li:last-child{margin-right:0}.body-small.fixed-sidebar.mini-navbar .top-navigation #page-wrapper,.canvas-menu #page-wrapper,.mini-navbar .top-navigation #page-wrapper,.top-navigation.body-small.fixed-sidebar.mini-navbar #page-wrapper,.top-navigation.mini-navbar #page-wrapper{margin:0}.fixed-nav #wrapper.top-navigation,.top-navigation.fixed-nav #wrapper{margin-top:50px}.top-navigation .footer.fixed{margin-left:0!important}.top-navigation .wrapper.wrapper-content{padding:40px}.body-small .top-navigation .wrapper.wrapper-content,.top-navigation.body-small .wrapper.wrapper-content{padding:40px 0}.navbar-toggle{color:#fff;padding:6px 12px;font-size:14px}.top-navigation .navbar-nav .open .dropdown-menu .dropdown-header,.top-navigation .navbar-nav .open .dropdown-menu>li>a{padding:10px 15px 10px 20px}@media (max-width:768px){.top-navigation .navbar-header{display:block;float:none}}.menu-visible-lg,.menu-visible-md{display:none!important}@media (min-width:1200px){.menu-visible-lg{display:block!important}}@media (min-width:992px){.menu-visible-md{display:block!important}}@media (max-width:767px){.menu-visible-lg,.menu-visible-md{display:block!important}}.btn{border-radius:3px}.float-e-margins .btn{margin-bottom:5px}.btn-w-m{min-width:120px}.btn-primary.btn-outline{color:#1ab394}.btn-success.btn-outline{color:#1c84c6}.btn-info.btn-outline{color:#23c6c8}.btn-warning.btn-outline{color:#f8ac59}.btn-danger.btn-outline{color:#ed5565}.btn-danger.btn-outline:hover,.btn-info.btn-outline:hover,.btn-primary.btn-outline:hover,.btn-success.btn-outline:hover,.btn-warning.btn-outline:hover{color:#fff}.btn-primary{background-color:#1ab394;border-color:#1ab394;color:#FFF}.btn-primary.active,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open .dropdown-toggle.btn-primary{background-color:#18a689;border-color:#18a689;color:#FFF}.btn-primary.active,.btn-primary:active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.active[disabled],.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#1dc5a3;border-color:#1dc5a3}.btn-success{background-color:#1c84c6;border-color:#1c84c6;color:#FFF}.btn-success.active,.btn-success:active,.btn-success:focus,.btn-success:hover,.open .dropdown-toggle.btn-success{background-color:#1a7bb9;border-color:#1a7bb9;color:#FFF}.btn-success.active,.btn-success:active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.active[disabled],.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#1f90d8;border-color:#1f90d8}.btn-info{background-color:#23c6c8;border-color:#23c6c8;color:#FFF}.btn-info.active,.btn-info:active,.btn-info:focus,.btn-info:hover,.open .dropdown-toggle.btn-info{background-color:#21b9bb;border-color:#21b9bb;color:#FFF}.btn-info.active,.btn-info:active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.active[disabled],.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#26d7d9;border-color:#26d7d9}.btn-default{background-color:#c2c2c2;border-color:#c2c2c2;color:#FFF}.btn-default.active,.btn-default:active,.btn-default:focus,.btn-default:hover,.open .dropdown-toggle.btn-default{background-color:#bababa;border-color:#bababa;color:#FFF}.btn-default.active,.btn-default:active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.active[disabled],.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#ccc;border-color:#ccc}.btn-warning{background-color:#f8ac59;border-color:#f8ac59;color:#FFF}.btn-warning.active,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open .dropdown-toggle.btn-warning{background-color:#f7a54a;border-color:#f7a54a;color:#FFF}.btn-warning.active,.btn-warning:active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.active[disabled],.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f9b66d;border-color:#f9b66d}.btn-danger{background-color:#ed5565;border-color:#ed5565;color:#FFF}.btn-danger.active,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open .dropdown-toggle.btn-danger{background-color:#ec4758;border-color:#ec4758;color:#FFF}.btn-danger.active,.btn-danger:active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.active[disabled],.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#ef6776;border-color:#ef6776}.btn-link{color:inherit}.btn-link.active,.btn-link:active,.btn-link:focus,.btn-link:hover,.open .dropdown-toggle.btn-link{color:#1ab394;text-decoration:none}.btn-link.active,.btn-link:active,.open .dropdown-toggle.btn-link{background-image:none}.btn-link.active[disabled],.btn-link.disabled,.btn-link.disabled.active,.btn-link.disabled:active,.btn-link.disabled:focus,.btn-link.disabled:hover,.btn-link[disabled],.btn-link[disabled]:active,.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link,fieldset[disabled] .btn-link.active,fieldset[disabled] .btn-link:active,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#cacaca}.btn-white{color:inherit;background:#fff;border:1px solid #e7eaec}.btn-white.active,.btn-white:active,.btn-white:focus,.btn-white:hover,.open .dropdown-toggle.btn-white{color:inherit;border:1px solid #d2d2d2}.btn-white.active,.btn-white:active{box-shadow:0 2px 5px rgba(0,0,0,.15)inset}.btn-white.active,.btn-white:active,.open .dropdown-toggle.btn-white{background-image:none}.btn-white.active[disabled],.btn-white.disabled,.btn-white.disabled.active,.btn-white.disabled:active,.btn-white.disabled:focus,.btn-white.disabled:hover,.btn-white[disabled],.btn-white[disabled]:active,.btn-white[disabled]:focus,.btn-white[disabled]:hover,fieldset[disabled] .btn-white,fieldset[disabled] .btn-white.active,fieldset[disabled] .btn-white:active,fieldset[disabled] .btn-white:focus,fieldset[disabled] .btn-white:hover{color:#cacaca}.form-control,.form-control:focus,.has-error .form-control:focus,.has-success .form-control:focus,.has-warning .form-control:focus,.navbar-collapse,.navbar-form,.navbar-form-custom .form-control:focus,.navbar-form-custom .form-control:hover,.open .btn.dropdown-toggle,.panel,.popover,.progress,.progress-bar{box-shadow:none}.btn-outline{color:inherit;background-color:transparent;-webkit-transition:all .5s;transition:all .5s}.btn-rounded{border-radius:50px}.btn-large-dim{width:90px;height:90px;font-size:42px}button.dim{display:inline-block;color:#fff;text-decoration:none;text-transform:uppercase;text-align:center;padding-top:6px;margin-right:10px;position:relative;cursor:pointer;border-radius:5px;font-weight:600;margin-bottom:20px!important}button.dim:active{top:3px}button.btn-primary.dim{box-shadow:inset 0 0 0 #16987e,0 5px 0 0 #16987e,0 10px 5px #999}button.btn-primary.dim:active{box-shadow:inset 0 0 0 #16987e,0 2px 0 0 #16987e,0 5px 3px #999}button.btn-default.dim{box-shadow:inset 0 0 0 #b3b3b3,0 5px 0 0 #b3b3b3,0 10px 5px #999}button.btn-default.dim:active{box-shadow:inset 0 0 0 #b3b3b3,0 2px 0 0 #b3b3b3,0 5px 3px #999}button.btn-warning.dim{box-shadow:inset 0 0 0 #f79d3c,0 5px 0 0 #f79d3c,0 10px 5px #999}button.btn-warning.dim:active{box-shadow:inset 0 0 0 #f79d3c,0 2px 0 0 #f79d3c,0 5px 3px #999}button.btn-info.dim{box-shadow:inset 0 0 0 #1eacae,0 5px 0 0 #1eacae,0 10px 5px #999}button.btn-info.dim:active{box-shadow:inset 0 0 0 #1eacae,0 2px 0 0 #1eacae,0 5px 3px #999}button.btn-success.dim{box-shadow:inset 0 0 0 #1872ab,0 5px 0 0 #1872ab,0 10px 5px #999}button.btn-success.dim:active{box-shadow:inset 0 0 0 #1872ab,0 2px 0 0 #1872ab,0 5px 3px #999}button.btn-danger.dim{box-shadow:inset 0 0 0 #ea394c,0 5px 0 0 #ea394c,0 10px 5px #999}button.btn-danger.dim:active{box-shadow:inset 0 0 0 #ea394c,0 2px 0 0 #ea394c,0 5px 3px #999}button.dim:before{font-size:50px;line-height:1em;font-weight:400;color:#fff;display:block;padding-top:10px}button.dim:active:before{top:7px;font-size:50px}.label{background-color:#d1dade;color:#5e5e5e;font-size:10px;font-weight:600;padding:3px 8px;text-shadow:none}.badge{background-color:#d1dade;color:#5e5e5e;font-size:11px;font-weight:600;padding-bottom:4px;padding-left:6px;padding-right:6px;text-shadow:none}.badge-primary,.label-primary{background-color:#1ab394;color:#FFF}.badge-success,.label-success{background-color:#1c84c6;color:#FFF}.badge-warning,.label-warning{background-color:#f8ac59;color:#FFF}.badge-warning-light,.label-warning-light{background-color:#f8ac59;color:#fff}.badge-danger,.label-danger{background-color:#ed5565;color:#FFF}.badge-info,.label-info{background-color:#23c6c8;color:#FFF}.badge-inverse,.label-inverse{background-color:#262626;color:#FFF}.badge-white,.label-white{background-color:#FFF;color:#5E5E5E}.badge-disable,.label-white{background-color:#2A2E36;color:#8B91A0}.chosen-container-single .chosen-single{background:#fff;box-shadow:none;-moz-box-sizing:border-box;background-color:#FFF;border:1px solid #CBD5DD;border-radius:2px;cursor:text;height:auto!important;margin:0;min-height:30px;overflow:hidden;padding:4px 12px;position:relative;width:100%}.chosen-container-multi .chosen-choices li.search-choice{background:#f1f1f1;border:1px solid #ededed;border-radius:2px;box-shadow:none;color:#333;cursor:default;line-height:13px;margin:3px 0 3px 5px;padding:3px 20px 3px 5px;position:relative}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{background-color:#f4f4f4;border-color:#DDD;color:inherit;cursor:default;z-index:2}.pagination>li>a,.pagination>li>span{background-color:#FFF;border:1px solid #DDD;color:inherit;float:left;line-height:1.42857;margin-left:-1px;padding:4px 10px;position:relative;text-decoration:none}.tooltip-inner{background-color:#2F4050}.tooltip.top .tooltip-arrow{border-top-color:#2F4050}.tooltip.right .tooltip-arrow{border-right-color:#2F4050}.tooltip.bottom .tooltip-arrow{border-bottom-color:#2F4050}.tooltip.left .tooltip-arrow{border-left-color:#2F4050}.easypiechart{position:relative;text-align:center}.easypiechart .h2{margin-left:10px;margin-top:10px;display:inline-block}.easypiechart canvas{top:0;left:0}.easypiechart .easypie-text{line-height:1;position:absolute;top:33px;width:100%;z-index:1}.easypiechart img{margin-top:-4px}.jqstooltip{box-sizing:content-box}.fc-state-default{background-color:#fff;background-image:none;background-repeat:repeat-x;box-shadow:none;color:#333;text-shadow:none;border:1px solid}.fc-button{color:inherit;border:1px solid #e7eaec;cursor:pointer;display:inline-block;height:1.9em;line-height:1.9em;overflow:hidden;padding:0 .6em;position:relative;white-space:nowrap}.fc-state-active{background-color:#1ab394;border-color:#1ab394;color:#fff}.fc-header-title h2{font-size:16px;font-weight:600;color:inherit}.fc-content .fc-widget-content,.fc-content .fc-widget-header{border-color:#e7eaec;font-weight:400}.fc-border-separate tbody{background-color:#F8F8F8}.fc-state-highlight{background:none repeat scroll 0 0 #FCF8E3}.external-event{padding:5px 10px;border-radius:2px;cursor:pointer;margin-bottom:5px}.fc-ltr .fc-event-hori.fc-event-end,.fc-rtl .fc-event-hori.fc-event-start{border-radius:2px}.fc-agenda .fc-event-time,.fc-event,.fc-event a{padding:4px 6px;background-color:#1ab394;border-color:#1ab394}.fc-event-time,.fc-event-title{color:#717171;padding:0 1px}.ui-calendar .fc-event-time,.ui-calendar .fc-event-title{color:#fff}.chat-activity-list .chat-element{border-bottom:1px solid #e7eaec}.chat-element:first-child{margin-top:0}.chat-element{padding-bottom:15px}.chat-element,.chat-element .media{margin-top:15px}.chat-element,.media-body{overflow:hidden}.media-body{display:block;width:auto}.chat-element>.pull-left{margin-right:10px}.chat-element img.img-circle,.dropdown-messages-box img.img-circle{width:38px;height:38px}.chat-element .well{border:1px solid #e7eaec;box-shadow:none;margin-top:10px;margin-bottom:5px;padding:10px 20px;font-size:11px;line-height:16px}.chat-element .actions{margin-top:10px}.chat-element .photos{margin:10px 0}.right.chat-element>.pull-right{margin-left:10px}.chat-photo{max-height:180px;border-radius:4px;overflow:hidden;margin-right:10px;margin-bottom:10px}.chat{margin:0;padding:0;list-style:none}.chat li{margin-bottom:10px;padding-bottom:5px;border-bottom:1px dotted #B3A9A9}.chat li.left .chat-body{margin-left:60px}.chat li.right .chat-body{margin-right:60px}.chat li .chat-body p{margin:0;color:#777}.chat .glyphicon,.panel .slidedown .glyphicon{margin-right:5px}.chat-panel .panel-body{height:350px;overflow-y:scroll}a.list-group-item.active,a.list-group-item.active:focus,a.list-group-item.active:hover{background-color:#1ab394;border-color:#1ab394;color:#FFF;z-index:2}.list-group-item-heading{margin-top:10px}.list-group-item-text{margin:0 0 10px;color:inherit;font-size:12px;line-height:inherit}.no-padding .list-group-item{border-left:none;border-right:none;border-bottom:none}.no-padding .list-group-item:first-child{border-left:none;border-right:none;border-bottom:none;border-top:none}.no-padding .list-group{margin-bottom:0}.list-group-item{background-color:inherit;border:1px solid #e7eaec;display:block;margin-bottom:-1px;padding:10px 15px;position:relative}.elements-list .list-group-item{border-left:none;border-right:none;padding:15px 25px}.elements-list .list-group-item:first-child{border-left:none;border-right:none;border-top:none!important}.elements-list .list-group{margin-bottom:0}.elements-list a{color:inherit}.elements-list .list-group-item.active,.elements-list .list-group-item:hover{background:#f3f3f4;color:inherit;border-color:#e7eaec;border-radius:0}.elements-list li.active{-webkit-transition:none;transition:none}.element-detail-box{padding:25px}.flot-chart{display:block;height:200px}.widget .flot-chart.dashboard-chart{display:block;height:120px;margin-top:40px}.flot-chart.dashboard-chart{display:block;height:180px;margin-top:40px}.flot-chart-content{width:100%;height:100%}.flot-chart-pie-content{width:200px;height:200px;margin:auto}.jqstooltip{position:absolute;display:block;left:0;top:0;visibility:hidden;background:#2b303a;background-color:rgba(43,48,58,.8);color:#fff;text-align:left;white-space:nowrap;z-index:10000;padding:5px;min-height:22px;border-radius:3px}.jqsfield{color:#fff;text-align:left}.h-200{min-height:200px}.legendLabel{padding-left:5px}.stat-list li:first-child{margin-top:0}.stat-list{list-style:none;padding:0;margin:0}.stat-percent{float:right}.stat-list li{margin-top:15px;position:relative}table.dataTable thead .sorting,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_desc_disabled{background:0 0}table.dataTable thead .sorting_asc:after{float:right;font-family:fontawesome}table.dataTable thead .sorting_desc:after{content:"\f0dd";float:right;font-family:fontawesome}table.dataTable thead .sorting:after{content:"\f0dc";float:right;font-family:fontawesome;color:rgba(50,50,50,.5)}.dataTables_wrapper{padding-bottom:30px}.img-circle{border-radius:50%}.btn-circle{width:30px;height:30px;padding:6px 0;border-radius:15px;text-align:center;font-size:12px;line-height:1.428571429}.btn-circle.btn-lg{width:50px;height:50px;padding:10px 16px;border-radius:25px;font-size:18px;line-height:1.33}.btn-circle.btn-xl{width:70px;height:70px;padding:10px 16px;border-radius:35px;font-size:24px;line-height:1.33}.show-grid [class^=col-]{padding-top:10px;padding-bottom:10px;border:1px solid #ddd;background-color:#eee!important}.show-grid{margin:15px 0}.css-animation-box h1{font-size:44px}.animation-efect-links a{padding:4px 6px;font-size:12px}#animation_box{background-color:#f9f8f8;border-radius:16px;width:80%;margin:0 auto;padding-top:80px}.animation-text-box{position:absolute;margin-top:40px;left:50%;margin-left:-100px;width:200px}.animation-text-info{position:absolute;margin-top:-60px;left:50%;margin-left:-100px;width:200px;font-size:10px}.animation-text-box h2{font-size:54px;font-weight:600;margin-bottom:5px}.animation-text-box p{font-size:12px;text-transform:uppercase}.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pace .pace-progress{background:#1ab394;position:fixed;z-index:2000;top:0;width:100%;height:2px}.pace-inactive{display:none}.widget{border-radius:5px;padding:15px 20px;margin-bottom:10px;margin-top:10px}.widget.style1 h2{font-size:30px}.widget h2,.widget h3{margin-top:5px;margin-bottom:0}.widget-text-box{padding:20px;border:1px solid #e7eaec;background:#fff}.widget-head-color-box{border-radius:5px 5px 0 0;margin-top:10px}.widget .flot-chart{height:100px}.vertical-align div{display:inline-block;vertical-align:middle}.vertical-align h2,.vertical-align h3{margin:0}.todo-list{list-style:none outside none;margin:0;padding:0;font-size:14px}.todo-list.small-list{font-size:12px}.todo-list.small-list>li{background:#f3f3f4;border-left:none;border-right:none;border-radius:4px;color:inherit;margin-bottom:2px;padding:6px 6px 6px 12px}.todo-list.small-list .btn-group-xs>.btn,.todo-list.small-list .btn-xs{border-radius:5px;font-size:10px;line-height:1.5;padding:1px 2px 1px 5px}.todo-list>li{background:#f3f3f4;border-left:6px solid #e7eaec;border-right:6px solid #e7eaec;border-radius:4px;color:inherit;margin-bottom:2px;padding:10px}.todo-list .handle{cursor:move;display:inline-block;font-size:16px;margin:0 5px}.todo-list>li .label{font-size:9px;margin-left:10px}.check-link{font-size:16px}.todo-completed{text-decoration:line-through}.geo-statistic h1{font-size:36px;margin-bottom:0}.glyphicon.fa{font-family:FontAwesome}.inline{display:inline-block!important}.input-s-sm{width:120px}.input-s{width:200px}.input-s-lg{width:250px}.i-checks{padding-left:0}.form-control,.single-line{background-color:#FFF;background-image:none;border:1px solid #e5e6e7;border-radius:1px;color:inherit;display:block;padding:6px 12px;-webkit-transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s;transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s;width:100%;font-size:14px}.form-control:focus,.single-line:focus{border-color:#1ab394!important}.has-success .form-control{border-color:#1ab394}.has-warning .form-control{border-color:#f8ac59}.has-error .form-control{border-color:#ed5565}.has-success .control-label{color:#1ab394}.has-warning .control-label{color:#f8ac59}.has-error .control-label{color:#ed5565}.input-group-addon{background-color:#fff;border:1px solid #E5E6E7;border-radius:1px;color:inherit;font-size:14px;font-weight:400;line-height:1;padding:6px 12px;text-align:center}.spinner-buttons.input-group-btn .btn-xs{line-height:1.13}.spinner-buttons.input-group-btn{width:20%}.noUi-connect{background:none repeat scroll 0 0 #1ab394;box-shadow:none}.slider_red .noUi-connect{background:none repeat scroll 0 0 #ed5565;box-shadow:none}.ui-sortable .ibox-title{cursor:move}.ui-sortable-placeholder{border:1px dashed #cecece!important;visibility:visible!important;background:#e7eaec}.ibox.ui-sortable-placeholder{margin:0 0 23px!important}.tabs-container .panel-body{background:#fff;border:1px solid #e7eaec;border-radius:2px;padding:20px;position:relative}.tabs-container .nav-tabs>li.active>a,.tabs-container .nav-tabs>li.active>a:focus,.tabs-container .nav-tabs>li.active>a:hover{background-color:#fff}.tabs-container .nav-tabs>li{float:left;margin-bottom:-1px}.tabs-container .nav-tabs>li.active>a,.tabs-container .nav-tabs>li.active>a:focus,.tabs-container .nav-tabs>li.active>a:hover{border:1px solid #e7eaec;border-bottom-color:transparent}.tabs-container .nav-tabs{border-bottom:1px solid #e7eaec}.tabs-container .tab-pane .panel-body{border-top:none}.tabs-container .tabs-left .tab-pane .panel-body,.tabs-container .tabs-right .tab-pane .panel-body{border-top:1px solid #e7eaec}.tabs-container .nav-tabs>li a:hover{background:0 0;border-color:transparent}.tabs-container .tabs-below>.nav-tabs,.tabs-container .tabs-left>.nav-tabs,.tabs-container .tabs-right>.nav-tabs{border-bottom:0}.tabs-container .tabs-left .panel-body{position:static}.tabs-container .tabs-left>.nav-tabs,.tabs-container .tabs-right>.nav-tabs{width:20%}.tabs-container .tabs-left .panel-body{width:80%;margin-left:20%}.tabs-container .tabs-right .panel-body{width:80%;margin-right:20%}.tabs-container .pill-content>.pill-pane,.tabs-container .tab-content>.tab-pane{display:none}.tabs-container .pill-content>.active,.tabs-container .tab-content>.active{display:block}.tabs-container .tabs-below>.nav-tabs{border-top:1px solid #e7eaec}.tabs-container .tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-container .tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-container .tabs-below>.nav-tabs>li>a:focus,.tabs-container .tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7eaec;border-bottom-color:transparent}.tabs-container .tabs-left>.nav-tabs>li,.tabs-container .tabs-right>.nav-tabs>li{float:none}.tabs-container .tabs-left>.nav-tabs>li>a,.tabs-container .tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-container .tabs-left>.nav-tabs{float:left;margin-right:19px}.tabs-container .tabs-left>.nav-tabs>li>a{margin-right:-1px;border-radius:4px 0 0 4px}.tabs-container .tabs-left>.nav-tabs .active>a,.tabs-container .tabs-left>.nav-tabs .active>a:focus,.tabs-container .tabs-left>.nav-tabs .active>a:hover{border-color:#e7eaec transparent #e7eaec #e7eaec;*border-right-color:#fff}.tabs-container .tabs-right>.nav-tabs{float:right;margin-left:19px}.tabs-container .tabs-right>.nav-tabs>li>a{margin-left:-1px;border-radius:0 4px 4px 0}.tabs-container .tabs-right>.nav-tabs .active>a,.tabs-container .tabs-right>.nav-tabs .active>a:focus,.tabs-container .tabs-right>.nav-tabs .active>a:hover{border-color:#e7eaec #e7eaec #e7eaec transparent;*border-left-color:#fff;z-index:1}.onoffswitch{position:relative;width:54px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.onoffswitch-checkbox{display:none}.onoffswitch-label{display:block;overflow:hidden;cursor:pointer;border:2px solid #1AB394;border-radius:3px}.onoffswitch-inner{display:block;width:200%;margin-left:-100%;-webkit-transition:margin .3s ease-in 0s;transition:margin .3s ease-in 0s}.onoffswitch-inner:after,.onoffswitch-inner:before{display:block;float:left;width:50%;height:16px;padding:0;line-height:16px;font-size:10px;font-family:Trebuchet,Arial,sans-serif;font-weight:700;box-sizing:border-box}.onoffswitch-inner:before{content:"ON";padding-left:7px;background-color:#1AB394;color:#FFF}.onoffswitch-inner:after{content:"OFF";padding-right:7px;background-color:#FFF;color:#919191;text-align:right}.onoffswitch-switch{display:block;width:18px;margin:0;background:#FFF;border:2px solid #1AB394;border-radius:3px;position:absolute;top:0;bottom:0;right:36px;-webkit-transition:all .3s ease-in 0s;transition:all .3s ease-in 0s}.onoffswitch-checkbox:checked+.onoffswitch-label .onoffswitch-inner{margin-left:0}.onoffswitch-checkbox:checked+.onoffswitch-label .onoffswitch-switch{right:0}.dd{position:relative;display:block;margin:0;padding:0;list-style:none;font-size:13px;line-height:20px}.dd-list{display:block;position:relative;margin:0;padding:0;list-style:none}.dd-list .dd-list{padding-left:30px}.dd-collapsed .dd-list{display:none}.dd-empty,.dd-item,.dd-placeholder{display:block;position:relative;margin:0;padding:0;min-height:20px;font-size:13px;line-height:20px}.dd-handle{display:block;margin:5px 0;padding:5px 10px;color:#333;text-decoration:none;border:1px solid #e7eaec;background:#f5f5f5;border-radius:3px;box-sizing:border-box;-moz-box-sizing:border-box}.dd-handle span{font-weight:700}.dd-handle:hover{background:#f0f0f0;cursor:pointer;font-weight:700}.dd-item>button{display:block;position:relative;cursor:pointer;float:left;width:25px;height:20px;margin:5px 0;padding:0;text-indent:100%;white-space:nowrap;overflow:hidden;border:0;background:0 0;font-size:12px;line-height:1;text-align:center;font-weight:700}.dd-item>button:before{content:'+';display:block;position:absolute;width:100%;text-align:center;text-indent:0}.dd-item>button[data-action=collapse]:before{content:'-'}#nestable2 .dd-item>button{font-family:FontAwesome;height:34px;width:33px;color:#c1c1c1}#nestable2 .dd-item>button:before{content:"\f067"}#nestable2 .dd-item>button[data-action=collapse]:before{content:"\f068"}.dd-empty,.dd-placeholder{margin:5px 0;padding:0;min-height:30px;background:#f2fbff;border:1px dashed #b6bcbf;box-sizing:border-box;-moz-box-sizing:border-box}.dd-empty{border:1px dashed #bbb;min-height:100px;background-color:#e5e5e5;background-image:-webkit-linear-gradient(45deg,#fff 25%,transparent 25%,transparent 75%,#fff 75%,#fff),-webkit-linear-gradient(45deg,#fff 25%,transparent 25%,transparent 75%,#fff 75%,#fff);background-image:linear-gradient(45deg,#fff 25%,transparent 25%,transparent 75%,#fff 75%,#fff),linear-gradient(45deg,#fff 25%,transparent 25%,transparent 75%,#fff 75%,#fff);background-size:60px 60px;background-position:0 0,30px 30px}.dd-dragel{position:absolute;z-index:9999;pointer-events:none}.dd-dragel>.dd-item .dd-handle{margin-top:0}.dd-dragel .dd-handle{box-shadow:2px 4px 6px 0 rgba(0,0,0,.1)}.nestable-lists{display:block;clear:both;padding:30px 0;width:100%;border:0;border-top:2px solid #ddd;border-bottom:2px solid #ddd}#nestable-menu{padding:0;margin:10px 0 20px}#nestable-output,#nestable2-output{width:100%;line-height:1.333333em;font-family:lucida grande,lucida sans unicode,helvetica,arial,sans-serif}#nestable2 .dd-handle{color:inherit;border:1px dashed #e7eaec;background:#f3f3f4;padding:10px}#nestable2 span.label{margin-right:10px}#nestable-output,#nestable2-output{font-size:12px;padding:25px;box-sizing:border-box;-moz-box-sizing:border-box}.CodeMirror{border:1px solid #eee;height:auto}.CodeMirror-scroll{overflow-y:hidden;overflow-x:auto}.google-map{height:300px}label.error{color:#cc5965;display:inline-block;margin-left:5px}.form-control.error{border:1px dotted #cc5965}.gridStyle{border:1px solid #d4d4d4;width:100%;height:400px}.gridStyle2{border:1px solid #d4d4d4;width:500px;height:300px}.ngH eaderCell{border-right:none;border-bottom:1px solid #e7eaec}.ngCell{border-right:none}.ngTopPanel{background:#F5F5F6}.ngRow.even{background:#f9f9f9}.ngRow.selected{background:#EBF2F1}.ngRow{border-bottom:1px solid #e7eaec}.ngCell{background-color:transparent}.ngHeaderCell{border-right:none}#toast-container>.toast{background-image:none!important}#toast-container>.toast:before{position:fixed;font-family:FontAwesome;font-size:24px;line-height:24px;float:left;color:#FFF;padding-right:.5em;margin:auto .5em auto -1.5em}#toast-container>div{box-shadow:0 0 3px #999;opacity:.9;-ms-filter:alpha(opacity=90);filter:alpha(opacity=90)}#toast-container >:hover{box-shadow:0 0 4px #999;opacity:1;-ms-filter:alpha(opacity=100);filter:alpha(opacity=100);cursor:pointer}.toast,.toast-success{background-color:#1ab394}.toast-error{background-color:#ed5565}.toast-info{background-color:#23c6c8}.toast-warning{background-color:#f8ac59}.toast-top-full-width{margin-top:20px}.toast-bottom-full-width{margin-bottom:20px}.img-container,.img-preview{overflow:hidden;text-align:center;width:100%}.img-preview-sm{height:130px;width:200px}.forum-post-container .media{margin:10px;padding:20px 10px;border-bottom:1px solid #f1f1f1}.forum-avatar{float:left;margin-right:20px;text-align:center;width:110px}.forum-avatar .img-circle{height:48px;width:48px}.author-info{color:#676a6c;font-size:11px;margin-top:5px;text-align:center}.forum-post-info{padding:9px 12px 6px;background:#f9f9f9;border:1px solid #f1f1f1}.media-body>.media{background:#f9f9f9;border-radius:3px;border:1px solid #f1f1f1}.forum-post-container .media-body .photos{margin:10px 0}.forum-photo{max-width:140px;border-radius:3px}.media-body>.media .forum-avatar{width:70px;margin-right:10px}.media-body>.media .forum-avatar .img-circle{height:38px;width:38px}.mid-icon{font-size:66px}.forum-item{margin:10px 0;padding:10px 0 20px;border-bottom:1px solid #f1f1f1}.views-number{font-size:24px;line-height:18px;font-weight:400}.forum-container,.forum-post-container{padding:30px!important}.forum-item small{color:#999}.forum-item .forum-sub-title{color:#999;margin-left:50px}.forum-title{margin:15px 0}.forum-info{text-align:center}.forum-desc{color:#999}.forum-icon{float:left;width:30px;margin-right:20px;text-align:center}a.forum-item-title{color:inherit;display:block;font-size:18px;font-weight:600}a.forum-item-title:hover{color:inherit}.forum-icon .fa{font-size:30px;margin-top:8px;color:#9b9b9b}.forum-item.active .fa,.forum-item.active a.forum-item-title{color:#1ab394}@media (max-width:992px){.forum-info{margin:15px 0 10px;display:none}.forum-desc{float:none!important}}.vertical-container{width:90%;max-width:1170px;margin:0 auto}.vertical-container::after{content:'';display:table;clear:both}#vertical-timeline{position:relative;padding:0;margin-top:2em;margin-bottom:2em}#vertical-timeline::before{content:'';position:absolute;top:0;left:18px;height:100%;width:4px;background:#f1f1f1}.vertical-timeline-content .btn{float:right}#vertical-timeline.light-timeline:before{background:#e7eaec}.dark-timeline .vertical-timeline-content:before{border-color:transparent #f5f5f5 transparent transparent}.dark-timeline.center-orientation .vertical-timeline-content:before{border-color:transparent transparent transparent #f5f5f5}.dark-timeline .vertical-timeline-block:nth-child(2n) .vertical-timeline-content:before,.dark-timeline.center-orientation .vertical-timeline-block:nth-child(2n) .vertical-timeline-content:before{border-color:transparent #f5f5f5 transparent transparent}.dark-timeline .vertical-timeline-content,.dark-timeline.center-orientation .vertical-timeline-content{background:#f5f5f5}@media only screen and (min-width:1170px){#vertical-timeline.center-orientation{margin-top:3em;margin-bottom:3em}#vertical-timeline.center-orientation:before{left:50%;margin-left:-2px}}@media only screen and (max-width:1170px){.center-orientation.dark-timeline .vertical-timeline-content:before{border-color:transparent #f5f5f5 transparent transparent}}.vertical-timeline-block{position:relative;margin:2em 0}.vertical-timeline-block:after{content:"";display:table;clear:both}.vertical-timeline-block:first-child{margin-top:0}.vertical-timeline-block:last-child{margin-bottom:0}@media only screen and (min-width:1170px){.center-orientation .vertical-timeline-block{margin:4em 0}.center-orientation .vertical-timeline-block:first-child{margin-top:0}.center-orientation .vertical-timeline-block:last-child{margin-bottom:0}}.vertical-timeline-icon{position:absolute;top:0;left:0;width:40px;height:40px;border-radius:50%;font-size:16px;border:3px solid #f1f1f1;text-align:center}.vertical-timeline-icon i{display:block;width:24px;height:24px;position:relative;left:50%;top:50%;margin-left:-12px;margin-top:-9px}@media only screen and (min-width:1170px){.center-orientation .vertical-timeline-icon{width:50px;height:50px;left:50%;margin-left:-25px;-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;font-size:19px}.center-orientation .vertical-timeline-icon i{margin-left:-12px;margin-top:-10px}.center-orientation .cssanimations .vertical-timeline-icon.is-hidden{visibility:hidden}}.vertical-timeline-content{position:relative;margin-left:60px;background:#fff;border-radius:.25em;padding:1em}.vertical-timeline-content:after{content:"";display:table;clear:both}.vertical-timeline-content h2{font-weight:400;margin-top:4px}.vertical-timeline-content p{margin:1em 0;line-height:1.6}.vertical-timeline-content .vertical-date{float:left;font-weight:500}.vertical-date small{color:#1ab394;font-weight:400}.vertical-timeline-content::before{content:'';position:absolute;top:16px;right:100%;height:0;width:0;border:7px solid transparent;border-right:7px solid #fff}@media only screen and (min-width:768px){.vertical-timeline-content h2{font-size:18px}.vertical-timeline-content p{font-size:13px}}@media only screen and (min-width:1170px){.center-orientation .vertical-timeline-content{margin-left:0;padding:1.6em;width:45%}.center-orientation .vertical-timeline-content::before{top:24px;left:100%;border-color:transparent;border-left-color:#fff}.center-orientation .vertical-timeline-content .btn{float:left}.center-orientation .vertical-timeline-content .vertical-date{position:absolute;width:100%;left:122%;top:2px;font-size:14px}.center-orientation .vertical-timeline-block:nth-child(even) .vertical-timeline-content{float:right}.center-orientation .vertical-timeline-block:nth-child(even) .vertical-timeline-content::before{top:24px;left:auto;right:100%;border-color:transparent;border-right-color:#fff}.center-orientation .vertical-timeline-block:nth-child(even) .vertical-timeline-content .btn{float:right}.center-orientation .vertical-timeline-block:nth-child(even) .vertical-timeline-content .vertical-date{left:auto;right:122%;text-align:right}.center-orientation .cssanimations .vertical-timeline-content.is-hidden{visibility:hidden}}.sidebard-panel{width:220px;background:#ebebed;padding:10px 20px;position:absolute;right:0}.sidebard-panel .feed-element img.img-circle{width:32px;height:32px}.media-body,.sidebard-panel .feed-element,.sidebard-panel p{font-size:12px}.sidebard-panel .feed-element{margin-top:20px;padding-bottom:0}.sidebard-panel .list-group{margin-bottom:10px}.sidebard-panel .list-group .list-group-item{padding:5px 0;font-size:12px;border:0}.sidebar-content .wrapper,.wrapper.sidebar-content{padding-right:240px!important}#right-sidebar{background-color:#fff;border-left:1px solid #e7eaec;border-top:1px solid #e7eaec;overflow:hidden;position:fixed;top:60px;width:260px!important;z-index:1009;bottom:0;right:-260px}#right-sidebar.sidebar-open{right:0}#right-sidebar.sidebar-open.sidebar-top{top:0;border-top:none}.sidebar-container ul.nav-tabs{border:none}.sidebar-container ul.nav-tabs.navs-4 li{width:25%}.sidebar-container ul.nav-tabs.navs-3 li{width:33.3333%}.sidebar-container ul.nav-tabs.navs-2 li{width:50%}.sidebar-container ul.nav-tabs li{border:none}.sidebar-container ul.nav-tabs li a{border:none;padding:12px 10px;margin:0;border-radius:0;background:#2f4050;color:#fff;text-align:center;border-right:1px solid #334556}.sidebar-container ul.nav-tabs li.active a{border:none;background:#f9f9f9;color:#676a6c;font-weight:700}.sidebar-container .nav-tabs>li.active>a:focus,.sidebar-container .nav-tabs>li.active>a:hover{border:none}.sidebar-container ul.sidebar-list{margin:0;padding:0}.sidebar-container ul.sidebar-list li{border-bottom:1px solid #e7eaec;padding:15px 20px;list-style:none;font-size:12px}.sidebar-container .sidebar-message:nth-child(2n+2){background:#f9f9f9}.sidebar-container ul.sidebar-list li a{text-decoration:none;color:inherit}.sidebar-container .sidebar-content{padding:15px 20px;font-size:12px}.sidebar-container .sidebar-title{background:#f9f9f9;padding:20px;border-bottom:1px solid #e7eaec}.sidebar-container .sidebar-title h3{margin-bottom:3px;padding-left:2px}.sidebar-container .tab-content h4{margin-bottom:5px}.sidebar-container .sidebar-message>a>.pull-left{margin-right:10px}.sidebar-container .sidebar-message>a{text-decoration:none;color:inherit}.sidebar-container .sidebar-message{padding:15px 20px}.sidebar-container .sidebar-message .message-avatar{height:38px;width:38px;border-radius:50%}.sidebar-container .setings-item{padding:15px 20px;border-bottom:1px solid #e7eaec}body{font-family:"open sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;color:#676a6c;overflow-x:hidden}body,body.full-height-layout #page-wrapper,body.full-height-layout #wrapper,html{height:100%;}#page-wrapper{min-height:auto}body.boxed-layout{background:url(patterns/shattered.png)}body.boxed-layout #wrapper{background-color:#2f4050;max-width:1200px;margin:0 auto}.boxed-layout #wrapper.top-navigation,.top-navigation.boxed-layout #wrapper{max-width:1300px!important}.block{display:block}.clear{display:block;overflow:hidden}a{cursor:pointer}a:focus,a:hover{text-decoration:none}.border-bottom{border-bottom:1px solid #e7eaec!important}.font-bold{font-weight:600}.font-noraml{font-weight:400}.text-uppercase{text-transform:uppercase}.b-r{border-right:1px solid #e7eaec}.hr-line-dashed{border-top:1px dashed #e7eaec;color:#fff;background-color:#fff;height:1px;margin:20px 0}.hr-line-solid{border-bottom:1px solid #e7eaec;background-color:rgba(0,0,0,0);border-style:solid!important;margin-top:15px;margin-bottom:15px}video{width:100%!important;height:auto!important}.gallery>.row>div{margin-bottom:15px}.fancybox img{margin-bottom:5px;width:24%}.note-editor{height:auto!important;min-height:100px;border:solid 1px #e5e6e7}.modal-content{background-clip:padding-box;background-color:#FFF;border:1px solid rgba(0,0,0,0);border-radius:4px;box-shadow:0 1px 3px rgba(0,0,0,.3);outline:0 none}.modal-dialog{z-index:1200}.modal-body{padding:20px 30px 30px}.inmodal .modal-body{background:#f8fafb}.inmodal .modal-header{padding:30px 15px;text-align:center}.animated.modal.fade .modal-dialog{-webkit-transform:none;-ms-transform:none;transform:none}.inmodal .modal-title{font-size:26px}.inmodal .modal-icon{font-size:84px;color:#e2e3e3}.modal-footer{margin-top:0}#wrapper{width:100%;overflow-x:hidden;background-color:#2f4050}.wrapper{padding:0 20px}.wrapper-content{padding:20px}#page-wrapper{padding:0 15px;position:inherit;margin:0 0 0 220px}.title-action{text-align:right;padding-top:30px}.ibox-content h1,.ibox-content h2,.ibox-content h3,.ibox-content h4,.ibox-content h5,.ibox-title h1,.ibox-title h2,.ibox-title h3,.ibox-title h4,.ibox-title h5{margin-top:5px}ol.unstyled,ul.unstyled{list-style:none outside none;margin-left:0}.big-icon{font-size:160px;color:#e5e6e7}.footer{background:none repeat scroll 0 0 #fff;border-top:1px solid #e7eaec;overflow:hidden;padding:10px 20px;margin:0 -15px;height:36px}.footer.fixed_full{position:fixed;bottom:0;left:0;right:0;z-index:1000;padding:10px 20px;background:#fff;border-top:1px solid #e7eaec}.footer.fixed{position:fixed;bottom:0;left:0;right:0;z-index:1000;padding:10px 20px;background:#fff;border-top:1px solid #e7eaec;margin-left:220px}body.body-small.mini-navbar .footer.fixed,body.mini-navbar .footer.fixed{margin:0 0 0 70px}body.canvas-menu .footer.fixed,body.mini-navbar.canvas-menu .footer.fixed{margin:0!important}body.fixed-sidebar.body-small.mini-navbar .footer.fixed{margin:0 0 0 220px}body.body-small .footer.fixed{margin-left:0}.page-heading{border-top:0;padding:0 20px 20px}.panel-heading h1,.panel-heading h2{margin-bottom:5px}.content-tabs{position:relative;height:42px;background:#fafafa;line-height:40px}.content-tabs .roll-nav,.page-tabs-list{position:absolute;width:40px;height:40px;text-align:center;color:#999;z-index:2;top:0}.content-tabs .roll-left{left:0;border-right:solid 1px #eee}.content-tabs .roll-right{right:0;border-left:solid 1px #eee}.content-tabs button{background:#fff;border:0;height:40px;width:40px;outline:0}.content-tabs button:hover{background:#fafafa}nav.page-tabs{margin-left:40px;width:100000px;height:40px;overflow:hidden}nav.page-tabs .page-tabs-content{float:left}.page-tabs a{display:block;float:left;border-right:solid 1px #eee;padding:0 15px}.page-tabs a i:hover{color:#c00}.content-tabs .roll-nav:hover,.page-tabs a:hover{color:#777;background:#f2f2f2;cursor:pointer}.roll-right.J_tabRight{right:140px}.roll-right.btn-group{right:60px;width:80px;padding:0}.roll-right.btn-group button{width:80px}.roll-right.J_tabExit{background:#fff;height:40px;width:60px;outline:0}.dropdown-menu-right{left:auto}#content-main{height:calc(100% - 140px);overflow: hidden}.fixed-nav #content-main{height:calc(100% - 80px);overflow:hidden}.table-bordered{border:1px solid #EBEBEB}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{background-color:#F5F5F6}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #e7e7e7}.table>thead>tr>th{border-bottom:1px solid #DDD}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{border-top:1px solid #e7eaec;line-height:1.42857;padding:8px;vertical-align:middle}.panel.blank-panel{background:0 0;margin:0}.blank-panel .panel-heading{padding-bottom:0}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{-moz-border-bottom-colors:none;-moz-border-left-colors:none;-moz-border-right-colors:none;-moz-border-top-colors:none;background:0 0;border-color:#ddd #ddd rgba(0,0,0,0);border-bottom:#f3f3f4;-webkit-border-image:none;-o-border-image:none;border-image:none;border-style:solid;border-width:1px;color:#555;cursor:default}.nav.nav-tabs li{background:0 0;border:none}.nav-tabs>li>a{color:#A7B1C2;font-weight:600;padding:10px 20px 10px 25px}.nav-tabs>li>a:focus,.nav-tabs>li>a:hover{background-color:#e6e6e6;color:#676a6c}.ui-tab .tab-content{padding:20px 0}.no-padding{padding:0!important}.no-borders{border:none!important}.no-margins{margin:0!important}.no-top-border{border-top:0!important}.ibox-content.text-box{padding-bottom:0;padding-top:15px}.border-left-right{border-left:1px solid #e7eaec;border-right:1px solid #e7eaec;border-top:none;border-bottom:none}.border-left{border-left:1px solid #e7eaec;border-right:none;border-top:none;border-bottom:none}.border-right{border-left:none;border-right:1px solid #e7eaec;border-top:none;border-bottom:none}.full-width{width:100%!important}.link-block{font-size:12px;padding:10px}.nav.navbar-top-links .link-block a{font-size:12px}.link-block a{font-size:10px;color:inherit}body.mini-navbar .branding{display:none}img.circle-border{border:6px solid #FFF;border-radius:50%}.branding{float:left;color:#FFF;font-size:18px;font-weight:600;padding:17px 20px;text-align:center;background-color:#1ab394}.login-panel{margin-top:25%}.page-header{padding:20px 0 9px;margin:0 0 20px;border-bottom:1px solid #eee}.fontawesome-icon-list{margin-top:22px}.fontawesome-icon-list .fa-hover a{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;color:#222;line-height:32px;height:32px;padding-left:10px;border-radius:4px}.fontawesome-icon-list .fa-hover a .fa{width:32px;font-size:14px;display:inline-block;text-align:right;margin-right:10px}.fontawesome-icon-list .fa-hover a:hover{background-color:#1d9d74;color:#fff;text-decoration:none}.fontawesome-icon-list .fa-hover a:hover .fa{font-size:30px;vertical-align:-6px}.fontawesome-icon-list .fa-hover a:hover .text-muted{color:#bbe2d5}.feature-list .col-md-4{margin-bottom:22px}.feature-list h4 .fa:before{vertical-align:-10%;font-size:28px;display:inline-block;width:1.07142857em;text-align:center;margin-right:5px}.ui-draggable .ibox-title{cursor:move}.breadcrumb{background-color:#fff;padding:0;margin-bottom:0}.breadcrumb>.active,.breadcrumb>li a{color:inherit}code{background-color:#F9F2F4;border-radius:4px;color:#ca4440;font-size:90%;padding:2px 4px;white-space:nowrap}.ibox{clear:both;margin-bottom:25px;margin-top:0;padding:0}.ibox.collapsed .ibox-content{display:none}.ibox.collapsed .fa.fa-chevron-up:before{content:"\f078"}.ibox.collapsed .fa.fa-chevron-down:before{content:"\f077"}.ibox:after,.ibox:before{display:table}.ibox-title{-moz-border-bottom-colors:none;-moz-border-left-colors:none;-moz-border-right-colors:none;-moz-border-top-colors:none;background-color:#fff;border-color:#e7eaec;-webkit-border-image:none;-o-border-image:none;border-image:none;border-style:solid solid none;border-width:4px 0 0;color:inherit;margin-bottom:0;padding:14px 15px 7px;min-height:48px}.ibox-content{background-color:#fff;color:inherit;padding:15px 20px 20px;border-color:#e7eaec;-webkit-border-image:none;-o-border-image:none;border-image:none;border-style:solid solid none;border-width:1px 0}table.table-mail tr td{padding:12px}.table-mail .check-mail{padding-left:20px}.table-mail .mail-date{padding-right:20px}.check-mail,.star-mail{width:40px}.unread td,.unread td a{font-weight:600;color:inherit}.read td,.read td a{font-weight:400;color:inherit}.unread td{background-color:#f9f8f8}.ibox-content{clear:both}.ibox-heading{background-color:#f3f6fb;border-bottom:none}.ibox-heading h3{font-weight:200;font-size:24px}.ibox-title h5{display:inline-block;font-size:14px;margin:0 0 7px;padding:0;text-overflow:ellipsis;float:left}.ibox-title .label{float:left;margin-left:4px}.ibox-tools{display:inline-block;float:right;margin-top:0;position:relative;padding:0}.ibox-tools a{cursor:pointer;margin-left:5px;color:#c4c4c4}.ibox-tools a.btn-primary{color:#fff}.ibox-tools .dropdown-menu>li>a{padding:4px 10px;font-size:12px}.ibox .open>.dropdown-menu{left:auto;right:0}.gray-bg{background-color:#f3f3f4}.white-bg{background-color:#fff}.navy-bg{background-color:#1ab394;color:#fff}.blue-bg{background-color:#1c84c6;color:#fff}.lazur-bg{background-color:#23c6c8;color:#fff}.yellow-bg{background-color:#f8ac59;color:#fff}.red-bg{background-color:#ed5565;color:#fff}.black-bg{background-color:#262626}.panel-primary{border-color:#1ab394}.panel-primary>.panel-heading{background-color:#1ab394;border-color:#1ab394}.panel-success{border-color:#1c84c6}.panel-success>.panel-heading{background-color:#1c84c6;border-color:#1c84c6;color:#fff}.panel-info{border-color:#23c6c8}.panel-info>.panel-heading{background-color:#23c6c8;border-color:#23c6c8;color:#fff}.panel-warning{border-color:#f8ac59}.panel-warning>.panel-heading{background-color:#f8ac59;border-color:#f8ac59;color:#fff}.panel-danger{border-color:#ed5565}.panel-danger>.panel-heading{background-color:#ed5565;border-color:#ed5565;color:#fff}.progress-bar{background-color:#1ab394}.progress-small,.progress-small .progress-bar{height:10px}.progress-mini,.progress-small{margin-top:5px}.progress-mini,.progress-mini .progress-bar{height:5px;margin-bottom:0}.progress-bar-navy-light{background-color:#3dc7ab}.progress-bar-success{background-color:#1c84c6}.progress-bar-info{background-color:#23c6c8}.progress-bar-warning{background-color:#f8ac59}.progress-bar-danger{background-color:#ed5565}.panel-title{font-size:inherit}.jumbotron{border-radius:6px;padding:40px}.jumbotron h1{margin-top:0}.text-navy{color:#1ab394}.text-primary{color:inherit}.text-success{color:#1c84c6}.text-info{color:#23c6c8}.text-warning{color:#f8ac59}.text-danger{color:#ed5565}.text-muted{color:#888}.simple_tag{background-color:#f3f3f4;border:1px solid #e7eaec;border-radius:2px;color:inherit;font-size:10px;margin-right:5px;margin-top:5px;padding:5px 12px;display:inline-block}.img-shadow{box-shadow:0 0 3px 0 #919191}.ComposeEmail .navbar.navbar-static-top,.Dashboard_2 .navbar.navbar-static-top,.Dashboard_3 .navbar.navbar-static-top,.Dashboard_4_1 .navbar.navbar-static-top,.EmailView .navbar.navbar-static-top,.Inbox .navbar.navbar-static-top,.dashboards\.dashboard_2 nav.navbar,.dashboards\.dashboard_3 nav.navbar,.dashboards\.dashboard_4_1 nav.navbar,.mailbox\.email_compose nav.navbar,.mailbox\.email_view nav.navbar,.mailbox\.inbox nav.navbar{background:#fff}a.close-canvas-menu{position:absolute;top:10px;right:15px;z-index:1011;color:#a7b1c2}a.close-canvas-menu:hover{color:#fff}.full-height{height:100%}.fh-breadcrumb{height:calc(100% - 196px);margin:0 -15px;position:relative}.fh-no-breadcrumb{height:calc(100% - 99px);margin:0 -15px;position:relative}.fh-column{background:#fff;height:100%;width:240px;float:left}.modal-backdrop{z-index:2040!important}.modal{z-index:2050!important}.spiner-example{height:200px;padding-top:70px}.p-xxs{padding:5px}.p-xs{padding:10px}.p-sm{padding:15px}.p-m{padding:20px}.p-md{padding:25px}.p-lg{padding:30px}.p-xl{padding:40px}.m-xxs{margin:2px 4px}.m-xs{margin:5px}.m-sm{margin:10px}.m{margin:15px}.m-md{margin:20px}.m-lg{margin:30px}.m-xl{margin:50px}.m-n{margin:0!important}.m-l-none{margin-left:0}.m-l-xs{margin-left:5px}.m-l-sm{margin-left:10px}.m-l{margin-left:15px}.m-l-md{margin-left:20px}.m-l-lg{margin-left:30px}.m-l-xl{margin-left:40px}.m-l-n-xxs{margin-left:-1px}.m-l-n-xs{margin-left:-5px}.m-l-n-sm{margin-left:-10px}.m-l-n{margin-left:-15px}.m-l-n-md{margin-left:-20px}.m-l-n-lg{margin-left:-30px}.m-l-n-xl{margin-left:-40px}.m-t-none{margin-top:0}.m-t-xxs{margin-top:1px}.m-t-xs{margin-top:5px}.m-t-sm{margin-top:10px}.m-t{margin-top:15px}.m-t-md{margin-top:20px}.m-t-lg{margin-top:30px}.m-t-xl{margin-top:40px}.m-t-n-xxs{margin-top:-1px}.m-t-n-xs{margin-top:-5px}.m-t-n-sm{margin-top:-10px}.m-t-n{margin-top:-15px}.m-t-n-md{margin-top:-20px}.m-t-n-lg{margin-top:-30px}.m-t-n-xl{margin-top:-40px}.m-r-none{margin-right:0}.m-r-xxs{margin-right:1px}.m-r-xs{margin-right:5px}.m-r-sm{margin-right:10px}.m-r{margin-right:15px}.m-r-md{margin-right:20px}.m-r-lg{margin-right:30px}.m-r-xl{margin-right:40px}.m-r-n-xxs{margin-right:-1px}.m-r-n-xs{margin-right:-5px}.m-r-n-sm{margin-right:-10px}.m-r-n{margin-right:-15px}.m-r-n-md{margin-right:-20px}.m-r-n-lg{margin-right:-30px}.m-r-n-xl{margin-right:-40px}.m-b-none{margin-bottom:0}.m-b-xxs{margin-bottom:1px}.m-b-xs{margin-bottom:5px}.m-b-sm{margin-bottom:10px}.m-b{margin-bottom:15px}.m-b-md{margin-bottom:20px}.m-b-lg{margin-bottom:30px}.m-b-xl{margin-bottom:40px}.m-b-n-xxs{margin-bottom:-1px}.m-b-n-xs{margin-bottom:-5px}.m-b-n-sm{margin-bottom:-10px}.m-b-n{margin-bottom:-15px}.m-b-n-md{margin-bottom:-20px}.m-b-n-lg{margin-bottom:-30px}.m-b-n-xl{margin-bottom:-40px}.space-15{margin:15px 0}.space-20{margin:20px 0}.space-25{margin:25px 0}.space-30{margin:30px 0}body.modal-open{padding-right:inherit!important}.search-form{margin-top:10px}.search-result h3{margin-bottom:0;color:#1E0FBE}.search-result .search-link{color:#006621}.search-result p{font-size:12px;margin-top:5px}.contact-box{background-color:#fff;border:1px solid #e7eaec;padding:20px;margin-bottom:20px}.contact-box a{color:inherit}.invoice-table tbody>tr>td:last-child,.invoice-table tbody>tr>td:nth-child(2),.invoice-table tbody>tr>td:nth-child(3),.invoice-table tbody>tr>td:nth-child(4),.invoice-table thead>tr>th:last-child,.invoice-table thead>tr>th:nth-child(2),.invoice-table thead>tr>th:nth-child(3),.invoice-table thead>tr>th:nth-child(4),.invoice-total>tbody>tr>td:first-child{text-align:right}.invoice-total>tbody>tr>td{border:0 none}.invoice-total>tbody>tr>td:last-child{border-bottom:1px solid #DDD;text-align:right;width:15%}.middle-box{max-width:400px;z-index:100;margin:0 auto;padding-top:40px}.lockscreen.middle-box{width:200px;padding-top:110px}.loginscreen.middle-box{width:300px}.loginColumns{max-width:800px;margin:0 auto;padding:100px 20px 20px}.passwordBox{max-width:460px;margin:0 auto;padding:100px 20px 20px}.logo-name{color:#e6e6e6;font-size:180px;font-weight:800;letter-spacing:-10px;margin-bottom:0}.middle-box h1{font-size:170px}.wrapper .middle-box{margin-top:140px}.lock-word{z-index:10;position:absolute;top:110px;left:50%;margin-left:-470px}.lock-word span{font-size:100px;font-weight:600;color:#e9e9e9;display:inline-block}.lock-word .first-word{margin-right:160px}.dashboard-header{border-top:0;padding:20px}.dashboard-header h2{margin-top:10px;font-size:26px}.fist-item{border-top:none!important}.statistic-box{margin-top:40px}.dashboard-header .list-group-item span.label{margin-right:10px}.list-group.clear-list .list-group-item{border-top:1px solid #e7eaec;border-bottom:0;border-right:0;border-left:0;padding:10px 0}ul.clear-list:first-child{border-top:none!important}.timeline-item .date i{position:absolute;top:0;right:0;padding:5px;width:30px;text-align:center;border-top:1px solid #e7eaec;border-bottom:1px solid #e7eaec;border-left:1px solid #e7eaec;background:#f8f8f8}.timeline-item .date{text-align:right;width:110px;position:relative;padding-top:30px}.timeline-item .content{border-left:1px solid #e7eaec;border-top:1px solid #e7eaec;padding-top:10px;min-height:100px}.timeline-item .content:hover{background:#f6f6f6}ul.notes li,ul.tag-list li{list-style:none}ul.notes li h4{margin-top:20px;font-size:16px}ul.notes li div{position:relative}ul.notes li div small{position:absolute;top:5px;right:5px;font-size:10px}ul.notes li div a{position:absolute;right:10px;bottom:10px;color:inherit}ul.notes li{margin:10px 40px 50px 0;float:left}ul.notes li div p{font-size:12px}ul.notes li div{-webkit-transform:rotate(-6deg);-o-transform:rotate(-6deg);-moz-transform:rotate(-6deg)}ul.notes li:nth-child(even) div{-o-transform:rotate(4deg);-webkit-transform:rotate(4deg);-moz-transform:rotate(4deg);position:relative;top:5px}ul.notes li:nth-child(3n) div{-o-transform:rotate(-3deg);-webkit-transform:rotate(-3deg);-moz-transform:rotate(-3deg);position:relative;top:-5px}ul.notes li:nth-child(5n) div{-o-transform:rotate(5deg);-webkit-transform:rotate(5deg);-moz-transform:rotate(5deg);position:relative;top:-10px}ul.notes li div:focus,ul.notes li div:hover{-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-o-transform:scale(1.1);position:relative;z-index:5}ul.notes li div{text-decoration:none;color:#000;background:#ffc;display:block;height:210px;width:210px;padding:1em;box-shadow:5px 5px 7px rgba(33,33,33,.7);-webkit-transition:-webkit-transform .15s linear}.file-box{float:left;width:220px}.file-manager h5{text-transform:uppercase}.file-manager{list-style:none outside none;margin:0;padding:0}.folder-list li a{color:#666;display:block;padding:5px 0}.folder-list li{border-bottom:1px solid #e7eaec;display:block}.folder-list li i{margin-right:8px;color:#3d4d5d}.category-list li a{color:#666;display:block;padding:5px 0}.category-list li{display:block}.category-list li i{margin-right:8px;color:#3d4d5d}.category-list li a .text-navy{color:#1ab394}.category-list li a .text-primary{color:#1c84c6}.category-list li a .text-info{color:#23c6c8}.category-list li a .text-danger{color:#EF5352}.category-list li a .text-warning{color:#F8AC59}.file-manager h5.tag-title{margin-top:20px}.tag-list li{float:left}.tag-list li a{font-size:10px;background-color:#f3f3f4;padding:5px 12px;color:inherit;border-radius:2px;border:1px solid #e7eaec;margin-right:5px;margin-top:5px;display:block}.file{border:1px solid #e7eaec;padding:0;background-color:#fff;position:relative;margin-bottom:20px;margin-right:20px}.file-manager .hr-line-dashed{margin:15px 0}.file .icon,.file .image{height:100px;overflow:hidden}.file .icon{padding:15px 10px;text-align:center}.file-control{color:inherit;font-size:11px;margin-right:10px}.file-control.active{text-decoration:underline}.file .icon i{font-size:70px;color:#dadada}.file .file-name{padding:10px;background-color:#f8f8f8;border-top:1px solid #e7eaec}.file-name small{color:#676a6c}.corner{position:absolute;display:inline-block;width:0;height:0;line-height:0;border:.6em solid transparent;border-right:.6em solid #f1f1f1;border-bottom:.6em solid #f1f1f1;right:0;bottom:0}a.compose-mail{padding:8px 10px}.mail-search{max-width:300px}.profile-content{border-top:none!important}.feed-activity-list .feed-element{border-bottom:1px solid #e7eaec}.feed-element:first-child{margin-top:0}.feed-element{padding-bottom:15px}.feed-element,.feed-element .media{margin-top:15px}.feed-element,.media-body{overflow:hidden}.feed-element>.pull-left{margin-right:10px}.dropdown-messages-box img.img-circle,.feed-element img.img-circle{width:38px;height:38px}.feed-element .well{border:1px solid #e7eaec;box-shadow:none;margin-top:10px;margin-bottom:5px;padding:10px 20px;font-size:11px;line-height:16px}.feed-element .actions{margin-top:10px}.feed-element .photos{margin:10px 0}.feed-photo{max-height:180px;border-radius:4px;overflow:hidden;margin-right:10px;margin-bottom:10px}.mail-box{background-color:#fff;border:1px solid #e7eaec;border-top:0;padding:0;margin-bottom:20px}.mail-box-header{background-color:#fff;border:1px solid #e7eaec;border-bottom:0;padding:30px 20px 20px}.mail-box-header h2{margin-top:0}.mailbox-content .tag-list li a{background:#fff}.mail-body{border-top:1px solid #e7eaec;padding:20px}.mail-text{border-top:1px solid #e7eaec}.mail-text .note-toolbar{padding:10px 15px}.mail-body .form-group{margin-bottom:5px}.mail-text .note-editor .note-toolbar{background-color:#F9F8F8}.mail-attachment{border-top:1px solid #e7eaec;padding:20px;font-size:12px}.mailbox-content{background:0 0;border:none;padding:10px}.mail-ontact{width:23%}.project-actions,.project-people{text-align:right;vertical-align:middle}dd.project-people{text-align:left;margin-top:5px}.project-people img{width:32px;height:32px}.project-title a{font-size:14px;color:#676a6c;font-weight:600}.project-list table tr td{border-top:none;border-bottom:1px solid #e7eaec;padding:15px 10px;vertical-align:middle}.project-manager .tag-list li a{font-size:10px;background-color:#fff;padding:5px 12px;color:inherit;border-radius:2px;border:1px solid #e7eaec;margin-right:5px;margin-top:5px;display:block}.project-files li a{font-size:11px;color:#676a6c;margin-left:10px;line-height:22px}.faq-item{padding:20px;margin-bottom:2px;background:#fff}.faq-question{font-size:18px;font-weight:600;color:#1ab394;display:block}.faq-question:hover{color:#179d82}.faq-answer{margin-top:10px;background:#f3f3f4;border:1px solid #e7eaec;border-radius:3px;padding:15px}.faq-item .tag-item{background:#f3f3f4;padding:2px 6px;font-size:10px;text-transform:uppercase}.message-input{height:90px!important}.chat-avatar{white:36px;height:36px;float:left;margin-right:10px}.chat-user-name{padding:10px}.chat-user{padding:8px 10px;border-bottom:1px solid #e7eaec}.chat-user a{color:inherit}.chat-view{z-index:20012}.chat-statistic,.chat-users{margin-left:-30px}@media (max-width:992px){.chat-statistic,.chat-users{margin-left:0}}.chat-view .ibox-content{padding:0}.chat-message{padding:10px 20px}.message-avatar{height:48px;width:48px;border:1px solid #e7eaec;border-radius:4px;margin-top:1px}.chat-discussion .chat-message:nth-child(2n+1) .message-avatar{float:left;margin-right:10px}.chat-discussion .chat-message:nth-child(2n) .message-avatar{float:right;margin-left:10px}.message{background-color:#fff;border:1px solid #e7eaec;text-align:left;display:block;padding:10px 20px;position:relative;border-radius:4px}.chat-discussion .chat-message:nth-child(2n+1) .message-date{float:right}.chat-discussion .chat-message:nth-child(2n) .message-date{float:left}.chat-discussion .chat-message:nth-child(2n+1) .message{text-align:left;margin-left:55px}.chat-discussion .chat-message:nth-child(2n) .message{text-align:right;margin-right:55px}.message-date{font-size:10px;color:#888}.message-content{display:block}.chat-discussion{background:#eee;padding:15px;height:400px;overflow-y:auto}.chat-users{overflow-y:auto;height:400px}.chat-message-form .form-group{margin-bottom:0}.jstree-open>.jstree-anchor>.fa-folder:before{content:"\f07c"}.jstree-default .jstree-icon.none{width:0}.clients-list{margin-top:20px}.clients-list .tab-pane{position:relative;height:600px}.client-detail{position:relative;height:620px}.clients-list table tr td{height:46px;vertical-align:middle;border:none}.client-link{font-weight:600;color:inherit}.client-link:hover{color:inherit}.client-avatar{width:42px}.client-avatar img{width:28px;height:28px;border-radius:50%}.contact-type{width:20px;color:#c1c3c4}.client-status{text-align:left}.client-detail .vertical-timeline-content p{margin:0}.client-detail .vertical-timeline-icon.gray-bg{color:#a7aaab}.clients-list .nav-tabs>li.active>a,.clients-list .nav-tabs>li.active>a:focus,.clients-list .nav-tabs>li.active>a:hover{border-bottom:1px solid #fff}.blog h2{font-weight:700}.blog .btn,.blog h5{margin:0 0 5px}.article h1{font-size:48px;font-weight:700;color:#2F4050}.article p{font-size:15px;line-height:26px}.article-title{text-align:center;margin:60px 0 40px}.article .ibox-content{padding:40px}.issue-tracker .btn-link{color:#1ab394}table.issue-tracker tbody tr td{vertical-align:middle;height:50px}.issue-info{width:50%}.issue-info a{font-weight:600;color:#676a6c}.issue-info small{display:block}.team-members{margin:10px 0}.team-members img.img-circle{width:42px;height:42px;margin-bottom:5px}.sortable-list{padding:10px 0}.agile-list{list-style:none;margin:0}.agile-list li{background:#FAFAFB;border:1px solid #e7eaec;margin:0 0 10px;padding:10px;border-radius:2px}.agile-list li:hover{cursor:pointer;background:#fff}.agile-list li.warning-element{border-left:3px solid #f8ac59}.agile-list li.danger-element{border-left:3px solid #ed5565}.agile-list li.info-element{border-left:3px solid #1c84c6}.agile-list li.success-element{border-left:3px solid #1ab394}.agile-detail{margin-top:5px;font-size:12px}ins{background-color:#c6ffc6;text-decoration:none}del{background-color:#ffc6c6}#small-chat{position:fixed;bottom:50px;right:26px;z-index:100}#small-chat .badge{position:absolute;top:-3px;right:-4px}.open-small-chat{height:38px;width:38px;display:block;background:#1ab394;padding:9px 8px;text-align:center;color:#fff;border-radius:50%}.open-small-chat:hover{color:#fff;background:#1ab394}.small-chat-box{display:none;position:fixed;bottom:50px;right:80px;background:#fff;border:1px solid #e7eaec;width:230px;height:320px;border-radius:4px}.small-chat-box.ng-small-chat{display:block}.body-small .small-chat-box{bottom:70px;right:20px}.small-chat-box.active{display:block}.small-chat-box .heading{background:#2f4050;padding:8px 15px;font-weight:700;color:#fff}.small-chat-box .chat-date{opacity:.6;font-size:10px;font-weight:400}.small-chat-box .content{padding:15px}.small-chat-box .content .author-name{font-weight:700;margin-bottom:3px;font-size:11px}.small-chat-box .content>div{padding-bottom:20px}.small-chat-box .content .chat-message{padding:5px 10px;border-radius:6px;font-size:11px;line-height:14px;max-width:80%;background:#f3f3f4;margin-bottom:10px}.small-chat-box .content .chat-message.active{background:#1ab394;color:#fff}.small-chat-box .content .left{text-align:left;clear:both}.small-chat-box .content .left .chat-message{float:left}.small-chat-box .content .right{text-align:right;clear:both}.small-chat-box .content .right .chat-message{float:right}.small-chat-box .form-chat{padding:10px}.sk-spinner-rotating-plane.sk-spinner{width:30px;height:30px;background-color:#1ab394;margin:0 auto;-webkit-animation:sk-rotatePlane 1.2s infinite ease-in-out;animation:sk-rotatePlane 1.2s infinite ease-in-out}@-webkit-keyframes sk-rotatePlane{0%{-webkit-transform:perspective(120px) rotateX(0deg) rotateY(0deg);transform:perspective(120px) rotateX(0deg) rotateY(0deg)}50%{-webkit-transform:perspective(120px) rotateX(-180.1deg) rotateY(0deg);transform:perspective(120px) rotateX(-180.1deg) rotateY(0deg)}100%{-webkit-transform:perspective(120px) rotateX(-180deg) rotateY(-179.9deg);transform:perspective(120px) rotateX(-180deg) rotateY(-179.9deg)}}@keyframes sk-rotatePlane{0%{-webkit-transform:perspective(120px) rotateX(0deg) rotateY(0deg);transform:perspective(120px) rotateX(0deg) rotateY(0deg)}50%{-webkit-transform:perspective(120px) rotateX(-180.1deg) rotateY(0deg);transform:perspective(120px) rotateX(-180.1deg) rotateY(0deg)}100%{-webkit-transform:perspective(120px) rotateX(-180deg) rotateY(-179.9deg);transform:perspective(120px) rotateX(-180deg) rotateY(-179.9deg)}}.sk-spinner-double-bounce.sk-spinner{width:40px;height:40px;position:relative;margin:0 auto}.sk-spinner-double-bounce .sk-double-bounce1,.sk-spinner-double-bounce .sk-double-bounce2{width:100%;height:100%;border-radius:50%;background-color:#1ab394;opacity:.6;position:absolute;top:0;left:0;-webkit-animation:sk-doubleBounce 2s infinite ease-in-out;animation:sk-doubleBounce 2s infinite ease-in-out}.sk-spinner-double-bounce .sk-double-bounce2{-webkit-animation-delay:-1s;animation-delay:-1s}@-webkit-keyframes sk-doubleBounce{0%,100%{-webkit-transform:scale(0);transform:scale(0)}50%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes sk-doubleBounce{0%,100%{-webkit-transform:scale(0);transform:scale(0)}50%{-webkit-transform:scale(1);transform:scale(1)}}.sk-spinner-wave.sk-spinner{margin:0 auto;width:50px;height:30px;text-align:center;font-size:10px}.sk-spinner-wave div{background-color:#1ab394;height:100%;width:6px;display:inline-block;-webkit-animation:sk-waveStretchDelay 1.2s infinite ease-in-out;animation:sk-waveStretchDelay 1.2s infinite ease-in-out}.sk-spinner-wave .sk-rect2{-webkit-animation-delay:-1.1s;animation-delay:-1.1s}.sk-spinner-wave .sk-rect3{-webkit-animation-delay:-1s;animation-delay:-1s}.sk-spinner-wave .sk-rect4{-webkit-animation-delay:-.9s;animation-delay:-.9s}.sk-spinner-wave .sk-rect5{-webkit-animation-delay:-.8s;animation-delay:-.8s}@-webkit-keyframes sk-waveStretchDelay{0%,100%,40%{-webkit-transform:scaleY(0.4);transform:scaleY(0.4)}20%{-webkit-transform:scaleY(1);transform:scaleY(1)}}@keyframes sk-waveStretchDelay{0%,100%,40%{-webkit-transform:scaleY(0.4);transform:scaleY(0.4)}20%{-webkit-transform:scaleY(1);transform:scaleY(1)}}.sk-spinner-wandering-cubes.sk-spinner{margin:0 auto;width:32px;height:32px;position:relative}.sk-spinner-wandering-cubes .sk-cube1,.sk-spinner-wandering-cubes .sk-cube2{background-color:#1ab394;width:10px;height:10px;position:absolute;top:0;left:0;-webkit-animation:sk-wanderingCubeMove 1.8s infinite ease-in-out;animation:sk-wanderingCubeMove 1.8s infinite ease-in-out}.sk-spinner-wandering-cubes .sk-cube2{-webkit-animation-delay:-.9s;animation-delay:-.9s}@-webkit-keyframes sk-wanderingCubeMove{25%{-webkit-transform:translateX(42px) rotate(-90deg) scale(0.5);transform:translateX(42px) rotate(-90deg) scale(0.5)}50%{-webkit-transform:translateX(42px) translateY(42px) rotate(-179deg);transform:translateX(42px) translateY(42px) rotate(-179deg)}50.1%{-webkit-transform:translateX(42px) translateY(42px) rotate(-180deg);transform:translateX(42px) translateY(42px) rotate(-180deg)}75%{-webkit-transform:translateX(0px) translateY(42px) rotate(-270deg) scale(0.5);transform:translateX(0px) translateY(42px) rotate(-270deg) scale(0.5)}100%{-webkit-transform:rotate(-360deg);transform:rotate(-360deg)}}@keyframes sk-wanderingCubeMove{25%{-webkit-transform:translateX(42px) rotate(-90deg) scale(0.5);transform:translateX(42px) rotate(-90deg) scale(0.5)}50%{-webkit-transform:translateX(42px) translateY(42px) rotate(-179deg);transform:translateX(42px) translateY(42px) rotate(-179deg)}50.1%{-webkit-transform:translateX(42px) translateY(42px) rotate(-180deg);transform:translateX(42px) translateY(42px) rotate(-180deg)}75%{-webkit-transform:translateX(0px) translateY(42px) rotate(-270deg) scale(0.5);transform:translateX(0px) translateY(42px) rotate(-270deg) scale(0.5)}100%{-webkit-transform:rotate(-360deg);transform:rotate(-360deg)}}.sk-spinner-pulse.sk-spinner{width:40px;height:40px;margin:0 auto;background-color:#1ab394;border-radius:100%;-webkit-animation:sk-pulseScaleOut 1s infinite ease-in-out;animation:sk-pulseScaleOut 1s infinite ease-in-out}@-webkit-keyframes sk-pulseScaleOut{0%{-webkit-transform:scale(0);transform:scale(0)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:0}}@keyframes sk-pulseScaleOut{0%{-webkit-transform:scale(0);transform:scale(0)}100%{-webkit-transform:scale(1);transform:scale(1);opacity:0}}.sk-spinner-chasing-dots.sk-spinner{margin:0 auto;width:40px;height:40px;position:relative;text-align:center;-webkit-animation:sk-chasingDotsRotate 2s infinite linear;animation:sk-chasingDotsRotate 2s infinite linear}.sk-spinner-chasing-dots .sk-dot1,.sk-spinner-chasing-dots .sk-dot2{width:60%;height:60%;display:inline-block;position:absolute;top:0;background-color:#1ab394;border-radius:100%;-webkit-animation:sk-chasingDotsBounce 2s infinite ease-in-out;animation:sk-chasingDotsBounce 2s infinite ease-in-out}.sk-spinner-chasing-dots .sk-dot2{top:auto;bottom:0;-webkit-animation-delay:-1s;animation-delay:-1s}@-webkit-keyframes sk-chasingDotsRotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes sk-chasingDotsRotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes sk-chasingDotsBounce{0%,100%{-webkit-transform:scale(0);transform:scale(0)}50%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes sk-chasingDotsBounce{0%,100%{-webkit-transform:scale(0);transform:scale(0)}50%{-webkit-transform:scale(1);transform:scale(1)}}.sk-spinner-three-bounce.sk-spinner{margin:0 auto;width:70px;text-align:center}.sk-spinner-three-bounce div{width:18px;height:18px;background-color:#1ab394;border-radius:100%;display:inline-block;-webkit-animation:sk-threeBounceDelay 1.4s infinite ease-in-out;animation:sk-threeBounceDelay 1.4s infinite ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both}.sk-spinner-three-bounce .sk-bounce1{-webkit-animation-delay:-.32s;animation-delay:-.32s}.sk-spinner-three-bounce .sk-bounce2{-webkit-animation-delay:-.16s;animation-delay:-.16s}@-webkit-keyframes sk-threeBounceDelay{0%,100%,80%{-webkit-transform:scale(0);transform:scale(0)}40%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes sk-threeBounceDelay{0%,100%,80%{-webkit-transform:scale(0);transform:scale(0)}40%{-webkit-transform:scale(1);transform:scale(1)}}.sk-spinner-circle.sk-spinner{margin:0 auto;width:22px;height:22px;position:relative}.sk-spinner-circle .sk-circle{width:100%;height:100%;position:absolute;left:0;top:0}.sk-spinner-circle .sk-circle:before{content:'';display:block;margin:0 auto;width:20%;height:20%;background-color:#1ab394;border-radius:100%;-webkit-animation:sk-circleBounceDelay 1.2s infinite ease-in-out;animation:sk-circleBounceDelay 1.2s infinite ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both}.sk-spinner-circle .sk-circle2{-webkit-transform:rotate(30deg);-ms-transform:rotate(30deg);transform:rotate(30deg)}.sk-spinner-circle .sk-circle3{-webkit-transform:rotate(60deg);-ms-transform:rotate(60deg);transform:rotate(60deg)}.sk-spinner-circle .sk-circle4{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.sk-spinner-circle .sk-circle5{-webkit-transform:rotate(120deg);-ms-transform:rotate(120deg);transform:rotate(120deg)}.sk-spinner-circle .sk-circle6{-webkit-transform:rotate(150deg);-ms-transform:rotate(150deg);transform:rotate(150deg)}.sk-spinner-circle .sk-circle7{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.sk-spinner-circle .sk-circle8{-webkit-transform:rotate(210deg);-ms-transform:rotate(210deg);transform:rotate(210deg)}.sk-spinner-circle .sk-circle9{-webkit-transform:rotate(240deg);-ms-transform:rotate(240deg);transform:rotate(240deg)}.sk-spinner-circle .sk-circle10{-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.sk-spinner-circle .sk-circle11{-webkit-transform:rotate(300deg);-ms-transform:rotate(300deg);transform:rotate(300deg)}.sk-spinner-circle .sk-circle12{-webkit-transform:rotate(330deg);-ms-transform:rotate(330deg);transform:rotate(330deg)}.sk-spinner-circle .sk-circle2:before{-webkit-animation-delay:-1.1s;animation-delay:-1.1s}.sk-spinner-circle .sk-circle3:before{-webkit-animation-delay:-1s;animation-delay:-1s}.sk-spinner-circle .sk-circle4:before{-webkit-animation-delay:-.9s;animation-delay:-.9s}.sk-spinner-circle .sk-circle5:before{-webkit-animation-delay:-.8s;animation-delay:-.8s}.sk-spinner-circle .sk-circle6:before{-webkit-animation-delay:-.7s;animation-delay:-.7s}.sk-spinner-circle .sk-circle7:before{-webkit-animation-delay:-.6s;animation-delay:-.6s}.sk-spinner-circle .sk-circle8:before{-webkit-animation-delay:-.5s;animation-delay:-.5s}.sk-spinner-circle .sk-circle9:before{-webkit-animation-delay:-.4s;animation-delay:-.4s}.sk-spinner-circle .sk-circle10:before{-webkit-animation-delay:-.3s;animation-delay:-.3s}.sk-spinner-circle .sk-circle11:before{-webkit-animation-delay:-.2s;animation-delay:-.2s}.sk-spinner-circle .sk-circle12:before{-webkit-animation-delay:-.1s;animation-delay:-.1s}@-webkit-keyframes sk-circleBounceDelay{0%,100%,80%{-webkit-transform:scale(0);transform:scale(0)}40%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes sk-circleBounceDelay{0%,100%,80%{-webkit-transform:scale(0);transform:scale(0)}40%{-webkit-transform:scale(1);transform:scale(1)}}.sk-spinner-cube-grid.sk-spinner{width:30px;height:30px;margin:0 auto}.sk-spinner-cube-grid .sk-cube{width:33%;height:33%;background-color:#1ab394;float:left;-webkit-animation:sk-cubeGridScaleDelay 1.3s infinite ease-in-out;animation:sk-cubeGridScaleDelay 1.3s infinite ease-in-out}.sk-spinner-cube-grid .sk-cube:nth-child(1){-webkit-animation-delay:.2s;animation-delay:.2s}.sk-spinner-cube-grid .sk-cube:nth-child(2){-webkit-animation-delay:.3s;animation-delay:.3s}.sk-spinner-cube-grid .sk-cube:nth-child(3){-webkit-animation-delay:.4s;animation-delay:.4s}.sk-spinner-cube-grid .sk-cube:nth-child(4){-webkit-animation-delay:.1s;animation-delay:.1s}.sk-spinner-cube-grid .sk-cube:nth-child(5){-webkit-animation-delay:.2s;animation-delay:.2s}.sk-spinner-cube-grid .sk-cube:nth-child(6){-webkit-animation-delay:.3s;animation-delay:.3s}.sk-spinner-cube-grid .sk-cube:nth-child(7){-webkit-animation-delay:0s;animation-delay:0s}.sk-spinner-cube-grid .sk-cube:nth-child(8){-webkit-animation-delay:.1s;animation-delay:.1s}.sk-spinner-cube-grid .sk-cube:nth-child(9){-webkit-animation-delay:.2s;animation-delay:.2s}@-webkit-keyframes sk-cubeGridScaleDelay{0%,100%,70%{-webkit-transform:scale3D(1,1,1);transform:scale3D(1,1,1)}35%{-webkit-transform:scale3D(0,0,1);transform:scale3D(0,0,1)}}@keyframes sk-cubeGridScaleDelay{0%,100%,70%{-webkit-transform:scale3D(1,1,1);transform:scale3D(1,1,1)}35%{-webkit-transform:scale3D(0,0,1);transform:scale3D(0,0,1)}}.sk-spinner-wordpress.sk-spinner{background-color:#1ab394;width:30px;height:30px;border-radius:30px;position:relative;margin:0 auto;-webkit-animation:sk-innerCircle 1s linear infinite;animation:sk-innerCircle 1s linear infinite}.sk-spinner-wordpress .sk-inner-circle{display:block;background-color:#fff;width:8px;height:8px;position:absolute;border-radius:8px;top:5px;left:5px}@-webkit-keyframes sk-innerCircle{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes sk-innerCircle{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.sk-spinner-fading-circle.sk-spinner{margin:0 auto;width:22px;height:22px;position:relative}.sk-spinner-fading-circle .sk-circle{width:100%;height:100%;position:absolute;left:0;top:0}.sk-spinner-fading-circle .sk-circle:before{content:'';display:block;margin:0 auto;width:18%;height:18%;background-color:#1ab394;border-radius:100%;-webkit-animation:sk-circleFadeDelay 1.2s infinite ease-in-out;animation:sk-circleFadeDelay 1.2s infinite ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both}.sk-spinner-fading-circle .sk-circle2{-webkit-transform:rotate(30deg);-ms-transform:rotate(30deg);transform:rotate(30deg)}.sk-spinner-fading-circle .sk-circle3{-webkit-transform:rotate(60deg);-ms-transform:rotate(60deg);transform:rotate(60deg)}.sk-spinner-fading-circle .sk-circle4{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.sk-spinner-fading-circle .sk-circle5{-webkit-transform:rotate(120deg);-ms-transform:rotate(120deg);transform:rotate(120deg)}.sk-spinner-fading-circle .sk-circle6{-webkit-transform:rotate(150deg);-ms-transform:rotate(150deg);transform:rotate(150deg)}.sk-spinner-fading-circle .sk-circle7{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.sk-spinner-fading-circle .sk-circle8{-webkit-transform:rotate(210deg);-ms-transform:rotate(210deg);transform:rotate(210deg)}.sk-spinner-fading-circle .sk-circle9{-webkit-transform:rotate(240deg);-ms-transform:rotate(240deg);transform:rotate(240deg)}.sk-spinner-fading-circle .sk-circle10{-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.sk-spinner-fading-circle .sk-circle11{-webkit-transform:rotate(300deg);-ms-transform:rotate(300deg);transform:rotate(300deg)}.sk-spinner-fading-circle .sk-circle12{-webkit-transform:rotate(330deg);-ms-transform:rotate(330deg);transform:rotate(330deg)}.sk-spinner-fading-circle .sk-circle2:before{-webkit-animation-delay:-1.1s;animation-delay:-1.1s}.sk-spinner-fading-circle .sk-circle3:before{-webkit-animation-delay:-1s;animation-delay:-1s}.sk-spinner-fading-circle .sk-circle4:before{-webkit-animation-delay:-.9s;animation-delay:-.9s}.sk-spinner-fading-circle .sk-circle5:before{-webkit-animation-delay:-.8s;animation-delay:-.8s}.sk-spinner-fading-circle .sk-circle6:before{-webkit-animation-delay:-.7s;animation-delay:-.7s}.sk-spinner-fading-circle .sk-circle7:before{-webkit-animation-delay:-.6s;animation-delay:-.6s}.sk-spinner-fading-circle .sk-circle8:before{-webkit-animation-delay:-.5s;animation-delay:-.5s}.sk-spinner-fading-circle .sk-circle9:before{-webkit-animation-delay:-.4s;animation-delay:-.4s}.sk-spinner-fading-circle .sk-circle10:before{-webkit-animation-delay:-.3s;animation-delay:-.3s}.sk-spinner-fading-circle .sk-circle11:before{-webkit-animation-delay:-.2s;animation-delay:-.2s}.sk-spinner-fading-circle .sk-circle12:before{-webkit-animation-delay:-.1s;animation-delay:-.1s}@-webkit-keyframes sk-circleFadeDelay{0%,100%,39%{opacity:0}40%{opacity:1}}@keyframes sk-circleFadeDelay{0%,100%,39%{opacity:0}40%{opacity:1}}body.rtls #page-wrapper{margin:0 220px 0 0}body.rtls .nav-second-level li a{padding:7px 35px 7px 10px}body.rtls .ibox-title h5{float:right}body.rtls .pull-right{float:left!important}body.rtls .pull-left{float:right!important}body.rtls .ibox-tools,body.rtls .stat-percent{float:left}body.rtls .navbar-right{float:left!important}body.rtls .navbar-top-links li:last-child{margin-right:0}body.rtls .minimalize-styl-2{float:right;margin:14px 20px 5px 5px}body.rtls .feed-element>.pull-left{margin-left:10px;margin-right:0}body.rtls .timeline-item .date{text-align:left}body.rtls .timeline-item .date i{left:0;right:auto}body.rtls .timeline-item .content{border-right:1px solid #e7eaec;border-left:none}body.rtls .toast-close-button{float:left}body.rtls #toast-container>.toast:before{margin:auto -1.5em auto .5em}body.rtls #toast-container>div{padding:15px 50px 15px 15px}body.rtls .center-orientation .vertical-timeline-icon i{margin-left:0;margin-right:-12px}body.rtls .vertical-timeline-icon i{right:50%;left:auto;margin-left:auto;margin-right:-12px}body.rtls .file-box,body.rtls ul.notes li{float:right}body.rtls .chat-statistic,body.rtls .chat-users{margin-right:-30px;margin-left:auto}body.rtls .dropdown-menu>li>a{text-align:right}body.rtls .b-r{border-left:1px solid #e7eaec;border-right:none}body.rtls .dd-list .dd-list{padding-right:30px;padding-left:0}body.rtls .dd-item>button{float:right}body.rtls .skin-setttings{margin-right:40px;margin-left:0;direction:ltr}body.rtls .footer.fixed{margin-right:220px;margin-left:0}@media (max-width:992px){body.rtls .chat-statistic,body.rtls .chat-users{margin-right:0}}body.body-small.mini-navbar .footer.fixed,body.rtls.mini-navbar .footer.fixed{margin:0 70px 0 0}body.body-small.mini-navbar .footer.fixed,body.rtls.mini-navbar.fixed-sidebar .footer.fixed{margin:0}body.rtls.top-navigation .navbar-toggle{float:right;margin-left:15px;margin-right:15px}.body-small.rtls.top-navigation .navbar-header{float:none}body.rtls.top-navigation #page-wrapper{margin:0}body.rtls.mini-navbar #page-wrapper{margin:0 70px 0 0}body.rtls.mini-navbar.fixed-sidebar #page-wrapper{margin:0}body.rtls.body-small.fixed-sidebar.mini-navbar #page-wrapper{margin:0 220px 0 0}body.rtls.body-small.fixed-sidebar.mini-navbar .navbar-static-side{width:220px}.body-small.rtls .navbar-fixed-top{margin-right:0}.body-small.rtls .navbar-header{float:right}body.rtls .navbar-top-links li:last-child{margin-left:20px}body.rtls .top-navigation #page-wrapper,body.rtls .top-navigation .footer.fixed,body.rtls.mini-navbar .top-navigation #page-wrapper,body.rtls.mini-navbar.top-navigation #page-wrapper,body.rtls.top-navigation .footer.fixed{margin:0}@media (max-width:768px){body.rtls .navbar-top-links li:last-child{margin-left:20px}.body-small.rtls #page-wrapper{position:inherit;margin:0;min-height:1000px}.body-small.rtls .navbar-static-side{display:none;z-index:2001;position:absolute;width:70px}.body-small.rtls.mini-navbar .navbar-static-side{display:block}.rtls.fixed-sidebar.body-small .navbar-static-side{display:none;z-index:2001;position:fixed;width:220px}.rtls.fixed-sidebar.body-small.mini-navbar .navbar-static-side{display:block}}.rtls .ltr-support{direction:ltr}.skin-setttings .title{background:#efefef;text-align:center;text-transform:uppercase;font-weight:600;display:block;padding:10px 15px;font-size:12px}.setings-item{padding:10px 30px}.setings-item.nb{border:none}.setings-item.skin{text-align:center}.setings-item .switch{float:right}.skin-name a{text-transform:uppercase}.setings-item a{color:#fff}.blue-skin,.default-skin,.ultra-skin,.yellow-skin{text-align:center}.default-skin{font-weight:600;background:#1ab394}.default-skin:hover{background:#199d82}.blue-skin{font-weight:600;background:url(patterns/header-profile-skin-1.png) repeat scroll 0 0}.blue-skin:hover{background:#0d8ddb}.yellow-skin{font-weight:600;background:url(patterns/header-profile-skin-3.png) repeat scroll 0 100%}.yellow-skin:hover{background:#ce8735}.content-tabs{border-bottom:solid 2px #2f4050}.page-tabs a{color:#999}.page-tabs a i{color:#ccc}.page-tabs a.active{background:#2f4050;color:#a7b1c2}.page-tabs a.active i:hover,.page-tabs a.active:hover{background:#293846;color:#fff}.skin-1 .minimalize-styl-2{margin:14px 5px 5px 30px}.skin-1 .navbar-top-links li:last-child{margin-right:30px}.skin-1.fixed-nav .minimalize-styl-2{margin:14px 5px 5px 15px}.skin-1 .spin-icon{background:#0e9aef!important}.skin-1 .nav-header{background:#0e9aef;background:url(patterns/header-profile-skin-1.png)}.skin-1.mini-navbar .nav-second-level{background:#3e495f}.skin-1 .breadcrumb{background:0 0}.skin-1 .page-heading{border:none}.skin-1 .nav>li.active{background:#3a4459}.skin-1 .nav>li>a{color:#9ea6b9}.skin-1 .nav>li.active>a{color:#fff}.skin-1 .navbar-minimalize{background:#0e9aef;border-color:#0e9aef}body.skin-1{background:#3e495f}.skin-1 .navbar-static-top{background:#fff}.skin-1 .dashboard-header{background:0 0;border-bottom:none!important;border-top:none;padding:20px 30px 10px}.fixed-nav.skin-1 .navbar-fixed-top{background:#fff}.skin-1 .wrapper-content{padding:30px 15px}.skin-1 #page-wrapper{background:#f4f6fa}.skin-1 .ibox-content,.skin-1 .ibox-title{border-width:1px}.skin-1 .ibox-content:last-child{border-style:solid}.skin-1 .nav>li.active{border:none}.skin-1 .nav-header{padding:35px 25px 25px}.skin-1 .nav-header a.dropdown-toggle{color:#fff;margin-top:10px}.skin-1 .nav-header a.dropdown-toggle .text-muted{color:#fff;opacity:.8}.skin-1 .profile-element{text-align:center}.skin-1 .img-circle{border-radius:5px}.skin-1 .navbar-default .nav>li>a:focus,.skin-1 .navbar-default .nav>li>a:hover{background:#39aef5;color:#fff}.skin-1 .nav.nav-tabs>li.active>a{color:#555}.skin-1 .content-tabs{border-bottom:solid 2px #39aef5}.skin-1 .nav.nav-tabs>li.active{background:0 0}.skin-1 .page-tabs a.active{background:#39aef5;color:#fff}.skin-1 .page-tabs a.active i:hover,.skin-1 .page-tabs a.active:hover{background:#0e9aef;color:#fff}.skin-3 .minimalize-styl-2{margin:14px 5px 5px 30px}.skin-3 .navbar-top-links li:last-child{margin-right:30px}.skin-3.fixed-nav .minimalize-styl-2{margin:14px 5px 5px 15px}.skin-3 .spin-icon{background:#ecba52!important}body.boxed-layout.skin-3 #wrapper{background:#3e2c42}.skin-3 .nav-header{background:#ecba52;background:url(patterns/header-profile-skin-3.png)}.skin-3.mini-navbar .nav-second-level{background:#3e2c42}.skin-3 .breadcrumb{background:0 0}.skin-3 .page-heading{border:none}.skin-3 .nav>li.active{background:#38283c}.fixed-nav.skin-3 .navbar-fixed-top{background:#fff}.skin-3 .nav>li>a{color:#948b96}.skin-3 .nav>li.active>a{color:#fff}.skin-3 .navbar-minimalize{background:#ecba52;border-color:#ecba52}body.skin-3{background:#3e2c42}.skin-3 .navbar-static-top{background:#fff}.skin-3 .dashboard-header{background:0 0;border-bottom:none!important;border-top:none;padding:20px 30px 10px}.skin-3 .wrapper-content{padding:30px 15px}.skin-3 #page-wrapper{background:#f4f6fa}.skin-3 .ibox-content,.skin-3 .ibox-title{border-width:1px}.skin-3 .ibox-content:last-child{border-style:solid}.skin-3 .nav>li.active{border:none}.skin-3 .nav-header{padding:35px 25px 25px}.skin-3 .nav-header a.dropdown-toggle{color:#fff;margin-top:10px}.skin-3 .nav-header a.dropdown-toggle .text-muted{color:#fff;opacity:.8}.skin-3 .profile-element{text-align:center}.skin-3 .img-circle{border-radius:5px}.skin-3 .navbar-default .nav>li>a:focus,.skin-3 .navbar-default .nav>li>a:hover{background:#38283c;color:#fff}.skin-3 .nav.nav-tabs>li.active>a{color:#555}.skin-3 .content-tabs{border-bottom:solid 2px #3e2c42}.skin-3 .nav.nav-tabs>li.active{background:0 0}.skin-3 .page-tabs a.active{background:#3e2c42;color:#fff}.skin-3 .page-tabs a.active i:hover,.skin-3 .page-tabs a.active:hover{background:#38283c;color:#fff}@media (min-width:768px){.navbar-top-links .dropdown-alerts,.navbar-top-links .dropdown-messages,.navbar-top-links .dropdown-tasks{margin-left:auto}}@media (max-width:768px){body.fixed-sidebar .navbar-static-side{display:none}body.fixed-sidebar.mini-navbar .navbar-static-side{width:70px}.lock-word,.navbar-form-custom{display:none}.navbar-header{display:inline;float:left}.sidebard-panel{z-index:2;position:relative;width:auto;min-height:100%!important}.sidebar-content .wrapper{padding-right:0;z-index:1}.fixed-sidebar.body-small .navbar-static-side{display:none;z-index:2001;position:fixed;width:220px}.fixed-sidebar.body-small.mini-navbar .navbar-static-side{display:block}.ibox-tools{float:none;text-align:right;display:block}.content-tabs{display:none}#content-main{height:calc(100% - 100px)}.fixed-nav #content-main{height:calc(100% - 38px)}}.navbar-static-side{background:#2f4050}.nav-close{padding:10px;position:absolute;right:5px;top:5px;font-size:1.4em;cursor:pointer;z-index:10;display:none;color:rgba(255,255,255,.3)}@media (max-width:350px){body.fixed-sidebar.mini-navbar .navbar-static-side{width:0}.nav-close{display:block}#page-wrapper{margin-left:0!important}.timeline-item .date{text-align:left;width:110px;position:relative;padding-top:30px}.timeline-item .date i{position:absolute;top:0;left:15px;padding:5px;width:30px;text-align:center;border:1px solid #e7eaec;background:#f8f8f8}.timeline-item .content{border-left:none;border-top:1px solid #e7eaec;padding-top:10px;min-height:100px}.nav.navbar-top-links li.dropdown{display:none}.ibox-tools{float:none;text-align:left;display:inline-block}}.ui-jqgrid-titlebar{height:40px;line-height:24px;color:#676a6c;background-color:#F9F9F9;text-shadow:0 1px 0 rgba(255,255,255,.5)}.ui-jqgrid .ui-jqgrid-title{float:left;margin-left:5px;font-weight:700}.ui-jqgrid .ui-jqgrid-titlebar{position:relative;border-left:0 solid;border-right:0 solid;border-top:0 solid}.social-feed-separated .social-feed-box{margin-left:62px}.social-feed-separated .social-avatar{float:left;padding:0}.social-feed-separated .social-avatar img{width:52px;height:52px;border:1px solid #e7eaec}.social-feed-separated .social-feed-box .social-avatar{padding:15px 15px 0;float:none}.social-feed-box{border:1px solid #e7eaec;background:#fff;margin-bottom:15px}.article .social-feed-box{margin-bottom:0;border-bottom:none}.article .social-feed-box:last-child{margin-bottom:0;border-bottom:1px solid #e7eaec}.article .social-feed-box p{font-size:13px;line-height:18px}.social-action{margin:15px}.social-avatar{padding:15px 15px 0}.social-comment .social-comment{margin-left:45px}.social-avatar img{height:40px;width:40px;margin-right:10px}.social-avatar .media-body a{font-size:14px;display:block}.social-body{padding:15px}.social-body img{margin-bottom:10px}.social-footer{border-top:1px solid #e7eaec;padding:10px 15px;background:#f9f9f9}.social-footer .social-comment img{width:32px;margin-right:10px}.social-comment:first-child{margin-top:0}.social-comment{margin-top:15px}.social-comment textarea{font-size:12px}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{margin-top:-4px}@media (max-width:1000px){.welcome-message{display:none}}.echarts{height:240px}.checkbox-inline,.checkbox-inline+.checkbox-inline,.radio-inline,.radio-inline+.radio-inline{margin:0 15px 0 0}.navbar-toggle{background-color:#fff}.J_menuTab{-webkit-transition:all .3s ease-out 0s;transition:all .3s ease-out 0s}::-webkit-scrollbar-track{background-color:#F5F5F5}::-webkit-scrollbar{width:6px;background-color:#F5F5F5}::-webkit-scrollbar-thumb{background-color:#999}.gohome{position:fixed;top:20px;right:20px;z-index:100}.gohome a{height:38px;width:38px;display:block;background:#2f4050;padding:9px 8px;text-align:center;color:#fff;border-radius:50%;opacity:.5}.gohome a:hover{opacity:1}@media only screen and (-webkit-min-device-pixel-ratio:2){#content-main{-webkit-overflow-scrolling:touch;}}.navbar-header{width:60%}.bs-glyphicons{margin:0 -10px 20px;overflow:hidden}.bs-glyphicons-list{padding-left:0;list-style:none}.bs-glyphicons li{float:left;width:25%;height:115px;padding:10px;font-size:10px;line-height:1.4;text-align:center;background-color:#f9f9f9;border:1px solid #fff}.bs-glyphicons .glyphicon{margin-top:5px;margin-bottom:10px;font-size:24px}.bs-glyphicons .glyphicon-class{display:block;text-align:center;word-wrap:break-word}.bs-glyphicons li:hover{color:#fff;background-color:#1ab394}@media (min-width:768px){.bs-glyphicons{margin-right:0;margin-left:0}.bs-glyphicons li{width:12.5%;font-size:12px}} diff --git a/html/static/fonts/fontawesome-webfont93e3.eot b/html/static/fonts/fontawesome-webfont93e3.eot deleted file mode 100644 index a30335d..0000000 Binary files a/html/static/fonts/fontawesome-webfont93e3.eot and /dev/null differ diff --git a/html/static/fonts/fontawesome-webfont93e3.svg b/html/static/fonts/fontawesome-webfont93e3.svg deleted file mode 100644 index 6c5bb76..0000000 --- a/html/static/fonts/fontawesome-webfont93e3.svg +++ /dev/null @@ -1,640 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/html/static/fonts/fontawesome-webfont93e3.ttf b/html/static/fonts/fontawesome-webfont93e3.ttf deleted file mode 100644 index d7994e1..0000000 Binary files a/html/static/fonts/fontawesome-webfont93e3.ttf and /dev/null differ diff --git a/html/static/fonts/fontawesome-webfont93e3.woff b/html/static/fonts/fontawesome-webfont93e3.woff deleted file mode 100644 index 6fd4ede..0000000 Binary files a/html/static/fonts/fontawesome-webfont93e3.woff and /dev/null differ diff --git a/html/static/fonts/fontawesome-webfont93e3.woff2 b/html/static/fonts/fontawesome-webfont93e3.woff2 deleted file mode 100644 index 5560193..0000000 Binary files a/html/static/fonts/fontawesome-webfont93e3.woff2 and /dev/null differ diff --git a/html/static/fonts/fontawesome-webfontd41d.eot b/html/static/fonts/fontawesome-webfontd41d.eot deleted file mode 100644 index a30335d..0000000 Binary files a/html/static/fonts/fontawesome-webfontd41d.eot and /dev/null differ diff --git a/html/static/fonts/glyphicons-halflings-regular.eot b/html/static/fonts/glyphicons-halflings-regular.eot deleted file mode 100644 index b93a495..0000000 Binary files a/html/static/fonts/glyphicons-halflings-regular.eot and /dev/null differ diff --git a/html/static/fonts/glyphicons-halflings-regular.svg b/html/static/fonts/glyphicons-halflings-regular.svg deleted file mode 100644 index 187805a..0000000 --- a/html/static/fonts/glyphicons-halflings-regular.svg +++ /dev/null @@ -1,288 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/html/static/fonts/glyphicons-halflings-regular.ttf b/html/static/fonts/glyphicons-halflings-regular.ttf deleted file mode 100644 index 1413fc6..0000000 Binary files a/html/static/fonts/glyphicons-halflings-regular.ttf and /dev/null differ diff --git a/html/static/fonts/glyphicons-halflings-regular.woff b/html/static/fonts/glyphicons-halflings-regular.woff deleted file mode 100644 index 9e61285..0000000 Binary files a/html/static/fonts/glyphicons-halflings-regular.woff and /dev/null differ diff --git a/html/static/fonts/glyphicons-halflings-regular.woff2 b/html/static/fonts/glyphicons-halflings-regular.woff2 deleted file mode 100644 index 64539b5..0000000 Binary files a/html/static/fonts/glyphicons-halflings-regular.woff2 and /dev/null differ diff --git a/html/static/fonts/glyphicons-halflings-regulard41d.eot b/html/static/fonts/glyphicons-halflings-regulard41d.eot deleted file mode 100644 index b93a495..0000000 Binary files a/html/static/fonts/glyphicons-halflings-regulard41d.eot and /dev/null differ diff --git a/html/static/img/a1.jpg b/html/static/img/a1.jpg deleted file mode 100644 index 4db26bc..0000000 Binary files a/html/static/img/a1.jpg and /dev/null differ diff --git a/html/static/img/a2.jpg b/html/static/img/a2.jpg deleted file mode 100644 index 36f7728..0000000 Binary files a/html/static/img/a2.jpg and /dev/null differ diff --git a/html/static/img/a3.jpg b/html/static/img/a3.jpg deleted file mode 100644 index 64c2049..0000000 Binary files a/html/static/img/a3.jpg and /dev/null differ diff --git a/html/static/img/a4.jpg b/html/static/img/a4.jpg deleted file mode 100644 index f82f9f4..0000000 Binary files a/html/static/img/a4.jpg and /dev/null differ diff --git a/html/static/img/a5.jpg b/html/static/img/a5.jpg deleted file mode 100644 index 56bea69..0000000 Binary files a/html/static/img/a5.jpg and /dev/null differ diff --git a/html/static/img/a6.jpg b/html/static/img/a6.jpg deleted file mode 100644 index 935ccc7..0000000 Binary files a/html/static/img/a6.jpg and /dev/null differ diff --git a/html/static/img/a7.jpg b/html/static/img/a7.jpg deleted file mode 100644 index 975ac18..0000000 Binary files a/html/static/img/a7.jpg and /dev/null differ diff --git a/html/static/img/a8.jpg b/html/static/img/a8.jpg deleted file mode 100644 index 7c89190..0000000 Binary files a/html/static/img/a8.jpg and /dev/null differ diff --git a/html/static/img/a9.jpg b/html/static/img/a9.jpg deleted file mode 100644 index 508eb09..0000000 Binary files a/html/static/img/a9.jpg and /dev/null differ diff --git a/html/static/js/bootstrap.min.js b/html/static/js/bootstrap.min.js deleted file mode 100644 index e364a13..0000000 --- a/html/static/js/bootstrap.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under the MIT license - */ -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||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(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.6",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.6",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.6",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.6",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(a.Event("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.6",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(a.Event("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.6",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.6",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.6",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); diff --git a/html/static/js/jquery.min.js b/html/static/js/jquery.min.js deleted file mode 100644 index 49990d6..0000000 --- a/html/static/js/jquery.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){ -return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*\s*$/g,ia={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll("loading");break;case 4:f||(t.content=[t.content,"body"]),t.follow=t.content[1],t.content=t.content[0]+'',delete t.title,t.tips="object"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll("tips")}e.vessel(f,function(n,r,d){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i("body").append(n[1])}():function(){l.parents("."+s[0])[0]||(l.data("display",l.css("display")).show().addClass("layui-layer-wrap").wrap(n[1]),i("#"+s[0]+a).find("."+s[5]).before(r))}()}():c.append(n[1]),i(".layui-layer-move")[0]||c.append(o.moveElem=d),e.layero=i("#"+s[0]+a),t.scrollbar||s.html.css("overflow","hidden").attr("layer-full",a)}).auto(a),2==t.type&&6==r.ie&&e.layero.find("iframe").attr("src",l[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on("resize",function(){e.offset(),(/^\d+%$/.test(t.area[0])||/^\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),s.anim[t.anim]&&e.layero.addClass(s.anim[t.anim]).data("anim",!0)}},l.pt.auto=function(e){function t(e){e=l.find(e),e.height(f[1]-c-d-2*(0|parseFloat(e.css("padding"))))}var a=this,o=a.config,l=i("#"+s[0]+e);""===o.area[0]&&o.maxWidth>0&&(r.ie&&r.ie<8&&o.btn&&l.width(l.innerWidth()),l.outerWidth()>o.maxWidth&&l.width(o.maxWidth));var f=[l.innerWidth(),l.innerHeight()],c=l.find(s[1]).outerHeight()||0,d=l.find("."+s[6]).outerHeight()||0;switch(o.type){case 2:t("iframe");break;default:""===o.area[1]?o.fixed&&f[1]>=n.height()&&(f[1]=n.height(),t("."+s[5])):t("."+s[5])}return a},l.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o="object"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):"auto"!==t.offset&&("t"===t.offset?e.offsetTop=0:"r"===t.offset?e.offsetLeft=n.width()-a[0]:"b"===t.offset?e.offsetTop=n.height()-a[1]:"l"===t.offset?e.offsetLeft=0:"lt"===t.offset?(e.offsetTop=0,e.offsetLeft=0):"lb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):"rt"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):"rb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr("minLeft")&&(e.offsetTop=n.height()-(i.find(s[1]).outerHeight()||0),e.offsetLeft=i.css("left")),i.css({top:e.offsetTop,left:e.offsetLeft})},l.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i("body"));var l={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(".layui-layer-TipsG"),c=t.tips[0];t.tips[1]||f.remove(),l.autoLeft=function(){l.left+o[0]-n.width()>0?(l.tipLeft=l.left+l.width-o[0],f.css({right:12,left:"auto"})):l.tipLeft=l.left},l.where=[function(){l.autoLeft(),l.tipTop=l.top-o[1]-10,f.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color",t.tips[1])},function(){l.tipLeft=l.left+l.width+10,l.tipTop=l.top,f.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color",t.tips[1])},function(){l.autoLeft(),l.tipTop=l.top+l.height+10,f.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color",t.tips[1])},function(){l.tipLeft=l.left-o[0]-10,l.tipTop=l.top,f.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color",t.tips[1])}],l.where[c-1](),1===c?l.top-(n.scrollTop()+o[1]+16)<0&&l.where[2]():2===c?n.width()-(l.left+l.width+o[0]+16)>0||l.where[3]():3===c?l.top-n.scrollTop()+l.height+o[1]+16-n.height()>0&&l.where[0]():4===c&&o[0]+16-l.left>0&&l.where[1](),a.find("."+s[5]).css({"background-color":t.tips[1],"padding-right":t.closeBtn?"30px":""}),a.css({left:l.tipLeft-(t.fixed?n.scrollLeft():0),top:l.tipTop-(t.fixed?n.scrollTop():0)})},l.pt.move=function(){var e=this,t=e.config,a=i(document),l=e.layero,s=l.find(t.move),f=l.find(".layui-layer-resize"),c={};return t.move&&s.css("cursor","move"),s.on("mousedown",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(l.css("left")),e.clientY-parseFloat(l.css("top"))],o.moveElem.css("cursor","move").show())}),f.on("mousedown",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[l.outerWidth(),l.outerHeight()],o.moveElem.css("cursor","se-resize").show()}),a.on("mousemove",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],s="fixed"===l.css("position");if(i.preventDefault(),c.stX=s?0:n.scrollLeft(),c.stY=s?0:n.scrollTop(),!t.moveOut){var f=n.width()-l.outerWidth()+c.stX,d=n.height()-l.outerHeight()+c.stY;af&&(a=f),od&&(o=d)}l.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0}}).on("mouseup",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd()),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},l.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find("iframe").on("load",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find("."+s[6]).children("a").on("click",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a["btn"+(e+1)]&&a["btn"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find("."+s[7]).on("click",e),a.shadeClose&&i("#layui-layer-shade"+t.index).on("click",function(){r.close(t.index)}),n.find(".layui-layer-min").on("click",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(".layui-layer-max").on("click",function(){i(this).hasClass("layui-layer-maxmin")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i("select"),function(e,t){var n=i(this);n.parents("."+s[0])[0]||1==n.attr("layer")&&i("."+s[0]).length<1&&n.removeAttr("layer").show(),n=null})},l.pt.IE6=function(e){i("select").each(function(e,t){var n=i(this);n.parents("."+s[0])[0]||"none"===n.css("display")||n.attr({layer:"1"}).hide(),n=null})},l.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css("z-index",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on("mousedown",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css("margin-left"))];e.find(".layui-layer-max").addClass("layui-layer-maxmin"),e.attr({area:t})},o.rescollbar=function(e){s.html.attr("layer-full")==e&&(s.html[0].style.removeProperty?s.html[0].style.removeProperty("overflow"):s.html[0].style.removeAttribute("overflow"),s.html.removeAttr("layer-full"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i("."+s[4]).attr("times"),i("#"+s[0]+t).find("iframe").contents().find(e)},r.getFrameIndex=function(e){return i("#"+e).parents("."+s[4]).attr("times")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame("html",e).outerHeight(),n=i("#"+s[0]+e),a=n.find(s[1]).outerHeight()||0,o=n.find("."+s[6]).outerHeight()||0;n.css({height:t+a+o}),n.find("iframe").css({height:t})}},r.iframeSrc=function(e,t){i("#"+s[0]+e).find("iframe").attr("src",t)},r.style=function(e,t,n){var a=i("#"+s[0]+e),r=a.find(".layui-layer-content"),l=a.attr("type"),f=a.find(s[1]).outerHeight()||0,c=a.find("."+s[6]).outerHeight()||0;a.attr("minLeft");l!==o.type[3]&&l!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find("."+s[6]).outerHeight(),l===o.type[2]?a.find("iframe").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css("padding-top"))-parseFloat(r.css("padding-bottom"))}))},r.min=function(e,t){var a=i("#"+s[0]+e),l=a.find(s[1]).outerHeight()||0,f=a.attr("minLeft")||181*o.minIndex+"px",c=a.css("position");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr("position",c),r.style(e,{width:180,height:l,left:f,top:n.height()-l,position:"fixed",overflow:"hidden"},!0),a.find(".layui-layer-min").hide(),"page"===a.attr("type")&&a.find(s[4]).hide(),o.rescollbar(e),a.attr("minLeft")||o.minIndex++,a.attr("minLeft",f)},r.restore=function(e){var t=i("#"+s[0]+e),n=t.attr("area").split(",");t.attr("type");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr("position"),overflow:"visible"},!0),t.find(".layui-layer-max").removeClass("layui-layer-maxmin"),t.find(".layui-layer-min").show(),"page"===t.attr("type")&&t.find(s[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i("#"+s[0]+e);o.record(a),s.html.attr("layer-full")||s.html.css("overflow","hidden").attr("layer-full",e),clearTimeout(t),t=setTimeout(function(){var t="fixed"===a.css("position");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(".layui-layer-min").hide()},100)},r.title=function(e,t){var n=i("#"+s[0]+(t||r.index)).find(s[1]);n.html(e)},r.close=function(e){var t=i("#"+s[0]+e),n=t.attr("type"),a="layer-anim-close";if(t[0]){var l="layui-layer-wrap",f=function(){if(n===o.type[1]&&"object"===t.attr("conType")){t.children(":not(."+s[5]+")").remove();for(var a=t.find("."+l),r=0;r<2;r++)a.unwrap();a.css("display",a.data("display")).removeClass(l)}else{if(n===o.type[2])try{var f=i("#"+s[4]+e)[0];f.contentWindow.document.write(""),f.contentWindow.close(),t.find("."+s[5])[0].removeChild(f)}catch(c){}t[0].innerHTML="",t.remove()}"function"==typeof o.end[e]&&o.end[e](),delete o.end[e]};t.data("anim")&&t.addClass(a),i("#layui-layer-moves, #layui-layer-shade"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),t.attr("minLeft")&&(o.minIndex--,o.minLeft.push(t.attr("minLeft"))),setTimeout(function(){f()},r.ie&&r.ie<10||!t.data("anim")?0:200)}},r.closeAll=function(e){i.each(i("."+s[0]),function(){var t=i(this),n=e?t.attr("type")===e:1;n&&r.close(t.attr("times")),n=null})};var f=r.cache||{},c=function(e){return f.skin?" "+f.skin+" "+f.skin+"-"+e:""};r.prompt=function(e,t){var a="";if(e=e||{},"function"==typeof e&&(t=e),e.area){var o=e.area;a='style="width: '+o[0]+"; height: "+o[1]+';"',delete e.area}var l,s=2==e.formType?'":function(){return''}();return r.open(i.extend({type:1,btn:["确定","取消"],content:s,skin:"layui-layer-prompt"+c("prompt"),maxWidth:n.width(),success:function(e){l=e.find(".layui-layer-input"),l.focus()},resize:!1,yes:function(i){var n=l.val();""===n?l.focus():n.length>(e.maxlength||500)?r.tips("最多输入"+(e.maxlength||500)+"个字数",l,{tips:1}):t&&t(n,i,l)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{};return r.open(i.extend({type:1,skin:"layui-layer-tab"+c("tab"),resize:!1,title:function(){var e=t.length,i=1,n="";if(e>0)for(n=''+t[0].title+"";i"+t[i].title+"";return n}(),content:'
    '+function(){var e=t.length,i=1,n="";if(e>0)for(n='
  • '+(t[0].content||"no content")+"
  • ";i'+(t[i].content||"no content")+"";return n}()+"
",success:function(t){var n=t.find(".layui-layer-title").children(),a=t.find(".layui-layer-tabmain").children();n.on("mousedown",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var n=i(this),o=n.index();n.addClass("layui-layer-tabnow").siblings().removeClass("layui-layer-tabnow"),a.eq(o).show().siblings().hide(),"function"==typeof e.change&&e.change(o)})}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var l={};if(t=t||{},t.photos){var s=t.photos.constructor===Object,f=s?t.photos:{},d=f.data||[],u=f.start||0;if(l.imgIndex=(0|u)+1,t.img=t.img||"img",s){if(0===d.length)return r.msg("没有图片")}else{var y=i(t.photos),p=function(){d=[],y.find(t.img).each(function(e){var t=i(this);t.attr("layer-index",e),d.push({alt:t.attr("alt"),pid:t.attr("layer-pid"),src:t.attr("layer-src")||t.attr("src"),thumb:t.attr("src")})})};if(p(),0===d.length)return;if(n||y.on("click",t.img,function(){var e=i(this),n=e.attr("layer-index");r.photos(i.extend(t,{photos:{start:n,data:d,tab:t.tab},full:t.full}),!0),p()}),!n)return}l.imgprev=function(e){l.imgIndex--,l.imgIndex<1&&(l.imgIndex=d.length),l.tabimg(e)},l.imgnext=function(e,t){l.imgIndex++,l.imgIndex>d.length&&(l.imgIndex=1,t)||l.tabimg(e)},l.keyup=function(e){if(!l.end){var t=e.keyCode;e.preventDefault(),37===t?l.imgprev(!0):39===t?l.imgnext(!0):27===t&&r.close(l.index)}},l.tabimg=function(e){d.length<=1||(f.start=l.imgIndex-1,r.close(l.index),r.photos(t,!0,e))},l.event=function(){l.bigimg.hover(function(){l.imgsee.show()},function(){l.imgsee.hide()}),l.bigimg.find(".layui-layer-imgprev").on("click",function(e){e.preventDefault(),l.imgprev()}),l.bigimg.find(".layui-layer-imgnext").on("click",function(e){e.preventDefault(),l.imgnext()}),i(document).on("keyup",l.keyup)},l.loadi=r.load(1,{shade:!("shade"in t)&&.9,scrollbar:!1}),o(d[u].src,function(n){r.close(l.loadi),l.index=r.open(i.extend({type:1,area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]'+(d[u].alt||
'+(d.length>1?'':"")+'
'+(d[u].alt||"")+""+l.imgIndex+"/"+d.length+"
",success:function(e,i){l.bigimg=e.find(".layui-layer-phimg"),l.imgsee=e.find(".layui-layer-imguide,.layui-layer-imgbar"),l.event(e),t.tab&&t.tab(d[u],e)},end:function(){l.end=!0,i(document).off("keyup",l.keyup)}},t))},function(){r.close(l.loadi),r.msg("当前图片地址异常
是否继续查看下一张?",{time:3e4,btn:["下一张","不看了"],yes:function(){d.length>1&&l.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),s.html=i("html"),r.open=function(e){var t=new l(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define("jquery",function(t){r.path=layui.cache.dir,o.run(layui.jquery),e.layer=r,t("layer",r)})):"function"==typeof define?define(["jquery"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window); \ No newline at end of file diff --git a/html/static/layer/mobile/layer.js b/html/static/layer/mobile/layer.js deleted file mode 100644 index f9cf693..0000000 --- a/html/static/layer/mobile/layer.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! layer mobile-v2.0.0 Web弹层组件 MIT License http://layer.layui.com/mobile By 贤心 */ - ;!function(e){"use strict";var t=document,n="querySelectorAll",i="getElementsByClassName",a=function(e){return t[n](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var n in e)t[n]=e[n];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener("click",function(e){t.call(this,e)},!1)};var r=0,o=["layui-m-layer"],c=function(e){var t=this;t.config=l.extend(e),t.view()};c.prototype.view=function(){var e=this,n=e.config,s=t.createElement("div");e.id=s.id=o[0]+r,s.setAttribute("class",o[0]+" "+o[0]+(n.type||0)),s.setAttribute("index",r);var l=function(){var e="object"==typeof n.title;return n.title?'

'+(e?n.title[0]:n.title)+"

":""}(),c=function(){"string"==typeof n.btn&&(n.btn=[n.btn]);var e,t=(n.btn||[]).length;return 0!==t&&n.btn?(e=''+n.btn[0]+"",2===t&&(e=''+n.btn[1]+""+e),'
'+e+"
"):""}();if(n.fixed||(n.top=n.hasOwnProperty("top")?n.top:100,n.style=n.style||"",n.style+=" top:"+(t.body.scrollTop+n.top)+"px"),2===n.type&&(n.content='

'+(n.content||"")+"

"),n.skin&&(n.anim="up"),"msg"===n.skin&&(n.shade=!1),s.innerHTML=(n.shade?"
':"")+'
"+l+'
'+n.content+"
"+c+"
",!n.type||2===n.type){var d=t[i](o[0]+n.type),y=d.length;y>=1&&layer.close(d[0].getAttribute("index"))}document.body.appendChild(s);var u=e.elem=a("#"+e.id)[0];n.success&&n.success(u),e.index=r++,e.action(n,u)},c.prototype.action=function(e,t){var n=this;e.time&&(l.timer[n.index]=setTimeout(function(){layer.close(n.index)},1e3*e.time));var a=function(){var t=this.getAttribute("type");0==t?(e.no&&e.no(),layer.close(n.index)):e.yes?e.yes(n.index):layer.close(n.index)};if(e.btn)for(var s=t[i]("layui-m-layerbtn")[0].children,r=s.length,o=0;odiv{line-height:22px;padding-top:7px;margin-bottom:20px;font-size:14px}.layui-m-layerbtn{display:box;display:-moz-box;display:-webkit-box;width:100%;height:50px;line-height:50px;font-size:0;border-top:1px solid #D0D0D0;background-color:#F2F2F2}.layui-m-layerbtn span{display:block;-moz-box-flex:1;box-flex:1;-webkit-box-flex:1;font-size:14px;cursor:pointer}.layui-m-layerbtn span[yes]{color:#40AFFE}.layui-m-layerbtn span[no]{border-right:1px solid #D0D0D0;border-radius:0 0 0 5px}.layui-m-layerbtn span:active{background-color:#F6F6F6}.layui-m-layerend{position:absolute;right:7px;top:10px;width:30px;height:30px;border:0;font-weight:400;background:0 0;cursor:pointer;-webkit-appearance:none;font-size:30px}.layui-m-layerend::after,.layui-m-layerend::before{position:absolute;left:5px;top:15px;content:'';width:18px;height:1px;background-color:#999;transform:rotate(45deg);-webkit-transform:rotate(45deg);border-radius:3px}.layui-m-layerend::after{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}body .layui-m-layer .layui-m-layer-footer{position:fixed;width:95%;max-width:100%;margin:0 auto;left:0;right:0;bottom:10px;background:0 0}.layui-m-layer-footer .layui-m-layercont{padding:20px;border-radius:5px 5px 0 0;background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn{display:block;height:auto;background:0 0;border-top:none}.layui-m-layer-footer .layui-m-layerbtn span{background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn span[no]{color:#FD482C;border-top:1px solid #c2c2c2;border-radius:0 0 5px 5px}.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top:10px;border-radius:5px}body .layui-m-layer .layui-m-layer-msg{width:auto;max-width:90%;margin:0 auto;bottom:-150px;background-color:rgba(0,0,0,.7);color:#fff}.layui-m-layer-msg .layui-m-layercont{padding:10px 20px} \ No newline at end of file diff --git a/html/static/layer/skin/default/icon-ext.png b/html/static/layer/skin/default/icon-ext.png deleted file mode 100644 index bbbb669..0000000 Binary files a/html/static/layer/skin/default/icon-ext.png and /dev/null differ diff --git a/html/static/layer/skin/default/icon.png b/html/static/layer/skin/default/icon.png deleted file mode 100644 index 3e17da8..0000000 Binary files a/html/static/layer/skin/default/icon.png and /dev/null differ diff --git a/html/static/layer/skin/default/layer.css b/html/static/layer/skin/default/layer.css deleted file mode 100644 index b88c0c7..0000000 --- a/html/static/layer/skin/default/layer.css +++ /dev/null @@ -1 +0,0 @@ -.layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}*html{background-image:url(about:blank);background-attachment:fixed}html #layuicss-skinlayercss{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;box-shadow:1px 1px 50px rgba(0,0,0,.3)}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.1);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-load{background:url(loading-1.gif) center center no-repeat #eee}.layui-layer-ico{background:url(icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-move{display:none;position:fixed;*position:absolute;left:0;top:0;width:100%;height:100%;cursor:move;opacity:0;filter:alpha(opacity=0);background-color:#fff;z-index:2147483647}.layui-layer-resize{position:absolute;width:15px;height:15px;right:0;bottom:0;cursor:se-resize}.layui-layer{border-radius:2px;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:rollIn;animation-name:rollIn}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:bounceOut;animation-name:bounceOut;-webkit-animation-duration:.2s;animation-duration:.2s}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:0 -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 10px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none}.layui-layer-btn a{height:28px;line-height:28px;margin:0 6px;padding:0 15px;border:1px solid #dedede;background-color:#f1f1f1;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.8}.layui-layer-btn .layui-layer-btn0{border-color:#4898d5;background-color:#2e8ded;color:#fff}.layui-layer-btn-l{text-align:left}.layui-layer-btn-c{text-align:center}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:5px 10px;font-size:12px;_float:left;border-radius:2px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#000}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:1px;border-bottom-style:solid;border-bottom-color:#000}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#BBB5B5;border:none}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:220px;height:30px;margin:0 auto;line-height:30px;padding:0 5px;border:1px solid #ccc;box-shadow:1px 1px 5px rgba(0,0,0,.1) inset;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px}.layui-layer-prompt .layui-layer-content{padding:20px}.layui-layer-prompt .layui-layer-btn{padding-top:0}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;border-bottom:1px solid #ccc;background-color:#eee;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;cursor:default;overflow:hidden}.layui-layer-tab .layui-layer-title span.layui-layer-tabnow{height:43px;border-left:1px solid #ccc;border-right:1px solid #ccc;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.xubox_tab_layer{display:block}.xubox_tabclose{position:absolute;right:10px;top:5px;cursor:pointer}.layui-layer-photos{-webkit-animation-duration:1s;animation-duration:1s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal}@media screen and (max-width:1100px){.layui-layer-iframe{overflow-y:auto;-webkit-overflow-scrolling:touch}} \ No newline at end of file diff --git a/html/static/layer/skin/default/loading-0.gif b/html/static/layer/skin/default/loading-0.gif deleted file mode 100644 index 6f3c953..0000000 Binary files a/html/static/layer/skin/default/loading-0.gif and /dev/null differ diff --git a/html/static/layer/skin/default/loading-1.gif b/html/static/layer/skin/default/loading-1.gif deleted file mode 100644 index db3a483..0000000 Binary files a/html/static/layer/skin/default/loading-1.gif and /dev/null differ diff --git a/html/static/layer/skin/default/loading-2.gif b/html/static/layer/skin/default/loading-2.gif deleted file mode 100644 index 5bb90fd..0000000 Binary files a/html/static/layer/skin/default/loading-2.gif and /dev/null differ diff --git a/server.php b/server.php deleted file mode 100644 index 9e062f1..0000000 --- a/server.php +++ /dev/null @@ -1,331 +0,0 @@ - [ - * info - * ] - * ] - * todo 解释socket与file号对应 - */ - private $sockets = []; - private $master; - - public function __construct($host, $port) { - try { - $this->master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); - // 设置IP和端口重用,在重启服务器后能重新使用此端口; - socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1); - // 将IP和端口绑定在服务器socket上; - socket_bind($this->master, $host, $port); - // listen函数使用主动连接套接口变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。在TCP服务器编程中listen函数把进程变为一个服务器,并指定相应的套接字变为被动连接,其中的能存储的请求不明的socket数目。 - socket_listen($this->master, self::LISTEN_SOCKET_NUM); - } catch (\Exception $e) { - $err_code = socket_last_error(); - $err_msg = socket_strerror($err_code); - - $this->error([ - 'error_init_server', - $err_code, - $err_msg - ]); - } - - $this->sockets[0] = ['resource' => $this->master]; - $pid = posix_getpid(); - $this->debug(["server: {$this->master} started,pid: {$pid}"]); - - while (true) { - try { - $this->doServer(); - } catch (\Exception $e) { - $this->error([ - 'error_do_server', - $e->getCode(), - $e->getMessage() - ]); - } - } - } - - private function doServer() { - $write = $except = NULL; - $sockets = array_column($this->sockets, 'resource'); - $read_num = socket_select($sockets, $write, $except, NULL); - // select作为监视函数,参数分别是(监视可读,可写,异常,超时时间),返回可操作数目,出错时返回false; - if (false === $read_num) { - $this->error([ - 'error_select', - $err_code = socket_last_error(), - socket_strerror($err_code) - ]); - return; - } - - foreach ($sockets as $socket) { - // 如果可读的是服务器socket,则处理连接逻辑 - if ($socket == $this->master) { - $client = socket_accept($this->master); - // 创建,绑定,监听后accept函数将会接受socket要来的连接,一旦有一个连接成功,将会返回一个新的socket资源用以交互,如果是一个多个连接的队列,只会处理第一个,如果没有连接的话,进程将会被阻塞,直到连接上.如果用set_socket_blocking或socket_set_noblock()设置了阻塞,会返回false;返回资源后,将会持续等待连接。 - if (false === $client) { - $this->error([ - 'err_accept', - $err_code = socket_last_error(), - socket_strerror($err_code) - ]); - continue; - } else { - self::connect($client); - continue; - } - } else { - // 如果可读的是其他已连接socket,则读取其数据,并处理应答逻辑 - $bytes = @socket_recv($socket, $buffer, 2048, 0); - if ($bytes < 9) { - $recv_msg = $this->disconnect($socket); - } else { - if (!$this->sockets[(int)$socket]['handshake']) { - self::handShake($socket, $buffer); - continue; - } else { - $recv_msg = self::parse($buffer); - } - } - array_unshift($recv_msg, 'receive_msg'); - $msg = self::dealMsg($socket, $recv_msg); - - $this->broadcast($msg); - } - } - } - - /** - * 将socket添加到已连接列表,但握手状态留空; - * - * @param $socket - */ - public function connect($socket) { - socket_getpeername($socket, $ip, $port); - $socket_info = [ - 'resource' => $socket, - 'uname' => '', - 'handshake' => false, - 'ip' => $ip, - 'port' => $port, - ]; - $this->sockets[(int)$socket] = $socket_info; - $this->debug(array_merge(['socket_connect'], $socket_info)); - } - - /** - * 客户端关闭连接 - * - * @param $socket - * - * @return array - */ - private function disconnect($socket) { - $recv_msg = [ - 'type' => 'logout', - 'content' => $this->sockets[(int)$socket]['uname'], - ]; - unset($this->sockets[(int)$socket]); - - return $recv_msg; - } - - /** - * 用公共握手算法握手 - * - * @param $socket - * @param $buffer - * - * @return bool - */ - public function handShake($socket, $buffer) { - // 获取到客户端的升级密匙 - $line_with_key = substr($buffer, strpos($buffer, 'Sec-WebSocket-Key:') + 18); - $key = trim(substr($line_with_key, 0, strpos($line_with_key, "\r\n"))); - - // 生成升级密匙,并拼接websocket升级头 - $upgrade_key = base64_encode(sha1($key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));// 升级key的算法 - $upgrade_message = "HTTP/1.1 101 Switching Protocols\r\n"; - $upgrade_message .= "Upgrade: websocket\r\n"; - $upgrade_message .= "Sec-WebSocket-Version: 13\r\n"; - $upgrade_message .= "Connection: Upgrade\r\n"; - $upgrade_message .= "Sec-WebSocket-Accept:" . $upgrade_key . "\r\n\r\n"; - - socket_write($socket, $upgrade_message, strlen($upgrade_message));// 向socket里写入升级信息 - $this->sockets[(int)$socket]['handshake'] = true; - - socket_getpeername($socket, $ip, $port); - $this->debug([ - 'hand_shake', - $socket, - $ip, - $port - ]); - - // 向客户端发送握手成功消息,以触发客户端发送用户名动作; - $msg = [ - 'type' => 'handshake', - 'content' => 'done', - ]; - $msg = $this->build(json_encode($msg)); - socket_write($socket, $msg, strlen($msg)); - return true; - } - - /** - * 解析数据 - * - * @param $buffer - * - * @return bool|string - */ - private function parse($buffer) { - $decoded = ''; - $len = ord($buffer[1]) & 127; - if ($len === 126) { - $masks = substr($buffer, 4, 4); - $data = substr($buffer, 8); - } else if ($len === 127) { - $masks = substr($buffer, 10, 4); - $data = substr($buffer, 14); - } else { - $masks = substr($buffer, 2, 4); - $data = substr($buffer, 6); - } - for ($index = 0; $index < strlen($data); $index++) { - $decoded .= $data[$index] ^ $masks[$index % 4]; - } - - return json_decode($decoded, true); - } - - /** - * 将普通信息组装成websocket数据帧 - * - * @param $msg - * - * @return string - */ - private function build($msg) { - $frame = []; - $frame[0] = '81'; - $len = strlen($msg); - if ($len < 126) { - $frame[1] = $len < 16 ? '0' . dechex($len) : dechex($len); - } else if ($len < 65025) { - $s = dechex($len); - $frame[1] = '7e' . str_repeat('0', 4 - strlen($s)) . $s; - } else { - $s = dechex($len); - $frame[1] = '7f' . str_repeat('0', 16 - strlen($s)) . $s; - } - - $data = ''; - $l = strlen($msg); - for ($i = 0; $i < $l; $i++) { - $data .= dechex(ord($msg{$i})); - } - $frame[2] = $data; - - $data = implode('', $frame); - - return pack("H*", $data); - } - - /** - * 拼装信息 - * - * @param $socket - * @param $recv_msg - * [ - * 'type'=>user/login - * 'content'=>content - * ] - * - * @return string - */ - private function dealMsg($socket, $recv_msg) { - $msg_type = $recv_msg['type']; - $msg_content = $recv_msg['content']; - $response = []; - - switch ($msg_type) { - case 'login': - $this->sockets[(int)$socket]['uname'] = $msg_content; - // 取得最新的名字记录 - $user_list = array_column($this->sockets, 'uname'); - $response['type'] = 'login'; - $response['content'] = $msg_content; - $response['user_list'] = $user_list; - break; - case 'logout': - $user_list = array_column($this->sockets, 'uname'); - $response['type'] = 'logout'; - $response['content'] = $msg_content; - $response['user_list'] = $user_list; - break; - case 'user': - $uname = $this->sockets[(int)$socket]['uname']; - $response['type'] = 'user'; - $response['from'] = $uname; - $response['content'] = $msg_content; - break; - } - - return $this->build(json_encode($response)); - } - - /** - * 广播消息 - * - * @param $data - */ - private function broadcast($data) { - foreach ($this->sockets as $socket) { - if ($socket['resource'] == $this->master) { - continue; - } - socket_write($socket['resource'], $data, strlen($data)); - } - } - - /** - * 记录debug信息 - * - * @param array $info - */ - private function debug(array $info) { - $time = date('Y-m-d H:i:s'); - array_unshift($info, $time); - - $info = array_map('json_encode', $info); - file_put_contents(self::LOG_PATH . 'websocket_debug.log', implode(' | ', $info) . "\r\n", FILE_APPEND); - } - - /** - * 记录错误信息 - * - * @param array $info - */ - private function error(array $info) { - $time = date('Y-m-d H:i:s'); - array_unshift($info, $time); - - $info = array_map('json_encode', $info); - file_put_contents(self::LOG_PATH . 'websocket_error.log', implode(' | ', $info) . "\r\n", FILE_APPEND); - } -} - -$ws = new WebSocket("127.0.0.1", "8080"); \ No newline at end of file diff --git a/sever/core/SocketChat.php b/sever/core/SocketChat.php deleted file mode 100644 index 332f7b5..0000000 --- a/sever/core/SocketChat.php +++ /dev/null @@ -1,296 +0,0 @@ -port = $port; - $this->startServer(); - } - - //开始服务器 - public function startServer() - { - $this->master = socket_create_listen( $this->port ); - if( !$this->master ) throw new \ErrorException("listen {$this->port} fail !"); - - $this->runLog("Server Started : ".date('Y-m-d H:i:s')); - $this->runLog("Listening on : 127.0.0.1 port " . $this->port); - $this->runLog("Master socket : " . $this->master . " \n"); - - self::$connectPool[] = $this->master; - - while( true ){ - $readFds = self::$connectPool; - //阻塞接收客户端链接 - @socket_select( $readFds, $writeFds, $e = null, $this->timeout ); - - foreach( $readFds as $socket ){ - //当前链接 是主进程 - if( $this->master == $socket ){ - - $client = socket_accept( $this->master ); //接收新的链接 - $this->handShake = False; - - if ($client < 0){ - $this->log('clinet connect false!'); - continue; - } else{ - //超过最大连接数 - if( count( self::$connectPool ) > self::$maxConnectNum ) - continue; - - //加入连接池 - $this->connect( $client ); - } - - }else{ - //不是主进程,开始接收数据 - $bytes = @socket_recv($socket, $buffer, 2048, 0); - //未读取到数据 - if( $bytes == 0 ){ - $this->disConnect( $socket ); - }else{ - //未握手 先握手 - if( !$this->handShake ){ - - $this->doHandShake( $socket, $buffer ); - }else{ - - //如果是已经握完手的数据,广播其发送的消息 - $buffer = $this->decode( $buffer ); - $this->parseMessage( $buffer, $socket ); - } - } - - } - } - - } - } - - //解析发送的数据 - public function parseMessage( $message, $socket ) - { - //msg type 1 初始化 2 通知 3 一般聊天 4 断开链接 5 获取在线用户 6 通知下线 - $message = json_decode( $message, true ); - switch( $message['type'] ){ - - case 1: - $this->bind( $socket, $message ); - //通知其他客户端,当前用户上线 - $msg = [ - 'type' => "2", - 'msg' => 'online', - 'avar' => $message['avar'] - ]; - $this->sendToAll( $socket, $msg ); - //更新在线用户 - $this->freshOnlineUser(); - - break; - case 3: - $this->sendToAll( $socket, $message ); - break; - case 4: - //通知用户离线 - $msgOutline = [ - 'type' => '6', - 'user' => self::$chatUser[(int)$socket]['user'] - ]; - $this->tellOnlineInfo( $msgOutline ); - //断开 要离线的用户 - $this->disConnect( $socket ); - //更新在线用户 - $this->freshOnlineUser(); - - break; - default: - break; - } - } - - //用户--链接 绑定 - public function bind( $socket, $user ) - { - self::$chatUser[(int) $socket] = [ - 'user' => $user['user'], - 'avar' => $user['avar'] - ]; - } - - //用户--链接 解绑 - public function unBind( $socket ) - { - unset( self::$chatUser[(int) $socket] ); - } - - //获取在线用户 - public function getOnlineUser() - { - return self::$chatUser; - } - - //更新在线用户 - public function freshOnlineUser() - { - $msgOnlie = [ - 'type' => "5", - 'msg' => 'online user', - 'info' => self::$chatUser - ]; - $this->tellOnlineInfo( $msgOnlie ); - } - - //广播所有的客户端(排除自己和master) - public function sendToAll( $client, $mess ) - { - //拼装发送者的名称 - $mess['user'] = self::$chatUser[(int) $client]['user']; - $mess['stime'] = date('Y-m-d H:i:s'); - - foreach( self::$connectPool as $socket ){ - if( $socket != $this->master && $socket != $client ){ - $this->send( $socket, $mess ); - } - } - } - - //广播客户端在线用户信息 - public function tellOnlineInfo( $mess ) - { - foreach( self::$connectPool as $socket ){ - if( $socket != $this->master ){ - $this->send( $socket, $mess ); - } - } - } - - //处理发送信息 - public function send( $client, $msg ) - { - $msg = $this->frame( json_encode( $msg ) ); - socket_write( $client, $msg, strlen($msg) ); - } - - //握手协议 - function doHandShake($socket, $buffer) - { - list($resource, $host, $origin, $key) = $this->getHeaders($buffer); - $upgrade = "HTTP/1.1 101 Switching Protocol\r\n" . - "Upgrade: websocket\r\n" . - "Connection: Upgrade\r\n" . - "Sec-WebSocket-Accept: " . $this->calcKey($key) . "\r\n\r\n"; //必须以两个回车结尾 - - socket_write($socket, $upgrade, strlen($upgrade)); - $this->handShake = true; - return true; - } - - //获取请求头 - function getHeaders( $req ) - { - $r = $h = $o = $key = null; - if (preg_match("/GET (.*) HTTP/" , $req, $match)) { $r = $match[1]; } - if (preg_match("/Host: (.*)\r\n/" , $req, $match)) { $h = $match[1]; } - if (preg_match("/Origin: (.*)\r\n/" , $req, $match)) { $o = $match[1]; } - if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $req, $match)) { $key = $match[1]; } - return [$r, $h, $o, $key]; - } - - //验证socket - function calcKey( $key ) - { - //基于websocket version 13 - $accept = base64_encode(sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true)); - return $accept; - } - - - //打包函数 返回帧处理 - public function frame( $buffer ) - { - $len = strlen($buffer); - if ($len <= 125) { - - return "\x81" . chr($len) . $buffer; - } else if ($len <= 65535) { - - return "\x81" . chr(126) . pack("n", $len) . $buffer; - } else { - - return "\x81" . char(127) . pack("xxxxN", $len) . $buffer; - } - } - - //解码 解析数据帧 - function decode( $buffer ) - { - $len = $masks = $data = $decoded = null; - $len = ord($buffer[1]) & 127; - - if ($len === 126) { - $masks = substr($buffer, 4, 4); - $data = substr($buffer, 8); - } - else if ($len === 127) { - $masks = substr($buffer, 10, 4); - $data = substr($buffer, 14); - } - else { - $masks = substr($buffer, 2, 4); - $data = substr($buffer, 6); - } - for ($index = 0; $index < strlen($data); $index++) { - $decoded .= $data[$index] ^ $masks[$index % 4]; - } - return $decoded; - } - - //客户端链接处理函数 - function connect( $socket ) - { - array_push( self::$connectPool, $socket ); - $this->runLog("\n" . $socket . " CONNECTED!"); - $this->runLog(date("Y-n-d H:i:s")); - } - - //客户端断开链接函数 - function disConnect( $socket ) - { - $index = array_search( $socket, self::$connectPool ); - socket_close( $socket ); - - $this->unBind( $socket ); - $this->runLog( $socket . " DISCONNECTED!" ); - if ($index >= 0){ - array_splice( self::$connectPool, $index, 1 ); - } - } - - //打印运行信息 - public function runLog( $mess = '' ) - { - echo $mess . PHP_EOL; - } - - //系统日志 - public function log( $mess = '' ) - { - @file_put_contents( './' . date("Y-m-d") . ".log", date('Y-m-d H:i:s') . " " . $mess . PHP_EOL, FILE_APPEND ); - } -} diff --git a/sever/index.php b/sever/index.php deleted file mode 100644 index 2dd35ff..0000000 --- a/sever/index.php +++ /dev/null @@ -1,14 +0,0 @@ -