Commit 32758a21 authored by 734642908@qq.com's avatar 734642908@qq.com

init

parents
<?xml version="1.0" encoding="UTF-8"?>
<buildpath>
<buildpathentry kind="src" path=""/>
<buildpathentry kind="con" path="org.eclipse.php.core.LANGUAGE"/>
</buildpath>
.idea/
.settings/
.vscode/
.project
Application/Runtime
%SystemDrive%/
dump.rdb
\ No newline at end of file
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>
\ No newline at end of file
This diff is collapsed.
\ No newline at end of file
<?php
return array(
// 'REDIS'=>array(
// 'type'=>'Redis',
// 'host'=>'127.0.0.1', // 119.23.249.188 (部署)
// 'port'=>'6379',
// 'auth'=>''
// )
);
\ No newline at end of file
<?php
return array(
'REDIS'=>array(
'type'=>'Redis',
'host'=>'127.0.0.1', // 119.23.249.188 (部署)
'port'=>'6379',
'auth'=>''
),
'LEWAN_HEZI' => array(
'DB_TYPE' => 'mysql',
'DB_HOST' => '172.16.175.88',
'DB_NAME' => 'lewan_hezi',
'DB_USER' => 'root',
'DB_PWD' => '111111',
'DB_PORT' => '3306',
'DB_PREFIX' => '',
'DB_CHARSET' => 'utf8',
'DB_DEBUG'=>true
),
'MYNAME' => 'Index',
);
\ No newline at end of file
<?php
/**
* 数据库配置信息
*/
return array(
'LEWAN_HEZI' => array(
'DB_TYPE' => 'mysql',
'DB_HOST' => '172.16.175.88',
'DB_NAME' => 'lewan_hezi',
'DB_USER' => 'root',
'DB_PWD' => '111111',
'DB_PORT' => '3306',
'DB_PREFIX' => '',
'DB_CHARSET' => 'utf8',
'DB_DEBUG'=>true
)
);
\ No newline at end of file
<?php
return array(
'REDIS'=>array(
'type'=>'Redis',
'host'=>'172.16.0.7', // 119.23.249.188 (部署)
'port'=>'6379',
'auth'=>'b@lq%k3lek'
),
'LEWAN_HEZI' => array(
'DB_TYPE' => 'mysql',
'DB_HOST' => '172.16.0.9', //youyun_account 主表
'DB_NAME' => 'lewan_hezi',
'DB_USER' => 'lewean',
'DB_PWD' => 'a@lw%k3len',
'DB_PORT' => '3306',
'DB_PREFIX' => '',
'DB_CHARSET' => 'utf8',
'DB_DEBUG'=>true
),
'MD_KEY' => '$5dfjr$%dsadsfdsii',
);
\ No newline at end of file
<?php
return array(
'REDIS'=>array(
'type'=>'Redis',
'host'=>'127.0.0.1', // 119.23.249.188 (部署)
'port'=>'6379',
'auth'=>''
),
'LEWAN_HEZI' => array(
'DB_TYPE' => 'mysql',
'DB_HOST' => '127.0.0.1',
'DB_NAME' => 'lewan_hezi',
'DB_USER' => 'root',
'DB_PWD' => '1QAZ2wsx',
'DB_PORT' => '3306',
'DB_PREFIX' => '',
'DB_CHARSET' => 'utf8',
'DB_DEBUG'=>true
),
'MYNAME' => 'Index',
);
\ No newline at end of file
<?php
namespace Common\Service;
/**
* Cookie 服务,对外提供的服务如下
*/
class CookieService
{
private $_key_prefix = 'KD_';
/***************************************************************************************************************************************************************************
* 玩家登陆信息
***************************************************************************************************************************************************************************/
/**
* 设置玩家登陆信息
* @param type $_playerId
* @param type $_key
*/
public function setPlayerMarkCookieForLogin($_playerId,$_key,$_gameId)
{
/*
* 每个游戏都存在一个登录信息
* 1、设置player id
* 2、设置加密key字段
*/
$key = cookie($this->_key_prefix.'key'); // 当前客户端全局加密key
if(isVarEmpty($key))
{
// 客户端不存在cookie-key,属于第一次设置cookie
cookie('key',$_key,array('prefix'=>$this->_key_prefix,'expire'=>60*60)); // playerId的加密秘钥
$key = $_key;
}
$gameInfoKey = 'gameKey_'.$_gameId; // 当前游戏的信息记录KEY
$gameInfoVal = authcode($_playerId,'ENCODE',$key);
cookie($gameInfoKey,$gameInfoVal,array('prefix'=>$this->_key_prefix,'expire'=>60*60)); // playerId的加密秘钥
}
/**
* 提取玩家登录信息COOKIE
* @param type $_game_id
* @return type
*/
public function getPlayerMarkCookieForLogin($_game_id)
{
/*
* 系统将在玩家客户端记录游戏的登录信息
* 每个游戏都有一个登录信息(palyerKey/playerMark)
* key = keyval
* game = key_mark
*/
$key = cookie($this->_key_prefix.'key'); // 当前客户端全局加密key
$palyerId = cookie($this->_key_prefix.'gameKey_'.$_game_id); // 当前游戏的信息记录KEY
if(!isVarEmpty($key) && !isVarEmpty($palyerId))
{
return array('playerKey'=>$key,'playerMark'=>$palyerId);
}
return false;
}
}
\ No newline at end of file
<?php
namespace Common\Service;
/**
* Session 服务,对外提供的服务如下
*/
class SessionService
{
/***************************************************************************************************************************************************************************
* 用于支付相关处理
***************************************************************************************************************************************************************************/
/**
* 设置当前用户支付的订单号
* @param type $_orderId
*/
public static function setOrderIdForPaySelect($_orderId)
{
session('order_id',$_orderId);
}
/**
* 查询当前用户支付的订单号
*/
public static function getOrderIdForPaySelect()
{
$orderId = session('order_id');
if(isVarEmpty($orderId))
{
return false;
}
return $orderId;
}
/***************************************************************************************************************************************************************************
* 登录请求授权状态处理部分
***************************************************************************************************************************************************************************/
/**
* 设置游戏授权验证状态(已授权)
* @param type $_game_id
* @param type $_channel
*/
public static function setGameAuthorizedStatus($_game_id,$_channel)
{
session('GAME.ID',$_game_id);
session('GAME.CHANNEL',$_channel);
}
/**
* 查询游戏登录授权状态
* @return boolean
*/
public static function getGameAuthorizedStatus()
{
$gameId = session('GAME.ID');
if($gameId)
{
return $gameId;
}
return false;
}
/**
* 查询游戏登录授权状态
* @return boolean
*/
public static function removeGameAuthorizedStatus()
{
session('GAME.ID',null);
}
}
\ No newline at end of file
\ No newline at end of file
\ No newline at end of file
<?php
return array(
//'配置项'=>'配置值'
'LOG'=>array(
'logFolder' => '/opt/logs/game/',
'dateFormat'=> 'Y-m-d H:i:s'
)
);
\ No newline at end of file
\ No newline at end of file
<?php
namespace Home\Controller;
use Think\Controller;
use Home\Utils\LogUtil;
/**
* 基础控制器,内容如下
* 1、空操作默认处理
* 2、错误信息展示页面
*/
class BaseController extends Controller {
const PROJECT_NAME ="game";
function _initialize()
{
LogUtil::input(self::PROJECT_NAME);//记录日志
}
//重写display,加入记录输出代码
public function display($templateFile='',$charset='',$contentType='',$content='',$prefix=''){
$logdata = $this->get();
LogUtil::output($logdata);
$this->view->display($templateFile,$charset,$contentType,$content,$prefix);
}
/**
* 空操作请求默认处理
*/
protected function _empty()
{
echo 'bad request...';
}
/**
* 获取请求信息
*/
protected function getReqData()
{
$srcData = file_get_contents('php://input');
if(getClientRealIp() === '127.0.0.1')
{
$srcData = '{"app_version": "1.0", "source": "QQ", "nickname": "劉新俊", "device_type": "ios", "channel_id": "14705", "device_model": "iPhone", "headimgurl": "http://qzapp.qlogo.cn/qzapp/101402694/F643B6603F98A017CEAEC3460B4552E0/100", "sign": "8dcedd4e9bf762cd84b75da90d1dce1f", "os_version": "ios:10.0", "game_id": "626526", "openid": "F643B6603F98A017CEAEC3460B4552E0", "device_id": "2DD34BC3-5038-498E-9237-766345DD306B", "sex": "0"}';
}
if(!isVarEmpty($srcData))
{
try
{
return json_decode($srcData,true);
}
catch (\Think\Exception $e)
{
return array();
}
}
return array();
}
/**
* 【格式化处理结果】
*
* 输入
* 标准的Result处理结果
*
* 输出
* json格式的字符串
*/
protected function formatRes($result)
{
if(empty($result))
{
$result['c']=0;
}else if($result['c']==2)
{
//数据为空
}else
{
$result['c']=1;
}
return json_encode($result);
}
}
\ No newline at end of file
<?php
namespace Home\Controller;
use Think\Controller;
/*
* 游戏控制器
*
*/
class GameController extends BaseController
{
public function gameList()
{
// $gameUid = I('uid');//用户id
// $gameCode = I('game');//游戏编号
// $gameVersion = I('version');
$model= new \Home\Model\GameModel();
//获取游戏列表数据
$result = $model->getData();
echo $this->formatRes($result);
}
}
?>
\ No newline at end of file
\ No newline at end of file
<?php
namespace Home\Model;
use Think\Model;
/**
*
*/
class BaseModel extends Model
{
protected $__lewan_hezi = 'LEWAN_HEZI';
function __construct() {
//不要这个判断也行,model.class.php已存在此判断
if(!is_array($this->__lewan_hezi))
{
$this->__lewan_hezi = C($this->__lewan_hezi);
}
}
}
\ No newline at end of file
<?php
namespace Home\Model;
class GameModel extends BaseModel
{
//获取游戏列表
function getData()
{
$result = Array();
$field = 'name,gamer,ad';
$gameList = M("yl_game","",$this->__lewan_hezi)->where(array('status'=>1))->field($field)->select();
$result = array(
'c'=>1
,'msg'=>'获取成功'
,'d'=>array(
'gameList'=>$gameList
)
);
return $result;
}
}
\ No newline at end of file
\ No newline at end of file
<?php
/*
* 统计 - 文本日志记录
* 每天一个文件
*/
namespace Home\Service;
class LogService
{
/* @var int $logLevel 多个日记级别
*/
protected $logLevel = 0;
/**
* @var int LOG_LEVEL_DEBUG 调试级别
*/
const LOG_LEVEL_DEBUG = 1;
/**
* @var int LOG_LEVEL_INFO 产品级别
*/
const LOG_LEVEL_INFO = 2;
/**
* @var int LOG_LEVEL_ERROR 错误级别
*/
const LOG_LEVEL_ERROR = 4;
protected $logFolder = '/opt/log/game/';
protected $dateFormat = 'Y-m-d H:i:s';
protected $fileDate;
public function init()
{
$conf = C("log");
if(isset($conf['logFolder']) && !empty($conf['logFolder'])) $this->logFolder = $conf['logFolder'];
if(isset($conf['dateFormat']) && !empty($conf['dateFormat'])) $this->dateFormat = $conf['dateFormat'];
// 跨天时新建日记文件
$curFileDate = date('Y-m-d', time());
#减轻套在循环中的执行次数
if ($this->fileDate == $curFileDate) {
return;
}
$this->fileDate = $curFileDate;
// 每月一个目录
$folder = $this->logFolder;
$folder = rtrim($folder,'/').'/'; //去掉最后一个/
if (!file_exists($folder)) {
mkdir($folder, 0777, TRUE);
}
// 每天一个文件
$this->logFile = $folder . $this->fileDate;
if (!file_exists($this->logFile)) {
// 当没有权限时,touch会抛出(Permission denied)异常
@touch($this->logFile);
// touch失败时,chmod会抛出(No such file or directory)异常
if (file_exists($this->logFile)) {
chmod($this->logFile, 0777);
}
}
}
public function log($type, $msg, $data) {
$this->init();
$msgArr = array();
$msgArr[] = date($this->dateFormat, time());
$msgArr[] = strtoupper($type);
$msgArr[] = str_replace(PHP_EOL, '\n', $msg);
if ($data !== NULL) {
$msgArr[] = is_array($data) ? json_encode($data) : $data;
}
$msgArr[] = get_client_ip(); //加上ip;
$content = implode('|', $msgArr) . PHP_EOL;
return file_put_contents($this->logFile, $content, FILE_APPEND);
}
/**
* 应用产品级日记
* @param string $msg 日记关键描述
* @param string/array $data 场景上下文信息
* @return NULL
*/
public function info($msg, $data = NULL) {
/*if (!$this->isAllowToLog(self::LOG_LEVEL_INFO)) {
return;
}*/
$this->log('info', $msg, $data);
}
/**
* 开发调试级日记
* @param string $msg 日记关键描述
* @param string/array $data 场景上下文信息
* @return NULL
*/
public function debug($msg, $data = NULL) {
/* if (!$this->isAllowToLog(self::LOG_LEVEL_DEBUG)) {
return;
}*/
$this->log('debug', $msg, $data);
}
/**
* 系统错误级日记
* @param string $msg 日记关键描述
* @param string/array $data 场景上下文信息
* @return NULL
*/
public function error($msg, $data = NULL) {
/*if (!$this->isAllowToLog(self::LOG_LEVEL_ERROR)) {
return;
}*/
$this->log('error', $msg, $data);
}
/**
* 是否允许写入日记,或运算
* @param int $logLevel
* @return boolean
*/
/*protected function isAllowToLog($logLevel) {
return (($this->logLevel & $logLevel) != 0) ? TRUE : FALSE;
}*/
}
\ No newline at end of file
This diff is collapsed.
\ No newline at end of file
dev
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
/**
* ThinkPHP 默认的调试模式配置文件
*/
defined('THINK_PATH') or exit();
// 调试模式下面默认设置 可以在应用配置目录下重新定义 debug.php 覆盖
return array(
'LOG_RECORD' => true, // 进行日志记录
'LOG_EXCEPTION_RECORD' => true, // 是否记录异常信息日志
'LOG_LEVEL' => 'EMERG,ALERT,CRIT,ERR,WARN,NOTIC,INFO,DEBUG,SQL', // 允许记录的日志级别
'DB_FIELDS_CACHE' => false, // 字段缓存信息
'DB_DEBUG' => true, // 开启调试模式 记录SQL日志
'TMPL_CACHE_ON' => false, // 是否开启模板编译缓存,设为false则每次都会重新编译
'TMPL_STRIP_SPACE' => false, // 是否去除模板文件里面的html空格与换行
'SHOW_ERROR_MSG' => false, // 显示错误信息
'URL_CASE_INSENSITIVE' => false, // URL区分大小写
);
\ No newline at end of file
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
/**
* ThinkPHP English language package
*/
return array(
/* core language package */
'_MODULE_NOT_EXIST_' => "Module can't be loaded",
'_CONTROLLER_NOT_EXIST_' => "Controller can't be loaded",
'_ERROR_ACTION_' => 'Illegal Action',
'_LANGUAGE_NOT_LOAD_' => "Can't load language package",
'_TEMPLATE_NOT_EXIST_' => "Template doesn't exist",
'_MODULE_' => 'Module',
'_ACTION_' => 'Action',
'_MODEL_NOT_EXIST_' => "Model can't be loaded",
'_VALID_ACCESS_' => 'No access',
'_XML_TAG_ERROR_' => 'XML tag syntax errors',
'_DATA_TYPE_INVALID_' => 'Illegal data objects!',
'_OPERATION_WRONG_' => 'Operation error occurs',
'_NOT_LOAD_DB_' => 'Unable to load the database',
'_NO_DB_DRIVER_' => 'Unable to load database driver',
'_NOT_SUPPORT_DB_' => 'The system is temporarily not support database',
'_NO_DB_CONFIG_' => 'Not define the database configuration',
'_NOT_SUPPORT_' => 'The system does not support',
'_CACHE_TYPE_INVALID_' => 'Unable to load the cache type',
'_FILE_NOT_WRITABLE_' => 'Directory (file) is not writable',
'_METHOD_NOT_EXIST_' => 'The method you requested does not exist!',
'_CLASS_NOT_EXIST_' => 'Instantiating a class does not exist!',
'_CLASS_CONFLICT_' => 'Class name conflicts',
'_TEMPLATE_ERROR_' => 'Template Engine errors',
'_CACHE_WRITE_ERROR_' => 'Cache file write failed!',
'_TAGLIB_NOT_EXIST_' => 'Tag library is not defined',
'_OPERATION_FAIL_' => 'Operation failed!',
'_OPERATION_SUCCESS_' => 'Operation succeed!',
'_SELECT_NOT_EXIST_' => 'Record does not exist!',
'_EXPRESS_ERROR_' => 'Expression errors',
'_TOKEN_ERROR_' => "Form's token errors",
'_RECORD_HAS_UPDATE_' => 'Record has been updated',
'_NOT_ALLOW_PHP_' => 'PHP codes are not allowed in the template',
'_PARAM_ERROR_' => 'Parameter error or undefined',
'_ERROR_QUERY_EXPRESS_' => 'Query express error',
);
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: Daiane Azevedo <daianeaze16@gmail.com>
// +----------------------------------------------------------------------
/**
* ThinkPHP Portuguese language package
*/
return array(
/* core language package */
'_MODULE_NOT_EXIST_' => "Módulo não pode ser carregado",
'_CONTROLLER_NOT_EXIST_' => "Controller não pode ser carregado",
'_ERROR_ACTION_' => 'Ação ilegal',
'_LANGUAGE_NOT_LOAD_' => "Não é possível carregar pacote da linguagem",
'_TEMPLATE_NOT_EXIST_' => "Template não existe",
'_MODULE_' => 'Módulo',
'_ACTION_' => 'Ação',
'_MODEL_NOT_EXIST_' => "Modelo não pode ser carregado",
'_VALID_ACCESS_' => 'Sem acesso',
'_XML_TAG_ERROR_' => 'Erro de sintaxe - XML tag',
'_DATA_TYPE_INVALID_' => 'Tipos de dados ilegais!',
'_OPERATION_WRONG_' => 'Erro na operação',
'_NOT_LOAD_DB_' => 'Impossível carregar banco de dados',
'_NO_DB_DRIVER_' => 'Impossível carregar driver do bando de dados',
'_NOT_SUPPORT_DB_' => 'Temporariamente sem suporte ao banco',
'_NO_DB_CONFIG_' => 'Não define a configuração do banco',
'_NOT_SUPPORT_' => 'O sistema não suporta',
'_CACHE_TYPE_INVALID_' => 'Impossível carregar o tipo de cache',
'_FILE_NOT_WRITABLE_' => 'Diretório (arquivo) não pode ser escrito',
'_METHOD_NOT_EXIST_' => 'O método solicitado não existe!',
'_CLASS_NOT_EXIST_' => 'Não existe instância da classe',
'_CLASS_CONFLICT_' => 'Conflitos com nome da classe',
'_TEMPLATE_ERROR_' => 'Erros na contrução do template',
'_CACHE_WRITE_ERROR_' => 'Escrita do arquivo de cache falhou!',
'_TAGLIB_NOT_EXIST_' => 'Biblioteca da tag não foi definida',
'_OPERATION_FAIL_' => 'Operação falhou!',
'_OPERATION_SUCCESS_' => 'Operação bem sucessida!',
'_SELECT_NOT_EXIST_' => 'Gravação não existe!',
'_EXPRESS_ERROR_' => 'Erros de expressão',
'_TOKEN_ERROR_' => 'Erro no token do formulário',
'_RECORD_HAS_UPDATE_' => 'Gravação não foi atualizada',
'_NOT_ALLOW_PHP_' => 'Código PHP não é permitido no template',
'_PARAM_ERROR_' => 'Parâmetro errado ou indefinido',
'_ERROR_QUERY_EXPRESS_' => 'Erros na expressão da query',
);
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
/**
* ThinkPHP 简体中文语言包
*/
return array(
/* 核心语言变量 */
'_MODULE_NOT_EXIST_' => '无法加载模块',
'_CONTROLLER_NOT_EXIST_' => '无法加载控制器',
'_ERROR_ACTION_' => '非法操作',
'_LANGUAGE_NOT_LOAD_' => '无法加载语言包',
'_TEMPLATE_NOT_EXIST_' => '模板不存在',
'_MODULE_' => '模块',
'_ACTION_' => '操作',
'_MODEL_NOT_EXIST_' => '模型不存在或者没有定义',
'_VALID_ACCESS_' => '没有权限',
'_XML_TAG_ERROR_' => 'XML标签语法错误',
'_DATA_TYPE_INVALID_' => '非法数据对象!',
'_OPERATION_WRONG_' => '操作出现错误',
'_NOT_LOAD_DB_' => '无法加载数据库',
'_NO_DB_DRIVER_' => '无法加载数据库驱动',
'_NOT_SUPPORT_DB_' => '系统暂时不支持数据库',
'_NO_DB_CONFIG_' => '没有定义数据库配置',
'_NOT_SUPPORT_' => '系统不支持',
'_CACHE_TYPE_INVALID_' => '无法加载缓存类型',
'_FILE_NOT_WRITABLE_' => '目录(文件)不可写',
'_METHOD_NOT_EXIST_' => '方法不存在!',
'_CLASS_NOT_EXIST_' => '实例化一个不存在的类!',
'_CLASS_CONFLICT_' => '类名冲突',
'_TEMPLATE_ERROR_' => '模板引擎错误',
'_CACHE_WRITE_ERROR_' => '缓存文件写入失败!',
'_TAGLIB_NOT_EXIST_' => '标签库未定义',
'_OPERATION_FAIL_' => '操作失败!',
'_OPERATION_SUCCESS_' => '操作成功!',
'_SELECT_NOT_EXIST_' => '记录不存在!',
'_EXPRESS_ERROR_' => '表达式错误',
'_TOKEN_ERROR_' => '表单令牌错误',
'_RECORD_HAS_UPDATE_' => '记录已经更新',
'_NOT_ALLOW_PHP_' => '模板禁用PHP代码',
'_PARAM_ERROR_' => '参数错误或者未定义',
'_ERROR_QUERY_EXPRESS_' => '错误的查询条件',
);
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
/**
* ThinkPHP 繁体中文語言包
*/
return array(
/* 核心語言變數 */
'_MODULE_NOT_EXIST_' => '無法載入模組',
'_CONTROLLER_NOT_EXIST_' => '無法載入控制器',
'_ERROR_ACTION_' => '非法操作',
'_LANGUAGE_NOT_LOAD_' => '無法載入語言包',
'_TEMPLATE_NOT_EXIST_' => '模板不存在',
'_MODULE_' => '模組',
'_ACTION_' => '操作',
'_MODEL_NOT_EXIST_' => '模型不存在或者沒有定義',
'_VALID_ACCESS_' => '沒有權限',
'_XML_TAG_ERROR_' => 'XML標籤語法錯誤',
'_DATA_TYPE_INVALID_' => '非法資料物件!',
'_OPERATION_WRONG_' => '操作出現錯誤',
'_NOT_LOAD_DB_' => '無法載入資料庫',
'_NO_DB_DRIVER_' => '無法載入資料庫驅動',
'_NOT_SUPPORT_DB_' => '系統暫時不支援資料庫',
'_NO_DB_CONFIG_' => '沒有定義資料庫設定',
'_NOT_SUPPORT_' => '系統不支援',
'_CACHE_TYPE_INVALID_' => '無法載入快取類型',
'_FILE_NOT_WRITABLE_' => '目錄(檔案)不可寫',
'_METHOD_NOT_EXIST_' => '方法不存在!',
'_CLASS_NOT_EXIST_' => '實例化一個不存在的類別!',
'_CLASS_CONFLICT_' => '類別名稱衝突',
'_TEMPLATE_ERROR_' => '模板引擎錯誤',
'_CACHE_WRITE_ERROR_' => '快取檔案寫入失敗!',
'_TAGLIB_NOT_EXIST_' => '標籤庫未定義',
'_OPERATION_FAIL_' => '操作失敗!',
'_OPERATION_SUCCESS_' => '操作成功!',
'_SELECT_NOT_EXIST_' => '記錄不存在!',
'_EXPRESS_ERROR_' => '運算式錯誤',
'_TOKEN_ERROR_' => '表單權限錯誤',
'_RECORD_HAS_UPDATE_' => '記錄已經更新',
'_NOT_ALLOW_PHP_' => '模板禁用PHP代碼',
'_PARAM_ERROR_' => '參數錯誤或者未定義',
'_ERROR_QUERY_EXPRESS_' => '錯誤的查詢條件',
);
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Behavior;
/**
* 行为扩展:代理检测
*/
class AgentCheckBehavior {
public function run(&$params) {
// 代理访问检测
$limitProxyVisit = C('LIMIT_PROXY_VISIT',null,true);
if($limitProxyVisit && ($_SERVER['HTTP_X_FORWARDED_FOR'] || $_SERVER['HTTP_VIA'] || $_SERVER['HTTP_PROXY_CONNECTION'] || $_SERVER['HTTP_USER_AGENT_VIA'])) {
// 禁止代理访问
exit('Access Denied');
}
}
}
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Behavior;
use Think\Think;
/**
* Boris行为扩展
*/
class BorisBehavior {
public function run(&$params) {
if(IS_CLI){
if(!function_exists('pcntl_signal'))
E("pcntl_signal not working.\nRepl mode based on Linux OS or PHP for OS X(http://php-osx.liip.ch/)\n");
Think::addMap(array(
'Boris\Boris' => VENDOR_PATH . 'Boris/Boris.php',
'Boris\Config' => VENDOR_PATH . 'Boris/Config.php',
'Boris\CLIOptionsHandler' => VENDOR_PATH . 'Boris/CLIOptionsHandler.php',
'Boris\ColoredInspector' => VENDOR_PATH . 'Boris/ColoredInspector.php',
'Boris\DumpInspector' => VENDOR_PATH . 'Boris/DumpInspector.php',
'Boris\EvalWorker' => VENDOR_PATH . 'Boris/EvalWorker.php',
'Boris\ExportInspector' => VENDOR_PATH . 'Boris/ExportInspector.php',
'Boris\Inspector' => VENDOR_PATH . 'Boris/Inspector.php',
'Boris\ReadlineClient' => VENDOR_PATH . 'Boris/ReadlineClient.php',
'Boris\ShallowParser' => VENDOR_PATH . 'Boris/ShallowParser.php',
));
$boris = new \Boris\Boris(">>> ");
$config = new \Boris\Config();
$config->apply($boris, true);
$options = new \Boris\CLIOptionsHandler();
$options->handle($boris);
$boris->onStart(sprintf("echo 'REPL MODE FOR THINKPHP \nTHINKPHP_VERSION: %s, PHP_VERSION: %s, BORIS_VERSION: %s\n';", THINK_VERSION, PHP_VERSION, $boris::VERSION));
$boris->start();
}
}
}
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Behavior;
/**
* 浏览器防刷新检测
*/
class BrowserCheckBehavior {
public function run(&$params) {
if($_SERVER['REQUEST_METHOD'] == 'GET') {
// 启用页面防刷新机制
$guid = md5($_SERVER['PHP_SELF']);
// 浏览器防刷新的时间间隔(秒) 默认为10
$refleshTime = C('LIMIT_REFLESH_TIMES',null,10);
// 检查页面刷新间隔
if(cookie('_last_visit_time_'.$guid) && cookie('_last_visit_time_'.$guid)>time()-$refleshTime) {
// 页面刷新读取浏览器缓存
header('HTTP/1.1 304 Not Modified');
exit;
}else{
// 缓存当前地址访问时间
cookie('_last_visit_time_'.$guid, $_SERVER['REQUEST_TIME']);
//header('Last-Modified:'.(date('D,d M Y H:i:s',$_SERVER['REQUEST_TIME']-C('LIMIT_REFLESH_TIMES'))).' GMT');
}
}
}
}
\ No newline at end of file
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Behavior;
// 创建Lite运行文件
// 可以替换框架入口文件运行
// 建议绑定位置app_init
class BuildLiteBehavior {
public function run(&$params) {
if(!defined('BUILD_LITE_FILE')) return ;
$litefile = C('RUNTIME_LITE_FILE',null,RUNTIME_PATH.'lite.php');
if(is_file($litefile)) return;
$defs = get_defined_constants(TRUE);
$content = 'namespace {$GLOBALS[\'_beginTime\'] = microtime(TRUE);';
if(MEMORY_LIMIT_ON) {
$content .= '$GLOBALS[\'_startUseMems\'] = memory_get_usage();';
}
// 生成数组定义
unset($defs['user']['BUILD_LITE_FILE']);
$content .= $this->buildArrayDefine($defs['user']).'}';
// 读取编译列表文件
$filelist = is_file(CONF_PATH.'lite.php')?
include CONF_PATH.'lite.php':
array(
THINK_PATH.'Common/functions.php',
COMMON_PATH.'Common/function.php',
CORE_PATH . 'Think'.EXT,
CORE_PATH . 'Hook'.EXT,
CORE_PATH . 'App'.EXT,
CORE_PATH . 'Dispatcher'.EXT,
CORE_PATH . 'Log'.EXT,
CORE_PATH . 'Log/Driver/File'.EXT,
CORE_PATH . 'Route'.EXT,
CORE_PATH . 'Controller'.EXT,
CORE_PATH . 'View'.EXT,
CORE_PATH . 'Storage'.EXT,
CORE_PATH . 'Storage/Driver/File'.EXT,
CORE_PATH . 'Exception'.EXT,
BEHAVIOR_PATH . 'ParseTemplateBehavior'.EXT,
BEHAVIOR_PATH . 'ContentReplaceBehavior'.EXT,
);
// 编译文件
foreach ($filelist as $file){
if(is_file($file)) {
$content .= compile($file);
}
}
// 处理Think类的start方法
$content = preg_replace('/\$runtimefile = RUNTIME_PATH(.+?)(if\(APP_STATUS)/','\2',$content,1);
$content .= "\nnamespace { Think\Think::addMap(".var_export(\Think\Think::getMap(),true).");";
$content .= "\nL(".var_export(L(),true).");\nC(".var_export(C(),true).');Think\Hook::import('.var_export(\Think\Hook::get(),true).');Think\Think::start();}';
// 生成运行Lite文件
file_put_contents($litefile,strip_whitespace('<?php '.$content));
}
// 根据数组生成常量定义
private function buildArrayDefine($array) {
$content = "\n";
foreach ($array as $key => $val) {
$key = strtoupper($key);
$content .= 'defined(\'' . $key . '\') or ';
if (is_int($val) || is_float($val)) {
$content .= "define('" . $key . "'," . $val . ');';
} elseif (is_bool($val)) {
$val = ($val) ? 'true' : 'false';
$content .= "define('" . $key . "'," . $val . ');';
} elseif (is_string($val)) {
$content .= "define('" . $key . "','" . addslashes($val) . "');";
}
$content .= "\n";
}
return $content;
}
}
\ No newline at end of file
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Behavior;
/**
* 系统行为扩展:操作路由检测
*/
class CheckActionRouteBehavior {
// 行为扩展的执行入口必须是run
public function run(&$config){
// 优先检测是否存在PATH_INFO
$regx = trim($_SERVER['PATH_INFO'],'/');
if(empty($regx)) return ;
// 路由定义文件优先于config中的配置定义
// 路由处理
$routes = $config['routes'];
if(!empty($routes)) {
$depr = C('URL_PATHINFO_DEPR');
// 分隔符替换 确保路由定义使用统一的分隔符
$regx = str_replace($depr,'/',$regx);
$regx = substr_replace($regx,'',0,strlen(__URL__));
foreach ($routes as $rule=>$route){
if(0===strpos($rule,'/') && preg_match($rule,$regx,$matches)) { // 正则路由
return C('ACTION_NAME',$this->parseRegex($matches,$route,$regx));
}else{ // 规则路由
$len1 = substr_count($regx,'/');
$len2 = substr_count($rule,'/');
if($len1>=$len2) {
if('$' == substr($rule,-1,1)) {// 完整匹配
if($len1 != $len2) {
continue;
}else{
$rule = substr($rule,0,-1);
}
}
$match = $this->checkUrlMatch($regx,$rule);
if($match) return C('ACTION_NAME',$this->parseRule($rule,$route,$regx));
}
}
}
}
}
// 检测URL和规则路由是否匹配
private function checkUrlMatch($regx,$rule) {
$m1 = explode('/',$regx);
$m2 = explode('/',$rule);
$match = true; // 是否匹配
foreach ($m2 as $key=>$val){
if(':' == substr($val,0,1)) {// 动态变量
if(strpos($val,'\\')) {
$type = substr($val,-1);
if('d'==$type && !is_numeric($m1[$key])) {
$match = false;
break;
}
}elseif(strpos($val,'^')){
$array = explode('|',substr(strstr($val,'^'),1));
if(in_array($m1[$key],$array)) {
$match = false;
break;
}
}
}elseif(0 !== strcasecmp($val,$m1[$key])){
$match = false;
break;
}
}
return $match;
}
// 解析规范的路由地址
// 地址格式 操作?参数1=值1&参数2=值2...
private function parseUrl($url) {
$var = array();
if(false !== strpos($url,'?')) { // 操作?参数1=值1&参数2=值2...
$info = parse_url($url);
$path = $info['path'];
parse_str($info['query'],$var);
}else{ // 操作
$path = $url;
}
$var[C('VAR_ACTION')] = $path;
return $var;
}
// 解析规则路由
// '路由规则'=>'操作?额外参数1=值1&额外参数2=值2...'
// '路由规则'=>array('操作','额外参数1=值1&额外参数2=值2...')
// '路由规则'=>'外部地址'
// '路由规则'=>array('外部地址','重定向代码')
// 路由规则中 :开头 表示动态变量
// 外部地址中可以用动态变量 采用 :1 :2 的方式
// 'news/:month/:day/:id'=>array('News/read?cate=1','status=1'),
// 'new/:id'=>array('/new.php?id=:1',301), 重定向
private function parseRule($rule,$route,$regx) {
// 获取路由地址规则
$url = is_array($route)?$route[0]:$route;
// 获取URL地址中的参数
$paths = explode('/',$regx);
// 解析路由规则
$matches = array();
$rule = explode('/',$rule);
foreach ($rule as $item){
if(0===strpos($item,':')) { // 动态变量获取
if($pos = strpos($item,'^') ) {
$var = substr($item,1,$pos-1);
}elseif(strpos($item,'\\')){
$var = substr($item,1,-2);
}else{
$var = substr($item,1);
}
$matches[$var] = array_shift($paths);
}else{ // 过滤URL中的静态变量
array_shift($paths);
}
}
if(0=== strpos($url,'/') || 0===strpos($url,'http')) { // 路由重定向跳转
if(strpos($url,':')) { // 传递动态参数
$values = array_values($matches);
$url = preg_replace('/:(\d+)/e','$values[\\1-1]',$url);
}
header("Location: $url", true,(is_array($route) && isset($route[1]))?$route[1]:301);
exit;
}else{
// 解析路由地址
$var = $this->parseUrl($url);
// 解析路由地址里面的动态参数
$values = array_values($matches);
foreach ($var as $key=>$val){
if(0===strpos($val,':')) {
$var[$key] = $values[substr($val,1)-1];
}
}
$var = array_merge($matches,$var);
// 解析剩余的URL参数
if($paths) {
preg_replace('@(\w+)\/([^\/]+)@e', '$var[strtolower(\'\\1\')]=strip_tags(\'\\2\');', implode('/',$paths));
}
// 解析路由自动传入参数
if(is_array($route) && isset($route[1])) {
parse_str($route[1],$params);
$var = array_merge($var,$params);
}
$action = $var[C('VAR_ACTION')];
unset($var[C('VAR_ACTION')]);
$_GET = array_merge($var,$_GET);
return $action;
}
}
// 解析正则路由
// '路由正则'=>'[分组/模块/操作]?参数1=值1&参数2=值2...'
// '路由正则'=>array('[分组/模块/操作]?参数1=值1&参数2=值2...','额外参数1=值1&额外参数2=值2...')
// '路由正则'=>'外部地址'
// '路由正则'=>array('外部地址','重定向代码')
// 参数值和外部地址中可以用动态变量 采用 :1 :2 的方式
// '/new\/(\d+)\/(\d+)/'=>array('News/read?id=:1&page=:2&cate=1','status=1'),
// '/new\/(\d+)/'=>array('/new.php?id=:1&page=:2&status=1','301'), 重定向
private function parseRegex($matches,$route,$regx) {
// 获取路由地址规则
$url = is_array($route)?$route[0]:$route;
$url = preg_replace('/:(\d+)/e','$matches[\\1]',$url);
if(0=== strpos($url,'/') || 0===strpos($url,'http')) { // 路由重定向跳转
header("Location: $url", true,(is_array($route) && isset($route[1]))?$route[1]:301);
exit;
}else{
// 解析路由地址
$var = $this->parseUrl($url);
// 解析剩余的URL参数
$regx = substr_replace($regx,'',0,strlen($matches[0]));
if($regx) {
preg_replace('@(\w+)\/([^,\/]+)@e', '$var[strtolower(\'\\1\')]=strip_tags(\'\\2\');', $regx);
}
// 解析路由自动传入参数
if(is_array($route) && isset($route[1])) {
parse_str($route[1],$params);
$var = array_merge($var,$params);
}
$action = $var[C('VAR_ACTION')];
unset($var[C('VAR_ACTION')]);
$_GET = array_merge($var,$_GET);
}
return $action;
}
}
\ No newline at end of file
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Behavior;
/**
* 语言检测 并自动加载语言包
*/
class CheckLangBehavior {
// 行为扩展的执行入口必须是run
public function run(&$params){
// 检测语言
$this->checkLanguage();
}
/**
* 语言检查
* 检查浏览器支持语言,并自动加载语言包
* @access private
* @return void
*/
private function checkLanguage() {
// 不开启语言包功能,仅仅加载框架语言文件直接返回
if (!C('LANG_SWITCH_ON',null,false)){
return;
}
$langSet = C('DEFAULT_LANG');
$varLang = C('VAR_LANGUAGE',null,'l');
$langList = C('LANG_LIST',null,'zh-cn');
// 启用了语言包功能
// 根据是否启用自动侦测设置获取语言选择
if (C('LANG_AUTO_DETECT',null,true)){
if(isset($_GET[$varLang])){
$langSet = $_GET[$varLang];// url中设置了语言变量
cookie('think_language',$langSet,3600);
}elseif(cookie('think_language')){// 获取上次用户的选择
$langSet = cookie('think_language');
}elseif(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){// 自动侦测浏览器语言
preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
$langSet = $matches[1];
cookie('think_language',$langSet,3600);
}
if(false === stripos($langList,$langSet)) { // 非法语言参数
$langSet = C('DEFAULT_LANG');
}
}
// 定义当前语言
define('LANG_SET',strtolower($langSet));
// 读取框架语言包
$file = THINK_PATH.'Lang/'.LANG_SET.'.php';
if(LANG_SET != C('DEFAULT_LANG') && is_file($file))
L(include $file);
// 读取应用公共语言包
$file = LANG_PATH.LANG_SET.'.php';
if(is_file($file))
L(include $file);
// 读取模块语言包
$file = MODULE_PATH.'Lang/'.LANG_SET.'.php';
if(is_file($file))
L(include $file);
// 读取当前控制器语言包
$file = MODULE_PATH.'Lang/'.LANG_SET.'/'.strtolower(CONTROLLER_NAME).'.php';
if (is_file($file))
L(include $file);
}
}
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Behavior;
/**
* 系统行为扩展:模板内容输出替换
*/
class ContentReplaceBehavior {
// 行为扩展的执行入口必须是run
public function run(&$content){
$content = $this->templateContentReplace($content);
}
/**
* 模板内容替换
* @access protected
* @param string $content 模板内容
* @return string
*/
protected function templateContentReplace($content) {
// 系统默认的特殊变量替换
$replace = array(
'__ROOT__' => __ROOT__, // 当前网站地址
'__APP__' => __APP__, // 当前应用地址
'__MODULE__' => __MODULE__,
'__ACTION__' => __ACTION__, // 当前操作地址
'__SELF__' => htmlentities(__SELF__), // 当前页面地址
'__CONTROLLER__'=> __CONTROLLER__,
'__URL__' => __CONTROLLER__,
'__PUBLIC__' => __ROOT__.'/Public',// 站点公共目录
);
// 允许用户自定义模板的字符串替换
if(is_array(C('TMPL_PARSE_STRING')) )
$replace = array_merge($replace,C('TMPL_PARSE_STRING'));
$content = str_replace(array_keys($replace),array_values($replace),$content);
return $content;
}
}
\ No newline at end of file
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Behavior;
/**
* 自动执行任务
*/
class CronRunBehavior {
public function run(&$params) {
// 锁定自动执行
$lockfile = RUNTIME_PATH.'cron.lock';
if(is_writable($lockfile) && filemtime($lockfile) > $_SERVER['REQUEST_TIME'] - C('CRON_MAX_TIME',null,60)) {
return ;
} else {
touch($lockfile);
}
set_time_limit(1000);
ignore_user_abort(true);
// 载入cron配置文件
// 格式 return array(
// 'cronname'=>array('filename',intervals,nextruntime),...
// );
if(is_file(RUNTIME_PATH.'~crons.php')) {
$crons = include RUNTIME_PATH.'~crons.php';
}elseif(is_file(COMMON_PATH.'Conf/crons.php')){
$crons = include COMMON_PATH.'Conf/crons.php';
}
if(isset($crons) && is_array($crons)) {
$update = false;
$log = array();
foreach ($crons as $key=>$cron){
if(empty($cron[2]) || $_SERVER['REQUEST_TIME']>=$cron[2]) {
// 到达时间 执行cron文件
G('cronStart');
include COMMON_PATH.'Cron/'.$cron[0].'.php';
G('cronEnd');
$_useTime = G('cronStart','cronEnd', 6);
// 更新cron记录
$cron[2] = $_SERVER['REQUEST_TIME']+$cron[1];
$crons[$key] = $cron;
$log[] = "Cron:$key Runat ".date('Y-m-d H:i:s')." Use $_useTime s\n";
$update = true;
}
}
if($update) {
// 记录Cron执行日志
\Think\Log::write(implode('',$log));
// 更新cron文件
$content = "<?php\nreturn ".var_export($crons,true).";\n?>";
file_put_contents(RUNTIME_PATH.'~crons.php',$content);
}
}
// 解除锁定
unlink($lockfile);
return ;
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment