text: /*
   Navicat Premium Data Transfer
  
   Source Server         : MySQL_47_240_0_22
   Source Server Type    : MySQL
   Source Server Version : 50719
   Source Host           : 47.240.0.22:3306
   Source Schema         : oibit_cn
  
   Target Server Type    : MySQL
   Target Server Version : 50719
   File Encoding         : 65001
  
   Date: 01/05/2019 17:00:39
  */
  
  SET NAMES utf8mb4;
  SET FOREIGN_KEY_CHECKS = 0;
  
  -- ----------------------------
  -- Table structure for article
  -- ----------------------------
  DROP TABLE IF EXISTS `article`;
  CREATE TABLE `article`  (
    `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '记录值',
    `title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '标题',
    `abstract` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '摘要',
    `content` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '内容',
    `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'Lang Hu' COMMENT '发表用户',
    `category_id` int(10) UNSIGNED NOT NULL COMMENT '分类id',
    `tags_list` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标签列表',
    `comment_count` int(11) NOT NULL DEFAULT 0 COMMENT '评论数目',
    `view_count` int(11) NOT NULL DEFAULT 0 COMMENT '查看数目',
    `status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态 0-显示 1-隐藏',
    `top` tinyint(4) NOT NULL DEFAULT 0 COMMENT '置顶 0-默认 1-置顶',
    `create_time` int(11) UNSIGNED NULL DEFAULT NULL COMMENT '创建时间',
    `update_time` int(11) UNSIGNED NULL DEFAULT NULL COMMENT '更新时间',
    `thumbnail` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '缩略图地址',
    `del` int(1) NOT NULL DEFAULT 0 COMMENT '是否删除1 是 0 否',
    PRIMARY KEY (`id`) USING BTREE
  ) ENGINE = MyISAM AUTO_INCREMENT = 29 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  
  -- ----------------------------
  -- Records of article
  -- ----------------------------
  INSERT INTO `article` VALUES (7, 'bootstrap-table+Thinkphp实现server分页', 'bootstrap-table+Thinkphp实现server分页', '界面需要：此处不提供文件下载，请自行到官网下载。\r\n```\r\n<link href=\"./css/plugins/bootstrap-table/bootstrap-table.min.css\" rel=\"stylesheet\" type=\"text/css\" />\r\n\r\n<script src=\"./js/bootstrap.min.js\" type=\"text/javascript\"></script>\r\n<script src=\"./js/plugins/bootstrap-table/bootstrap-table.min.js\" type=\"text/javascript\"></script>\r\n<script src=\"./js/plugins/bootstrap-table/locale/bootstrap-table-zh-CN.min.js\" type=\"text/javascript\"></script>\r\n```\r\n前端html代码：\r\n```\r\n<table id=\"table\"></table>\r\n```\r\n前端JavaScript:代码\r\n```\r\n  $(\'#table\').bootstrapTable({\r\n          url: \"./infolist\", //请求地址\r\n          method: \'GET\', //请求\r\n          striped: true,\r\n          cache: false,\r\n          pagination: true,\r\n          sortable: true,\r\n          showHeader : true,\r\n          showRefresh: true,\r\n          clickToSelect: true,\r\n          search: false,\r\n          sidePagination: \"server\", //客户端client   服务端server\r\n          pageNumber: 1,\r\n          pageList: \\[10, 15\\],\r\n          queryParams: function (params) { return {\r\n                offset: params.offset, //页码\r\n                limit: params.limit,   //页面大小\r\n };\r\n          },\r\n          columns: \\[{\r\n              field: \'id\',\r\n              title: \'应用ID\',\r\n              width: \'10%\',\r\n          }, {\r\n              field: \'name\',\r\n              title: \'应用名称\',\r\n          },  {\r\n              field: \'type\',\r\n              title: \'类型\',\r\n              width: \'10%\',\r\n          },  {\r\n              field: \'status\',\r\n              title: \'状态\',\r\n              width: \'10%\',\r\n          }, {\r\n              field: \'xznum\',\r\n              title: \'下载量\',\r\n              width: \'10%\',\r\n          }, {\r\n              field: \'phnum\',\r\n              title: \'排序号\',\r\n              width: \'10%\',\r\n          }\\],\r\n      }); \r\n```\r\n后端Thinkphp处理：\r\n```\r\n$limit = trim(I(\'get.limit\')); $offset = trim(I(\'get.offset\')); $page = floor($offset / $limit) \\+ 1; # 获取并且计算 页号 分页大小\r\n\r\n$list = M(\'table\')->where(\\[\'id\'=>1\\])->page($page,$limit)->select(); # 查询相关数据\r\n$count = M(\'table\')->where(\\[\'id\'=>1\\])->count(); # 查询数据条数\r\n\r\n$ret = \\[ \'total\' => $list,\r\n        \'rows\' => $count, \\]; # 构造返回数据类型\r\n$this->ajaxReturn($ret); # 返回JSON数据\r\n```', 'Lang Hu', 1, '2,3,4', 0, 23, 0, 0, 1551940933, 1556699041, '/uploads/Images/thumbnail/2019-03-07/5c80bd453c7d9.png', 0);
  INSERT INTO `article` VALUES (8, 'QT 简单应用之播放WAV声音', '对于每一个可视化开发者而言，创建一个可以播放声音的工程或许是必要的，在QT中，给我们提供了比较友好的播放声音的函数类库QSound', '#对于每一个可视化开发者而言，创建一个可以播放声音的工程或许是必要的，在QT中，给我们提供了比较友好的播放声音的函数类库QSound\r\n\r\n##首先 我们需要在工程文件中添加\r\n```\r\nQT += multimedia\r\n```\r\n\r\n##然后我们需要在文件头部分引入QSound库文件：\r\n```\r\n#include <QSound>\r\n```\r\n\r\n##然后 我们只需要去加载对应的声音函数就可以了。\r\n```\r\nQSound *sound1 = new QSound(\":/resources/1.wav\");//加载声音文件\r\n```\r\n\r\n##当然，对于这样的而言只是加载了声音文件而已，接下来的一些操作会是我们简单的使得声音文件被播放\r\n    ###公有成员\r\n    QSound ( const QString & filename, QObject * parent = 0, const char * name = 0 )\r\n    ~QSound ()\r\n    int loops () const\r\n    int loopsRemaining () const\r\n    QString fileName () const\r\n    bool isFinished () const\r\n    ###公有槽\r\n    void play ()\r\n    void stop ()\r\n    ###静态公有成员\r\n    bool isAvailable ()\r\n    void play ( const QString & filename )\r\n    bool available ()\r\n\r\n##在此就不提供相关文档了。感谢阅读。', 'Lang Hu', 1, '12,13', 0, 10, 0, 0, 1551941494, 1556627682, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (9, '使用JavaScript和Jquery给网页添加验证码', '通过前端计算借用Canvas，生成验证码。', '\r\n**verify.js**\r\n```\r\n /**生成一个随机数**/  \r\n  function randomNum(min,max){  \r\n    return Math.floor( Math.random()*(max-min)+min);  \r\n  }  \r\n  /**生成一个随机色**/  \r\n  function randomColor(min,max){  \r\n    var r = randomNum(min,max);  \r\n    var g = randomNum(min,max);  \r\n    var b = randomNum(min,max);  \r\n    return \"rgb(\"+r+\",\"+g+\",\"+b+\")\";  \r\n  }  \r\n  verifydrawPic();  \r\n  document.getElementById(\"changecheckcodepic\").onclick = function(e){  \r\n    e.preventDefault();  \r\n    verifydrawPic();  \r\n  }  \r\n  \r\n  /**绘制验证码图片**/  \r\n  function verifydrawPic(){  \r\n    var canvas=document.getElementById(\"canvas\");  \r\n    var width=canvas.width;  \r\n    var height=canvas.height;  \r\n    var ctx = canvas.getContext(\'2d\');  \r\n    ctx.textBaseline = \'bottom\';  \r\n  \r\n    /**绘制背景色**/  \r\n    ctx.fillStyle = randomColor(180,240); //颜色若太深可能导致看不清  \r\n    ctx.fillRect(0,0,width,height);  \r\n    /**绘制文字**/  \r\n    var str = \'ABCEFGHJKLMNPQRSTWXY123456789\';  \r\n    for(var i=0; i<4; i++){  \r\n      var txt = str\\[randomNum(0,str.length)\\];  \r\n      ctx.fillStyle = randomColor(50,160);  //随机生成字体颜色  \r\n      ctx.font = randomNum(15,40)+\'px SimHei\'; //随机生成字体大小  \r\n      var x = 10+i*25;  \r\n      var y = randomNum(25,45);  \r\n      var deg = randomNum(-45, 45);  \r\n      //修改坐标原点和旋转角度  \r\n      ctx.translate(x,y);  \r\n      ctx.rotate(deg*Math.PI/180);  \r\n      ctx.fillText(txt, 0,0);  \r\n      //恢复坐标原点和旋转角度  \r\n      ctx.rotate(-deg*Math.PI/180);  \r\n      ctx.translate(-x,-y);  \r\n    }  \r\n    /**绘制干扰线**/  \r\n    for(var i=0; i<8; i++){  \r\n      ctx.strokeStyle = randomColor(40,180);  \r\n      ctx.beginPath();  \r\n      ctx.moveTo( randomNum(0,width), randomNum(0,height) );  \r\n      ctx.lineTo( randomNum(0,width), randomNum(0,height) );  \r\n      ctx.stroke();  \r\n    }  \r\n    /**绘制干扰点**/  \r\n    for(var i=0; i<100; i++){  \r\n      ctx.fillStyle = randomColor(0,255);  \r\n      ctx.beginPath();  \r\n      ctx.arc(randomNum(0,width),randomNum(0,height), 1, 0, 2*Math.PI);  \r\n      ctx.fill();  \r\n    }  \r\n  }\r\n```\r\n\r\njquery：jquery-3.3.1.min.js\r\n\r\n下载地址：https://code.jquery.com/jquery-3.3.1.min.js\r\n\r\ncookie验证：jquery.cookie.js\r\n\r\n下载地址：http://plugins.jquery.com/cookie/1.4.0/\r\n\r\njquery-md5加密：jquery.md5.js\r\n```\r\n/**  \r\n\\* jQuery MD5 hash algorithm function  \r\n\\*   \r\n\\* <code>  \r\n\\* Calculate the md5 hash of a String   \r\n\\* String $.md5 ( String str )  \r\n\\* </code>  \r\n\\*   \r\n\\* Calculates the MD5 hash of str using the удё RSA Data Security, Inc. MD5 Message-Digest Algorithm, and returns that hash.   \r\n\\* MD5 (Message-Digest algorithm 5) is a widely-used cryptographic hash function with a 128-bit hash value. MD5 has been employed in a wide variety of security applications, and is also commonly used to check the integrity of data. The generated hash is also non-reversable. Data cannot be retrieved from the message digest, the digest uniquely identifies the data.  \r\n\\* MD5 was developed by Professor Ronald L. Rivest in 1994. Its 128 bit (16 byte) message digest makes it a faster implementation than SHA-1.  \r\n\\* This script is used to process a variable length message into a fixed-length output of 128 bits using the MD5 algorithm. It is fully compatible with UTF-8 encoding. It is very useful when u want to transfer encrypted passwords over the internet. If you plan using UTF-8 encoding in your project don\'t forget to set the page encoding to UTF-8 (Content-Type meta tag).   \r\n\\* This function orginally get from the WebToolkit and rewrite for using as the jQuery plugin.  \r\n\\*   \r\n\\* Example  \r\n\\* Code  \r\n\\* <code>  \r\n\\* $.md5(\"I\'m Persian.\");   \r\n\\* </code>  \r\n\\* Result  \r\n\\* <code>  \r\n\\* \"b8c901d0f02223f9761016cfff9d68df\"  \r\n\\* </code>  \r\n\\*   \r\n\\* @alias Muhammad Hussein Fattahizadeh < muhammad \\[AT\\] semnanweb \\[DOT\\] com >  \r\n\\* @link http://www.semnanweb.com/jquery-plugin/md5.html  \r\n\\* @see http://www.webtoolkit.info/  \r\n\\* @license http://www.gnu.org/licenses/gpl.html \\[GNU General Public License\\]  \r\n\\* @param {jQuery} {md5:function(string))  \r\n\\* @return string  \r\n*/  \r\n  \r\n(function($){  \r\n  \r\nvar rotateLeft = function(lValue, iShiftBits) {  \r\nreturn (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));  \r\n}  \r\n  \r\nvar addUnsigned = function(lX, lY) {  \r\nvar lX4, lY4, lX8, lY8, lResult;  \r\nlX8 = (lX & 0x80000000);  \r\nlY8 = (lY & 0x80000000);  \r\nlX4 = (lX & 0x40000000);  \r\nlY4 = (lY & 0x40000000);  \r\nlResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);  \r\nif (lX4 & lY4) return (lResult ^ 0x80000000 ^ lX8 ^ lY8);  \r\nif (lX4 | lY4) {  \r\nif (lResult & 0x40000000) return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);  \r\nelse return (lResult ^ 0x40000000 ^ lX8 ^ lY8);  \r\n} else {  \r\nreturn (lResult ^ lX8 ^ lY8);  \r\n}  \r\n}  \r\n  \r\nvar F = function(x, y, z) {  \r\nreturn (x & y) | ((~ x) & z);  \r\n}  \r\n  \r\nvar G = function(x, y, z) {  \r\nreturn (x & z) | (y & (~ z));  \r\n}  \r\n  \r\nvar H = function(x, y, z) {  \r\nreturn (x ^ y ^ z);  \r\n}  \r\n  \r\nvar I = function(x, y, z) {  \r\nreturn (y ^ (x | (~ z)));  \r\n}  \r\n  \r\nvar FF = function(a, b, c, d, x, s, ac) {  \r\na = addUnsigned(a, addUnsigned(addUnsigned(F(b, c, d), x), ac));  \r\nreturn addUnsigned(rotateLeft(a, s), b);  \r\n};  \r\n  \r\nvar GG = function(a, b, c, d, x, s, ac) {  \r\na = addUnsigned(a, addUnsigned(addUnsigned(G(b, c, d), x), ac));  \r\nreturn addUnsigned(rotateLeft(a, s), b);  \r\n};  \r\n  \r\nvar HH = function(a, b, c, d, x, s, ac) {  \r\na = addUnsigned(a, addUnsigned(addUnsigned(H(b, c, d), x), ac));  \r\nreturn addUnsigned(rotateLeft(a, s), b);  \r\n};  \r\n  \r\nvar II = function(a, b, c, d, x, s, ac) {  \r\na = addUnsigned(a, addUnsigned(addUnsigned(I(b, c, d), x), ac));  \r\nreturn addUnsigned(rotateLeft(a, s), b);  \r\n};  \r\n  \r\nvar convertToWordArray = function(string) {  \r\nvar lWordCount;  \r\nvar lMessageLength = string.length;  \r\nvar lNumberOfWordsTempOne = lMessageLength + 8;  \r\nvar lNumberOfWordsTempTwo = (lNumberOfWordsTempOne - (lNumberOfWordsTempOne % 64)) / 64;  \r\nvar lNumberOfWords = (lNumberOfWordsTempTwo + 1) * 16;  \r\nvar lWordArray = Array(lNumberOfWords - 1);  \r\nvar lBytePosition = 0;  \r\nvar lByteCount = 0;  \r\nwhile (lByteCount < lMessageLength) {  \r\nlWordCount = (lByteCount - (lByteCount % 4)) / 4;  \r\nlBytePosition = (lByteCount % 4) * 8;  \r\nlWordArray\\[lWordCount\\] = (lWordArray\\[lWordCount\\] | (string.charCodeAt(lByteCount) << lBytePosition));  \r\nlByteCount++;  \r\n}  \r\nlWordCount = (lByteCount - (lByteCount % 4)) / 4;  \r\nlBytePosition = (lByteCount % 4) * 8;  \r\nlWordArray\\[lWordCount\\] = lWordArray\\[lWordCount\\] | (0x80 << lBytePosition);  \r\nlWordArray\\[lNumberOfWords - 2\\] = lMessageLength << 3;  \r\nlWordArray\\[lNumberOfWords - 1\\] = lMessageLength >>> 29;  \r\nreturn lWordArray;  \r\n};  \r\n  \r\nvar wordToHex = function(lValue) {  \r\nvar WordToHexValue = \"\", WordToHexValueTemp = \"\", lByte, lCount;  \r\nfor (lCount = 0; lCount <= 3; lCount++) {  \r\nlByte = (lValue >>> (lCount * 8)) & 255;  \r\nWordToHexValueTemp = \"0\" + lByte.toString(16);  \r\nWordToHexValue = WordToHexValue + WordToHexValueTemp.substr(WordToHexValueTemp.length - 2, 2);  \r\n}  \r\nreturn WordToHexValue;  \r\n};  \r\n  \r\nvar uTF8Encode = function(string) {  \r\nstring = string.replace(/\\\\x0d\\\\x0a/g, \"\\\\x0a\");  \r\nvar output = \"\";  \r\nfor (var n = 0; n < string.length; n++) {  \r\nvar c = string.charCodeAt(n);  \r\nif (c < 128) {  \r\noutput += String.fromCharCode(c);  \r\n} else if ((c > 127) && (c < 2048)) {  \r\noutput += String.fromCharCode((c >> 6) | 192);  \r\noutput += String.fromCharCode((c & 63) | 128);  \r\n} else {  \r\noutput += String.fromCharCode((c >> 12) | 224);  \r\noutput += String.fromCharCode(((c >> 6) & 63) | 128);  \r\noutput += String.fromCharCode((c & 63) | 128);  \r\n}  \r\n}  \r\nreturn output;  \r\n};  \r\n  \r\n$.extend({  \r\nmd5: function(string) {  \r\nvar x = Array();  \r\nvar k, AA, BB, CC, DD, a, b, c, d;  \r\nvar S11=7, S12=12, S13=17, S14=22;  \r\nvar S21=5, S22=9 , S23=14, S24=20;  \r\nvar S31=4, S32=11, S33=16, S34=23;  \r\nvar S41=6, S42=10, S43=15, S44=21;  \r\nstring = uTF8Encode(string);  \r\nx = convertToWordArray(string);  \r\na = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;  \r\nfor (k = 0; k < x.length; k += 16) {  \r\nAA = a; BB = b; CC = c; DD = d;  \r\na = FF(a, b, c, d, x\\[k+0\\], S11, 0xD76AA478);  \r\nd = FF(d, a, b, c, x\\[k+1\\], S12, 0xE8C7B756);  \r\nc = FF(c, d, a, b, x\\[k+2\\], S13, 0x242070DB);  \r\nb = FF(b, c, d, a, x\\[k+3\\], S14, 0xC1BDCEEE);  \r\na = FF(a, b, c, d, x\\[k+4\\], S11, 0xF57C0FAF);  \r\nd = FF(d, a, b, c, x\\[k+5\\], S12, 0x4787C62A);  \r\nc = FF(c, d, a, b, x\\[k+6\\], S13, 0xA8304613);  \r\nb = FF(b, c, d, a, x\\[k+7\\], S14, 0xFD469501);  \r\na = FF(a, b, c, d, x\\[k+8\\], S11, 0x698098D8);  \r\nd = FF(d, a, b, c, x\\[k+9\\], S12, 0x8B44F7AF);  \r\nc = FF(c, d, a, b, x\\[k+10\\], S13, 0xFFFF5BB1);  \r\nb = FF(b, c, d, a, x\\[k+11\\], S14, 0x895CD7BE);  \r\na = FF(a, b, c, d, x\\[k+12\\], S11, 0x6B901122);  \r\nd = FF(d, a, b, c, x\\[k+13\\], S12, 0xFD987193);  \r\nc = FF(c, d, a, b, x\\[k+14\\], S13, 0xA679438E);  \r\nb = FF(b, c, d, a, x\\[k+15\\], S14, 0x49B40821);  \r\na = GG(a, b, c, d, x\\[k+1\\], S21, 0xF61E2562);  \r\nd = GG(d, a, b, c, x\\[k+6\\], S22, 0xC040B340);  \r\nc = GG(c, d, a, b, x\\[k+11\\], S23, 0x265E5A51);  \r\nb = GG(b, c, d, a, x\\[k+0\\], S24, 0xE9B6C7AA);  \r\na = GG(a, b, c, d, x\\[k+5\\], S21, 0xD62F105D);  \r\nd = GG(d, a, b, c, x\\[k+10\\], S22, 0x2441453);  \r\nc = GG(c, d, a, b, x\\[k+15\\], S23, 0xD8A1E681);  \r\nb = GG(b, c, d, a, x\\[k+4\\], S24, 0xE7D3FBC8);  \r\na = GG(a, b, c, d, x\\[k+9\\], S21, 0x21E1CDE6);  \r\nd = GG(d, a, b, c, x\\[k+14\\], S22, 0xC33707D6);  \r\nc = GG(c, d, a, b, x\\[k+3\\], S23, 0xF4D50D87);  \r\nb = GG(b, c, d, a, x\\[k+8\\], S24, 0x455A14ED);  \r\na = GG(a, b, c, d, x\\[k+13\\], S21, 0xA9E3E905);  \r\nd = GG(d, a, b, c, x\\[k+2\\], S22, 0xFCEFA3F8);  \r\nc = GG(c, d, a, b, x\\[k+7\\], S23, 0x676F02D9);  \r\nb = GG(b, c, d, a, x\\[k+12\\], S24, 0x8D2A4C8A);  \r\na = HH(a, b, c, d, x\\[k+5\\], S31, 0xFFFA3942);  \r\nd = HH(d, a, b, c, x\\[k+8\\], S32, 0x8771F681);  \r\nc = HH(c, d, a, b, x\\[k+11\\], S33, 0x6D9D6122);  \r\nb = HH(b, c, d, a, x\\[k+14\\], S34, 0xFDE5380C);  \r\na = HH(a, b, c, d, x\\[k+1\\], S31, 0xA4BEEA44);  \r\nd = HH(d, a, b, c, x\\[k+4\\], S32, 0x4BDECFA9);  \r\nc = HH(c, d, a, b, x\\[k+7\\], S33, 0xF6BB4B60);  \r\nb = HH(b, c, d, a, x\\[k+10\\], S34, 0xBEBFBC70);  \r\na = HH(a, b, c, d, x\\[k+13\\], S31, 0x289B7EC6);  \r\nd = HH(d, a, b, c, x\\[k+0\\], S32, 0xEAA127FA);  \r\nc = HH(c, d, a, b, x\\[k+3\\], S33, 0xD4EF3085);  \r\nb = HH(b, c, d, a, x\\[k+6\\], S34, 0x4881D05);  \r\na = HH(a, b, c, d, x\\[k+9\\], S31, 0xD9D4D039);  \r\nd = HH(d, a, b, c, x\\[k+12\\], S32, 0xE6DB99E5);  \r\nc = HH(c, d, a, b, x\\[k+15\\], S33, 0x1FA27CF8);  \r\nb = HH(b, c, d, a, x\\[k+2\\], S34, 0xC4AC5665);  \r\na = II(a, b, c, d, x\\[k+0\\], S41, 0xF4292244);  \r\nd = II(d, a, b, c, x\\[k+7\\], S42, 0x432AFF97);  \r\nc = II(c, d, a, b, x\\[k+14\\], S43, 0xAB9423A7);  \r\nb = II(b, c, d, a, x\\[k+5\\], S44, 0xFC93A039);  \r\na = II(a, b, c, d, x\\[k+12\\], S41, 0x655B59C3);  \r\nd = II(d, a, b, c, x\\[k+3\\], S42, 0x8F0CCC92);  \r\nc = II(c, d, a, b, x\\[k+10\\], S43, 0xFFEFF47D);  \r\nb = II(b, c, d, a, x\\[k+1\\], S44, 0x85845DD1);  \r\na = II(a, b, c, d, x\\[k+8\\], S41, 0x6FA87E4F);  \r\nd = II(d, a, b, c, x\\[k+15\\], S42, 0xFE2CE6E0);  \r\nc = II(c, d, a, b, x\\[k+6\\], S43, 0xA3014314);  \r\nb = II(b, c, d, a, x\\[k+13\\], S44, 0x4E0811A1);  \r\na = II(a, b, c, d, x\\[k+4\\], S41, 0xF7537E82);  \r\nd = II(d, a, b, c, x\\[k+11\\], S42, 0xBD3AF235);  \r\nc = II(c, d, a, b, x\\[k+2\\], S43, 0x2AD7D2BB);  \r\nb = II(b, c, d, a, x\\[k+9\\], S44, 0xEB86D391);  \r\na = addUnsigned(a, AA);  \r\nb = addUnsigned(b, BB);  \r\nc = addUnsigned(c, CC);  \r\nd = addUnsigned(d, DD);  \r\n}  \r\nvar tempValue = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);  \r\nreturn tempValue.toLowerCase();  \r\n}  \r\n});  \r\n})(jQuery); \r\n```\r\n HTML代码：实现验证码显示：\r\n```\r\n<html>  \r\n    <head>  \r\n        <title>验证码</title>  \r\n    </head>  \r\n    <body>  \r\n        <input id=\"verify\" /><button id=\"submit\">submit</button>  \r\n        <hr>  \r\n        <canvas id=\"canvas\" width=\"120\" height=\"40\"></canvas>  \r\n        <script src=\"jquery-3.3.1.min.js\"></script>  \r\n        <script src=\"jquery.cookie.js\"></script>  \r\n        <script src=\"verify.js\"></script>  \r\n    </body>  \r\n</html>\r\n```\r\n效果如图：\r\n\r\n![](https://images2018.cnblogs.com/blog/1351758/201806/1351758-20180608132530577-2012687708.png)\r\n\r\n如何实现验证，再verify.js中使用cookies方式保存验证码。\r\n\r\n![](https://images2018.cnblogs.com/blog/1351758/201806/1351758-20180608132846938-324228352.png)\r\n\r\n转换为小写并且通过MD5加密保存\r\n\r\n![](https://images2018.cnblogs.com/blog/1351758/201806/1351758-20180608133141636-131921785.png)\r\n\r\n\r\n实现验证：\r\n\r\n在HTML中编写代码：\r\n```\r\n    <script>\r\n        function checkVerify()\r\n        { var verify = $.cookie(\"verify\"); var getVerify = $.md5($(\'#verify\').val()); if(verify == getVerify)\r\n            {\r\n                alert(\"验证码正确！\");\r\n            } else {\r\n                alert(\"验证码错误！\");\r\n            }\r\n        } </script>\r\n```\r\n\r\n完整HTML代码：\r\n```\r\n<html>\r\n    <head>\r\n        <title>验证码</title>\r\n    </head>\r\n    <body>\r\n        <input id=\"verify\" /><button id=\"submit\" Onclick=\"checkVerify();\">submit</button>\r\n        <hr>\r\n        <canvas id=\"canvas\" width=\"120\" height=\"40\"></canvas>\r\n        <script src=\"jquery-3.3.1.min.js\"></script>\r\n        <script src=\"jquery.md5.js\"></script>\r\n        <script src=\"jquery.cookie.js\"></script>\r\n        <script src=\"verify.js\"></script>\r\n    </body>\r\n    <script>\r\n        function checkVerify()\r\n        { var verify = $.cookie(\"verify\"); var getVerify = $.md5($(\'#verify\').val()); if(verify == getVerify)\r\n            {\r\n                alert(\"验证码正确！\");\r\n            } else {\r\n                alert(\"验证码错误！\");\r\n            }\r\n        } </script>\r\n</html>\r\n```\r\n加密方式位MD5...具体使用自己修改。', 'Lang Hu', 1, '1,3,4', 0, 19, 0, 0, 1551941723, 1556627857, '/uploads/Images/thumbnail/2019-03-07/5c80c05b43ab3.jpg', 0);
  INSERT INTO `article` VALUES (1, 'JQuery实现网页全屏', '### 本内容分享本站的全屏实现*   JS', '### 本内容分享本站的全屏实现\r\n\r\n*   JS文件代码\r\n    \r\n        (function($){\r\n          \"use strict\";\r\n        \r\n          function supportFullScreen(){\r\n              var doc = document.documentElement;\r\n              return (\'requestFullscreen\' in doc) || (\'mozRequestFullScreen\' in doc && document.mozFullScreenEnabled) || (\'webkitRequestFullScreen\' in doc);\r\n          }\r\n        \r\n          function requestFullScreen(elem){\r\n              if(elem.requestFullscreen) {\r\n                  elem.requestFullscreen();\r\n              } else if(elem.mozRequestFullScreen) {\r\n                  elem.mozRequestFullScreen();\r\n              } else if(elem.msRequestFullscreen){ \r\n                  elem.msRequestFullscreen();  \r\n              } else if(elem.oRequestFullscreen){\r\n                  elem.oRequestFullscreen();\r\n              } else if(elem.webkitRequestFullscreen) {\r\n                  elem.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);\r\n              } /*else {\r\n                  var  cssText = \'width:100%;height:100%;overflow:hidden;\';\r\n                  document.documentElement.style.cssText = cssText;\r\n                  document.body.style.cssText = cssText;\r\n                  elem.style.cssText = cssText+\';\'+\'margin:0px;padding:0px;\';\r\n                  document.IsFullScreen = true;\r\n              }*/\r\n          }\r\n        \r\n          function fullScreenStatus(){\r\n              return document.fullscreen || document.mozFullScreen || document.webkitIsFullScreen || false;\r\n          }\r\n        \r\n          function cancelFullScreen(){\r\n              if (document.exitFullscreen) {\r\n                  document.exitFullscreen();\r\n              } else if (document.msExitFullscreen) {\r\n                  document.msExitFullscreen();\r\n              } else if (document.mozCancelFullScreen) {\r\n                  document.mozCancelFullScreen();\r\n              } else if(document.oRequestFullscreen) {\r\n                  document.oCancelFullScreen();\r\n              } else if (document.webkitExitFullscreen) {\r\n                  document.webkitExitFullscreen();\r\n                 } /*else {\r\n                  var docHtml  = document.documentElement;\r\n                  var docBody  = document.body;\r\n                  var videobox  = document.getElementById(\'videobox\');\r\n                  docHtml.style.cssText = \"\";\r\n                  docBody.style.cssText = \"\";\r\n                  videobox.style.cssText = \"\";\r\n                  document.IsFullScreen = false;\r\n              }*/\r\n          }\r\n        \r\n          function onFullScreenEvent(callback){\r\n              $(document).on(\"fullscreenchange mozfullscreenchange webkitfullscreenchange\", function(){\r\n                  callback(fullScreenStatus());\r\n              });\r\n          }\r\n        \r\n          $.support.fullscreen = supportFullScreen();\r\n        \r\n          $.fn.fullScreen = function(props){\r\n              if(!$.support.fullscreen || this.length !== 1) {\r\n                  return this;\r\n              }\r\n        \r\n              if(fullScreenStatus()){\r\n                  cancelFullScreen();\r\n                  return this;\r\n              }\r\n        \r\n              var options = $.extend({\r\n                  \'background\'      : \'#111\',\r\n                  \'callback\'        : $.noop( ),\r\n                  \'fullscreenClass\' : \'fullScreen\'\r\n              }, props),\r\n        \r\n              elem = this,\r\n        \r\n              fs = $(\'<div>\', {\r\n                  \'css\' : {\r\n                      \'overflow-y\' : \'auto\',\r\n                      \'background\' : options.background,\r\n                      \'width\'      : \'100%\',\r\n                      \'height\'     : \'100%\'\r\n                  }\r\n              }).insertBefore(elem).append(elem);\r\n        \r\n              elem.addClass( options.fullscreenClass );\r\n        \r\n              requestFullScreen(fs.get(0));\r\n        \r\n              fs.click(function(e){\r\n                  if(e.target == this){\r\n                      cancelFullScreen();\r\n                  }\r\n              });\r\n        \r\n              elem.cancel = function(){\r\n                  cancelFullScreen();\r\n                  return elem;\r\n              };\r\n        \r\n              onFullScreenEvent(function(fullScreen){\r\n                  if(!fullScreen){\r\n                      $(document).off( \'fullscreenchange mozfullscreenchange webkitfullscreenchange\' );\r\n                      elem.removeClass( options.fullscreenClass ).insertBefore(fs);\r\n                      fs.remove();\r\n                  }\r\n        \r\n                  if(options.callback) {\r\n                      options.callback(fullScreen);\r\n                  }\r\n              });\r\n              return elem;\r\n          };\r\n        \r\n          $.fn.cancelFullScreen = function( ) {\r\n                  cancelFullScreen();\r\n                  return this;\r\n          };\r\n        }(jQuery));\r\n    \r\n*   初始化代码\r\n    \r\n        $(\"elem\").click(function() {\r\n          $(\'.container\').fullScreen();\r\n        });\r\n    \r\n    保存为对应的js文件，在页面中直接调用就可以了。注意，需要jquery支持\r\n    =====================================', 'Lang Hu', 1, '1,3', 0, 19, 0, 0, 1551859425, 1551859425, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (2, 'php工具箱升级自带mysql到mysql5.7', '# 下载安装mysql5.7\r\n## 0X01 打开地址 https', '# 下载安装mysql5.7\r\n## 0X01 打开地址 https://dev.mysql.com/downloads/mysql/ 点击 Looking for the latest GA version? 按钮\r\n![](/uploads/Images/article/2019-03-06/5c7f834859502.jpg)\r\n\r\n## 0X02 点击下边的跳过登陆直接下载\r\n![](/uploads/Images/article/2019-03-06/5c7f8372b26b5.png)\r\n\r\n## 0X03 修改PHP工具箱对应目录下的mysql文件夹名称 （提前停止mysql服务）\r\n![](/uploads/Images/article/2019-03-06/5c7f837f500e2.png)\r\n\r\n## 0X04 解压下载好的mysql5.7到PHP目录下，并且修改文件夹名称为MySQL。\r\n![](/uploads/Images/article/2019-03-06/5c7f843ee9496.png)\r\n\r\n## 0X05 通过cmd进入Mysql目录\r\n![](/uploads/Images/article/2019-03-06/5c7f8448cafcb.png)\r\n\r\n## 0X06 新建my.ini文件 内容如下 注意替换你得PHP工具箱的目录\r\n```\r\n# For advice on how to change settings please see\r\n# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html\r\n# *** DO NOT EDIT THIS FILE. It\'s a template which will be copied to the\r\n# *** default location during install, and will be replaced if you\r\n# *** upgrade to a newer version of MySQL.\r\n\r\n[mysqld]\r\n\r\n# Remove leading # and set to the amount of RAM for the most important data\r\n# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.\r\n# innodb_buffer_pool_size = 128M\r\n\r\n# Remove leading # to turn on a very important data integrity option: logging\r\n# changes to the binary log between backups.\r\n# log_bin\r\n\r\n# These are commonly set, remove the # and set as required.\r\nbasedir = \"D:/php/myphp_www/PHPTutorial/MySQL/\"\r\ndatadir = \"D:/php/myphp_www/PHPTutorial/MySQL/data/\"\r\nport = 3306\r\n# server_id = .....\r\n\r\n\r\n# Remove leading # to set options mainly useful for reporting servers.\r\n# The server defaults are faster for transactions and fast SELECTs.\r\n# Adjust sizes as needed, experiment to find the optimal values.\r\n# join_buffer_size = 128M\r\n# sort_buffer_size = 2M\r\n# read_rnd_buffer_size = 2M \r\n\r\nsql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES\r\ndefault-storage-engine=INNODB\r\n```\r\n## 0X07 回到CMD窗口，执行命令。\r\n![](/uploads/Images/article/2019-03-06/5c7f84550c7cd.png)\r\n\r\n## 0X08 提示安装拒绝，这时使用管理员身份运行命令窗口。再从新执行install命令\r\n![](/uploads/Images/article/2019-03-06/5c7f8467d60cb.png)\r\n\r\n## 0X09 此时mysql5.7已经安装成功，使用net start mysql 尝试启动服务（管理员模式下能够正常启动，普通权限无法启动）\r\n![](/uploads/Images/article/2019-03-06/5c7f84a62f62a.png)\r\n![](/uploads/Images/article/2019-03-06/5c7f84b009a31.png)\r\n\r\n## 0X0A 尝试再php工具箱中启动或停止mysql服务（此时PHP工具箱无法启动mysql服务。）\r\n![](/uploads/Images/article/2019-03-06/5c7f84baf413e.png)\r\n\r\n## 0X0B 在管理员模式下执行\r\n![](/uploads/Images/article/2019-03-06/5c7f84c6736f1.png)\r\n\r\n## 0X0C 回到PHP工具箱 点击重启，此时mysql服务能够正确的被启动。\r\n![](/uploads/Images/article/2019-03-06/5c7f84ce5970c.png)\r\n\r\n# 数据恢复\r\n\r\n## 0X01 回到之前的MySQL_BAK目录下赋值data中的内容到新的MySQL的目录下，同户名文件选择跳过覆盖。\r\n![](/uploads/Images/article/2019-03-06/5c7f84da5d404.png)\r\n\r\n## 0X02 通过MYSQL管理工具登陆MYSQL\r\n账号密码均为root，此时回1045无法登陆\r\n![](/uploads/Images/article/2019-03-06/5c7f84e7e9377.png)\r\n\r\n## 0X03 由于MYSQL安装过程中密码是水机产生，所以我们需要通过日志来查看密码。\r\n打开MYSQL/data目录下的.err文件 查找并复制密码，使用此密码登陆mysql，并修改设置为自己的密码。\r\n![](/uploads/Images/article/2019-03-06/5c7f84fc0e253.png)\r\n\r\n![](/uploads/Images/article/2019-03-06/5c7f8504eedfd.png)\r\n\r\n## 0X04 此时登陆mysql\r\n![](/uploads/Images/article/2019-03-06/5c7f850d3fb09.png)\r\n\r\n## 0X05 PHP工具箱升级MySQL5.7完毕', 'Lang Hu', 1, '', 0, 5, 0, 0, 1551859625, 1556016361, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (3, 'JQuery+css实现分页', '### 本内容分享本站的分页按钮实\r\n\r\n*   css代码（适配手机和pc 1024为分界线）\r\n    \r\n        @media screen and  (min-width: 1024px) {\r\n          .page-box { text-align: center; display: inline-block; padding-left: 0; margin: 20px 0;', '### 本内容分享本站的分页按钮实\r\n\r\n*   css代码（适配手机和pc 1024为分界线）\r\n    \r\n        @media screen and  (min-width: 1024px) {\r\n          .page-box { text-align: center; display: inline-block; padding-left: 0; margin: 20px 0; border-radius: 4px; }\r\n          .page-box .button { height: 35px; width: 50px; display: inline; position: relative; float: left; padding-top: 6px; margin-left: -1px; line-height: 1.42857143; color: #337ab7; text-decoration: none; background-color: #fff; border: 1px solid #ddd; }\r\n          .page-box .button::before{ color: #EB5055; content: attr(data-hover); position: absolute; outline:0; white-space: nowrap; opacity: 0; text-shadow: 0 0 1px rgba(255,255,255,0.3); -webkit-transform: scale(1.1) translateX(10px) translateY(-10px) rotate(4deg); -moz-transform: scale(1.1) translateX(10px) translateY(-10px) rotate(4deg); transform: scale(1.1) translateX(10px) translateY(-10px) rotate(4deg); -webkit-transition: -webkit-transform 0.3s, opacity 0.3s; -moz-transition: -moz-transform 0.3s, opacity 0.3s; transition: transform 0.3s, opacity 0.3s; }\r\n          .page-box .button:hover::before,a:focus::before { outline:0; white-space: nowrap; -webkit-transform: scale(1) translateX(0px) translateY(0px) rotate(0deg); -moz-transform: scale(1) translateX(0px) translateY(0px) rotate(0deg); transform: scale(1) translateX(0px) translateY(0px) rotate(0deg); opacity: 1; }\r\n          .page-box .button.disabled { background-color: rgb(238, 238, 238); }\r\n          .page-box .button.active { background-color: rgb(238, 238, 238); }\r\n          .page-box .button:hover { background-color: rgb(238, 238, 238); }\r\n          .page-box .page-select { height:35px; width: 245px; display: inline; float: left; overflow: hidden; }\r\n          .page-box .page-select ul { float: left; display: inline; width: 999999999px;  }    \r\n          .page-box .page-select ul li { transition: all 600ms ease 0s; float: left; height: 35px; }\r\n        }\r\n        @media screen and  (max-width: 1023px) {\r\n          .page-box { text-align: center; display: inline-block; padding-left: 0; margin: 20px 0; border-radius: 4px; }\r\n          .page-box .button { height: 35px; width: 40px; display: inline; position: relative; float: left; padding-top: 6px; margin-left: -1px; line-height: 1.42857143; color: #337ab7; text-decoration: none; background-color: #fff; border: 1px solid #ddd; }\r\n          .page-box .button::before{ color: #EB5055; content: attr(data-hover); position: absolute; outline:0; white-space: nowrap; opacity: 0; text-shadow: 0 0 1px rgba(255,255,255,0.3); -webkit-transform: scale(1.1) translateX(10px) translateY(-10px) rotate(4deg); -moz-transform: scale(1.1) translateX(10px) translateY(-10px) rotate(4deg); transform: scale(1.1) translateX(10px) translateY(-10px) rotate(4deg); -webkit-transition: -webkit-transform 0.3s, opacity 0.3s; -moz-transition: -moz-transform 0.3s, opacity 0.3s; transition: transform 0.3s, opacity 0.3s; }\r\n          .page-box .button:hover::before,a:focus::before { outline:0; white-space: nowrap; -webkit-transform: scale(1) translateX(0px) translateY(0px) rotate(0deg); -moz-transform: scale(1) translateX(0px) translateY(0px) rotate(0deg); transform: scale(1) translateX(0px) translateY(0px) rotate(0deg); opacity: 1; }\r\n          .page-box .button.disabled { background-color: rgb(238, 238, 238); }\r\n          .page-box .button.active { background-color: rgb(238, 238, 238); }\r\n          .page-box .button:hover { background-color: rgb(238, 238, 238); }\r\n          .page-box .page-select { height:35px; width: 117px; display: inline; float: left; overflow: hidden; }\r\n          .page-box .page-select ul { float: left; display: inline; width: 999999999px;  }    \r\n          .page-box .page-select ul li { transition: all 600ms ease 0s; float: left; height: 35px; }\r\n        }\r\n    \r\n*   JS文件代码 （与css文件对应）\r\n    \r\n        (function($,window,document){\r\n          function Paging(elem,options) {\r\n              this.elem = elem;\r\n              this.options = {\r\n                  pageNo: options.initPageNo||1, // 初始页码\r\n                  totalPages: options.totalPages||1, // 总页数\r\n                  slideSpeed: options.slideSpeed||0, // 滑动速度\r\n                  callback: options.callback||function(){ } // 回调函数\r\n              };\r\n              this.init();\r\n          }\r\n          Paging.prototype = {\r\n              constructor:Paging,\r\n              init: function() {\r\n                      this.createDom();\r\n                      this.bindEvents();\r\n                  },\r\n              createDom: function() {\r\n                      var elem = this.elem;\r\n                      var options = this.options;\r\n                      var Prev = \"\";\r\n                      var Next = \"\";\r\n                      var First = \"\";\r\n                      var Last = \"\";\r\n                      var Center = \"\";\r\n                      var Html = \"\";\r\n                      options.pageNo == 1 ? Prev = \'<span class=\"prev-page button disabled\" data-hover=\"&lt;\">&lt;</span>\'  : Prev = \'<span class=\"prev-page button\" data-hover=\"&lt;\">&lt;</span>\';\r\n                      options.pageNo == options.totalPages ? Next = \'<span class=\"next-page button disabled\" data-hover=\"&gt;\">&gt;</span>\'  : Next = \'<span class=\"next-page button\" data-hover=\"&gt;\">&gt;</span>\';\r\n                      if (options.totalPages > 5) {\r\n                          options.pageNo == 1 ? First = \'<span class=\"first-page button disabled\" data-hover=\"&laquo;\">&laquo;</span>\'  : First = \'<span class=\"first-page button\" data-hover=\"&laquo;\">&laquo;</span>\';\r\n                          options.pageNo == options.totalPages ? Last = \'<span class=\"last-page button disabled\" data-hover=\"&raquo;\">&raquo;</span>\' : Last = \'<span class=\"last-page button\" data-hover=\"&raquo;\">&raquo;</span>\';\r\n                      }\r\n                      Center += \'<div class=\"page-select\"><ul>\';\r\n                      for (var i = 1 ; i <= options.totalPages ; i++ ) {\r\n                          i != options.pageNo ? Center += \'<li class=\"button\" data-hover=\"\' + i + \'\">\' + i + \'</li>\' : Center += \'<li class=\"button active\" data-hover=\"\' + i + \'\">\' + i + \'</li>\';\r\n                      }\r\n                      Center += \'</ul></div>\';\r\n                      Html = \'<div class=\"page-box\">\' + First + Prev +  Center + Next + Last +\'</div>\';\r\n                      elem.html(Html);\r\n                  },\r\n              bindEvents: function() {\r\n                      var elem = this.elem;\r\n                      var options = this.options;\r\n                      var Prev = elem.find(\'.page-box>.prev-page\');\r\n                      var Next = elem.find(\'.page-box>.next-page\');\r\n                      var First = elem.find(\'.page-box>.first-page\');\r\n                      var Last = elem.find(\'.page-box>.last-page\');\r\n                      var currPage = options.pageNo;\r\n                      var Page = elem.find(\".page-box>.page-select>ul>li.button\");\r\n                      Prev.on(\'click\',function() {\r\n                          if (currPage > 1) {\r\n                              currPage--;\r\n                              handles(currPage);\r\n                          }\r\n                      });\r\n                      Next.on(\'click\',function() {\r\n                          if (currPage < options.totalPages) {\r\n                              currPage++;\r\n                              handles(currPage);\r\n                          }\r\n                      });\r\n                      First.on(\'click\',function() {\r\n                          if (currPage != 1) {\r\n                              currPage = 1;\r\n                              handles(currPage);\r\n                          }\r\n                      });\r\n                      Last.on(\'click\',function() {\r\n                          if (currPage != options.totalPages) {\r\n                              currPage = options.totalPages;\r\n                              handles(currPage);\r\n                          }\r\n                      });\r\n                      Page.on(\'click\',function(){\r\n                          var val = $(this).attr(\'data-hover\');\r\n                          if ( /-?[1-9]\\d*/.test(val) ) {\r\n                              currPage = val;\r\n                              handles(currPage);\r\n                          }\r\n                      });\r\n                      function handles(currPage) {\r\n                          Page.removeClass([\'active\',\'disabled\']);\r\n                          elem.find(\'[data-hover=\"\'+currPage+\'\"]\').addClass(\'active\');\r\n                          currPage == 1 ? Prev.addClass(\'disabled\') && First.addClass(\'disabled\') : Prev.removeClass(\'disabled\') && First.removeClass(\'disabled\');\r\n                          currPage == options.totalPages ? Next.addClass(\'disabled\') && Last.addClass(\'disabled\') : Next.removeClass(\'disabled\') && Last.removeClass(\'disabled\');\r\n                          var distance = 0;\r\n                          var liWidth = Page.width() + 1;\r\n                          console.log(liWidth);\r\n                          if ($(window).width() >= 1024) {\r\n                              if( currPage >= 3 && currPage <= options.totalPages-2 )\r\n                                      distance = ( currPage - 3 ) * liWidth;\r\n                              if( currPage == 2 || currPage == 1)\r\n                                      distance = 0;\r\n                              if( currPage > options.totalPages-2)\r\n                                  distance = ( options.totalPages - 5 ) * liWidth;\r\n                          } else {\r\n                              if( currPage >= 2 && currPage <= options.totalPages - 1 )\r\n                                      distance = ( currPage - 2 ) * liWidth;\r\n                              if( currPage == 2 || currPage == 1)\r\n                                      distance = 0;\r\n                              if( currPage > options.totalPages - 1)\r\n                                  distance = ( options.totalPages - 3 ) * liWidth;\r\n                          }\r\n                          Page.css(\'transform\',\'translateX(\' + (-distance) + \'px)\');\r\n                          options.callback(currPage);\r\n                      }\r\n                      handles(options.pageNo);\r\n                      }\r\n          }\r\n          $.fn.paging=function(options) {\r\n              return new Paging($(this),options);\r\n          }\r\n        })(jQuery,window,document);\r\n    \r\n*   完整html代码\r\n    \r\n        <!DOCTYPE html>\r\n        <html>\r\n        <head>\r\n        <title>JQuery分页</title>\r\n        <link rel=\"stylesheet\" type=\"text/css\" href=\"css/style.css\">\r\n        </head>\r\n        <body>\r\n        <div id=\"page\"></div>\r\n        <script src=\"js/JQuery.min.js\"></script>\r\n        <script src=\"js/Paging.js\"></script>\r\n        <script type=\"text/javascript\">\r\n          // TODO 初始化\r\n          $(\'.page\').paging({\r\n              initPageNo: 1, // 初始页码\r\n              totalPages: 200, //总页数\r\n              slideSpeed: 600, // 缓动速度。单位毫秒\r\n              callback: function(page) { // 回调函数\r\n                  // 你要执行的操作\r\n                  console.log(page);\r\n              }\r\n          });\r\n        </script>\r\n        </body>\r\n        </html>\r\n    \r\n*   目前只有分页，没有条数，不喜勿喷\r\n    ================', 'Lang Hu', 1, '', 0, 1, 0, 0, 1551861355, 1552407046, '/uploads/Images/thumbnail/2019-03-06/5c7f866bc7bf1.png', 0);
  INSERT INTO `article` VALUES (4, '这是第一篇博客--创始之初', '这篇文章阐述了为何', '为什么写这个博客？\r\n==\r\n肯定是作业啊，加上自己也想自己写一个，所以就这样咯\r\n发展到什么地步了？\r\n==\r\n目前只支持电脑端啦。。。分辨率在1024*768以上的都不会出现布局混乱的情况。。小了就不一定了。。。。\r\n什么时候开始兼容手机端？\r\n==\r\n等吧，什么时候有时间就什么时候开始兼容\r\n结语\r\n==\r\n这是一个新的尝试，但是会越来越好。', 'Lang Hu', 1, '', 0, 5, 0, 0, 1551861755, 1554817600, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (5, '测试带标签的文章添加', '多标签选择测试', '2', 'Lang Hu', 1, '2,4,6,8', 0, 9, 0, 0, 1551863753, 1556627679, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (6, '带分类和标签的文章测试', '2', '# 后端\r\n## PHP, HTML, 后端', 'Lang Hu', 2, '2,4,5', 0, 12, 0, 0, 1551864655, 1556627678, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (10, 'JQuery笔记JQuery.DataTable.js使用。', 'jquery强大插件之DataTable', '相关文件：\r\n\r\n[https://git.coding.net/HULANG-BTB/JQuery.DataTable.js.git](https://git.coding.net/HULANG-BTB/JQuery.DataTable.js.git)\r\n\r\nHTML代码：\r\n```\r\n 1 <html>\r\n 2     <head>\r\n 3         <title>DataTable</title>\r\n 4         <link rel=\"stylesheet\" href=\"./jquery.dataTables.min.css\">\r\n 5     </head>\r\n 6     <body>\r\n 7         <table id=\"example\" class=\"display\" style=\"width:100%\">\r\n 8         <thead>\r\n 9             <tr>\r\n 10                 <th>Name</th>\r\n 11                 <th>Position</th>\r\n 12                 <th>Office</th>\r\n 13                 <th>Age</th>\r\n 14                 <th>Start date</th>\r\n 15                 <th>Salary</th>\r\n 16             </tr>\r\n 17         </thead>\r\n 18         <tbody>\r\n 19             <tr>\r\n 20                 <td>Tiger Nixon</td>\r\n 21                 <td>System Architect</td>\r\n 22                 <td>Edinburgh</td>\r\n 23                 <td>61</td>\r\n 24                 <td>2011/04/25</td>\r\n 25                 <td>$320,800</td>\r\n 26             </tr>\r\n 27             <tr>\r\n 28                 <td>Garrett Winters</td>\r\n 29                 <td>Accountant</td>\r\n 30                 <td>Tokyo</td>\r\n 31                 <td>63</td>\r\n 32                 <td>2011/07/25</td>\r\n 33                 <td>$170,750</td>\r\n 34             </tr>\r\n 35             <tr>\r\n 36                 <td>Ashton Cox</td>\r\n 37                 <td>Junior Technical Author</td>\r\n 38                 <td>San Francisco</td>\r\n 39                 <td>66</td>\r\n 40                 <td>2009/01/12</td>\r\n 41                 <td>$86,000</td>\r\n 42             </tr>\r\n 43             <tr>\r\n 44                 <td>Cedric Kelly</td>\r\n 45                 <td>Senior Javascript Developer</td>\r\n 46                 <td>Edinburgh</td>\r\n 47                 <td>22</td>\r\n 48                 <td>2012/03/29</td>\r\n 49                 <td>$433,060</td>\r\n 50             </tr>\r\n 51             <tr>\r\n 52                 <td>Airi Satou</td>\r\n 53                 <td>Accountant</td>\r\n 54                 <td>Tokyo</td>\r\n 55                 <td>33</td>\r\n 56                 <td>2008/11/28</td>\r\n 57                 <td>$162,700</td>\r\n 58             </tr>\r\n 59             <tr>\r\n 60                 <td>Brielle Williamson</td>\r\n 61                 <td>Integration Specialist</td>\r\n 62                 <td>New York</td>\r\n 63                 <td>61</td>\r\n 64                 <td>2012/12/02</td>\r\n 65                 <td>$372,000</td>\r\n 66             </tr>\r\n 67             <tr>\r\n 68                 <td>Herrod Chandler</td>\r\n 69                 <td>Sales Assistant</td>\r\n 70                 <td>San Francisco</td>\r\n 71                 <td>59</td>\r\n 72                 <td>2012/08/06</td>\r\n 73                 <td>$137,500</td>\r\n 74             </tr>\r\n 75             <tr>\r\n 76                 <td>Rhona Davidson</td>\r\n 77                 <td>Integration Specialist</td>\r\n 78                 <td>Tokyo</td>\r\n 79                 <td>55</td>\r\n 80                 <td>2010/10/14</td>\r\n 81                 <td>$327,900</td>\r\n 82             </tr>\r\n 83             <tr>\r\n 84                 <td>Colleen Hurst</td>\r\n 85                 <td>Javascript Developer</td>\r\n 86                 <td>San Francisco</td>\r\n 87                 <td>39</td>\r\n 88                 <td>2009/09/15</td>\r\n 89                 <td>$205,500</td>\r\n 90             </tr>\r\n 91             <tr>\r\n 92                 <td>Sonya Frost</td>\r\n 93                 <td>Software Engineer</td>\r\n 94                 <td>Edinburgh</td>\r\n 95                 <td>23</td>\r\n 96                 <td>2008/12/13</td>\r\n 97                 <td>$103,600</td>\r\n 98             </tr>\r\n 99             <tr>\r\n100                 <td>Jena Gaines</td>\r\n101                 <td>Office Manager</td>\r\n102                 <td>London</td>\r\n103                 <td>30</td>\r\n104                 <td>2008/12/19</td>\r\n105                 <td>$90,560</td>\r\n106             </tr>\r\n107             <tr>\r\n108                 <td>Quinn Flynn</td>\r\n109                 <td>Support Lead</td>\r\n110                 <td>Edinburgh</td>\r\n111                 <td>22</td>\r\n112                 <td>2013/03/03</td>\r\n113                 <td>$342,000</td>\r\n114             </tr>\r\n115             <tr>\r\n116                 <td>Charde Marshall</td>\r\n117                 <td>Regional Director</td>\r\n118                 <td>San Francisco</td>\r\n119                 <td>36</td>\r\n120                 <td>2008/10/16</td>\r\n121                 <td>$470,600</td>\r\n122             </tr>\r\n123             <tr>\r\n124                 <td>Haley Kennedy</td>\r\n125                 <td>Senior Marketing Designer</td>\r\n126                 <td>London</td>\r\n127                 <td>43</td>\r\n128                 <td>2012/12/18</td>\r\n129                 <td>$313,500</td>\r\n130             </tr>\r\n131             <tr>\r\n132                 <td>Tatyana Fitzpatrick</td>\r\n133                 <td>Regional Director</td>\r\n134                 <td>London</td>\r\n135                 <td>19</td>\r\n136                 <td>2010/03/17</td>\r\n137                 <td>$385,750</td>\r\n138             </tr>\r\n139             <tr>\r\n140                 <td>Michael Silva</td>\r\n141                 <td>Marketing Designer</td>\r\n142                 <td>London</td>\r\n143                 <td>66</td>\r\n144                 <td>2012/11/27</td>\r\n145                 <td>$198,500</td>\r\n146             </tr>\r\n147             <tr>\r\n148                 <td>Paul Byrd</td>\r\n149                 <td>Chief Financial Officer (CFO)</td>\r\n150                 <td>New York</td>\r\n151                 <td>64</td>\r\n152                 <td>2010/06/09</td>\r\n153                 <td>$725,000</td>\r\n154             </tr>\r\n155             <tr>\r\n156                 <td>Gloria Little</td>\r\n157                 <td>Systems Administrator</td>\r\n158                 <td>New York</td>\r\n159                 <td>59</td>\r\n160                 <td>2009/04/10</td>\r\n161                 <td>$237,500</td>\r\n162             </tr>\r\n163             <tr>\r\n164                 <td>Bradley Greer</td>\r\n165                 <td>Software Engineer</td>\r\n166                 <td>London</td>\r\n167                 <td>41</td>\r\n168                 <td>2012/10/13</td>\r\n169                 <td>$132,000</td>\r\n170             </tr>\r\n171             <tr>\r\n172                 <td>Dai Rios</td>\r\n173                 <td>Personnel Lead</td>\r\n174                 <td>Edinburgh</td>\r\n175                 <td>35</td>\r\n176                 <td>2012/09/26</td>\r\n177                 <td>$217,500</td>\r\n178             </tr>\r\n179             <tr>\r\n180                 <td>Jenette Caldwell</td>\r\n181                 <td>Development Lead</td>\r\n182                 <td>New York</td>\r\n183                 <td>30</td>\r\n184                 <td>2011/09/03</td>\r\n185                 <td>$345,000</td>\r\n186             </tr>\r\n187             <tr>\r\n188                 <td>Yuri Berry</td>\r\n189                 <td>Chief Marketing Officer (CMO)</td>\r\n190                 <td>New York</td>\r\n191                 <td>40</td>\r\n192                 <td>2009/06/25</td>\r\n193                 <td>$675,000</td>\r\n194             </tr>\r\n195             <tr>\r\n196                 <td>Caesar Vance</td>\r\n197                 <td>Pre-Sales Support</td>\r\n198                 <td>New York</td>\r\n199                 <td>21</td>\r\n200                 <td>2011/12/12</td>\r\n201                 <td>$106,450</td>\r\n202             </tr>\r\n203             <tr>\r\n204                 <td>Doris Wilder</td>\r\n205                 <td>Sales Assistant</td>\r\n206                 <td>Sidney</td>\r\n207                 <td>23</td>\r\n208                 <td>2010/09/20</td>\r\n209                 <td>$85,600</td>\r\n210             </tr>\r\n211             <tr>\r\n212                 <td>Angelica Ramos</td>\r\n213                 <td>Chief Executive Officer (CEO)</td>\r\n214                 <td>London</td>\r\n215                 <td>47</td>\r\n216                 <td>2009/10/09</td>\r\n217                 <td>$1,200,000</td>\r\n218             </tr>\r\n219             <tr>\r\n220                 <td>Gavin Joyce</td>\r\n221                 <td>Developer</td>\r\n222                 <td>Edinburgh</td>\r\n223                 <td>42</td>\r\n224                 <td>2010/12/22</td>\r\n225                 <td>$92,575</td>\r\n226             </tr>\r\n227             <tr>\r\n228                 <td>Jennifer Chang</td>\r\n229                 <td>Regional Director</td>\r\n230                 <td>Singapore</td>\r\n231                 <td>28</td>\r\n232                 <td>2010/11/14</td>\r\n233                 <td>$357,650</td>\r\n234             </tr>\r\n235             <tr>\r\n236                 <td>Brenden Wagner</td>\r\n237                 <td>Software Engineer</td>\r\n238                 <td>San Francisco</td>\r\n239                 <td>28</td>\r\n240                 <td>2011/06/07</td>\r\n241                 <td>$206,850</td>\r\n242             </tr>\r\n243             <tr>\r\n244                 <td>Fiona Green</td>\r\n245                 <td>Chief Operating Officer (COO)</td>\r\n246                 <td>San Francisco</td>\r\n247                 <td>48</td>\r\n248                 <td>2010/03/11</td>\r\n249                 <td>$850,000</td>\r\n250             </tr>\r\n251             <tr>\r\n252                 <td>Shou Itou</td>\r\n253                 <td>Regional Marketing</td>\r\n254                 <td>Tokyo</td>\r\n255                 <td>20</td>\r\n256                 <td>2011/08/14</td>\r\n257                 <td>$163,000</td>\r\n258             </tr>\r\n259             <tr>\r\n260                 <td>Michelle House</td>\r\n261                 <td>Integration Specialist</td>\r\n262                 <td>Sidney</td>\r\n263                 <td>37</td>\r\n264                 <td>2011/06/02</td>\r\n265                 <td>$95,400</td>\r\n266             </tr>\r\n267             <tr>\r\n268                 <td>Suki Burks</td>\r\n269                 <td>Developer</td>\r\n270                 <td>London</td>\r\n271                 <td>53</td>\r\n272                 <td>2009/10/22</td>\r\n273                 <td>$114,500</td>\r\n274             </tr>\r\n275             <tr>\r\n276                 <td>Prescott Bartlett</td>\r\n277                 <td>Technical Author</td>\r\n278                 <td>London</td>\r\n279                 <td>27</td>\r\n280                 <td>2011/05/07</td>\r\n281                 <td>$145,000</td>\r\n282             </tr>\r\n283             <tr>\r\n284                 <td>Gavin Cortez</td>\r\n285                 <td>Team Leader</td>\r\n286                 <td>San Francisco</td>\r\n287                 <td>22</td>\r\n288                 <td>2008/10/26</td>\r\n289                 <td>$235,500</td>\r\n290             </tr>\r\n291             <tr>\r\n292                 <td>Martena Mccray</td>\r\n293                 <td>Post-Sales support</td>\r\n294                 <td>Edinburgh</td>\r\n295                 <td>46</td>\r\n296                 <td>2011/03/09</td>\r\n297                 <td>$324,050</td>\r\n298             </tr>\r\n299             <tr>\r\n300                 <td>Unity Butler</td>\r\n301                 <td>Marketing Designer</td>\r\n302                 <td>San Francisco</td>\r\n303                 <td>47</td>\r\n304                 <td>2009/12/09</td>\r\n305                 <td>$85,675</td>\r\n306             </tr>\r\n307             <tr>\r\n308                 <td>Howard Hatfield</td>\r\n309                 <td>Office Manager</td>\r\n310                 <td>San Francisco</td>\r\n311                 <td>51</td>\r\n312                 <td>2008/12/16</td>\r\n313                 <td>$164,500</td>\r\n314             </tr>\r\n315             <tr>\r\n316                 <td>Hope Fuentes</td>\r\n317                 <td>Secretary</td>\r\n318                 <td>San Francisco</td>\r\n319                 <td>41</td>\r\n320                 <td>2010/02/12</td>\r\n321                 <td>$109,850</td>\r\n322             </tr>\r\n323             <tr>\r\n324                 <td>Vivian Harrell</td>\r\n325                 <td>Financial Controller</td>\r\n326                 <td>San Francisco</td>\r\n327                 <td>62</td>\r\n328                 <td>2009/02/14</td>\r\n329                 <td>$452,500</td>\r\n330             </tr>\r\n331             <tr>\r\n332                 <td>Timothy Mooney</td>\r\n333                 <td>Office Manager</td>\r\n334                 <td>London</td>\r\n335                 <td>37</td>\r\n336                 <td>2008/12/11</td>\r\n337                 <td>$136,200</td>\r\n338             </tr>\r\n339             <tr>\r\n340                 <td>Jackson Bradshaw</td>\r\n341                 <td>Director</td>\r\n342                 <td>New York</td>\r\n343                 <td>65</td>\r\n344                 <td>2008/09/26</td>\r\n345                 <td>$645,750</td>\r\n346             </tr>\r\n347             <tr>\r\n348                 <td>Olivia Liang</td>\r\n349                 <td>Support Engineer</td>\r\n350                 <td>Singapore</td>\r\n351                 <td>64</td>\r\n352                 <td>2011/02/03</td>\r\n353                 <td>$234,500</td>\r\n354             </tr>\r\n355             <tr>\r\n356                 <td>Bruno Nash</td>\r\n357                 <td>Software Engineer</td>\r\n358                 <td>London</td>\r\n359                 <td>38</td>\r\n360                 <td>2011/05/03</td>\r\n361                 <td>$163,500</td>\r\n362             </tr>\r\n363             <tr>\r\n364                 <td>Sakura Yamamoto</td>\r\n365                 <td>Support Engineer</td>\r\n366                 <td>Tokyo</td>\r\n367                 <td>37</td>\r\n368                 <td>2009/08/19</td>\r\n369                 <td>$139,575</td>\r\n370             </tr>\r\n371             <tr>\r\n372                 <td>Thor Walton</td>\r\n373                 <td>Developer</td>\r\n374                 <td>New York</td>\r\n375                 <td>61</td>\r\n376                 <td>2013/08/11</td>\r\n377                 <td>$98,540</td>\r\n378             </tr>\r\n379             <tr>\r\n380                 <td>Finn Camacho</td>\r\n381                 <td>Support Engineer</td>\r\n382                 <td>San Francisco</td>\r\n383                 <td>47</td>\r\n384                 <td>2009/07/07</td>\r\n385                 <td>$87,500</td>\r\n386             </tr>\r\n387             <tr>\r\n388                 <td>Serge Baldwin</td>\r\n389                 <td>Data Coordinator</td>\r\n390                 <td>Singapore</td>\r\n391                 <td>64</td>\r\n392                 <td>2012/04/09</td>\r\n393                 <td>$138,575</td>\r\n394             </tr>\r\n395             <tr>\r\n396                 <td>Zenaida Frank</td>\r\n397                 <td>Software Engineer</td>\r\n398                 <td>New York</td>\r\n399                 <td>63</td>\r\n400                 <td>2010/01/04</td>\r\n401                 <td>$125,250</td>\r\n402             </tr>\r\n403             <tr>\r\n404                 <td>Zorita Serrano</td>\r\n405                 <td>Software Engineer</td>\r\n406                 <td>San Francisco</td>\r\n407                 <td>56</td>\r\n408                 <td>2012/06/01</td>\r\n409                 <td>$115,000</td>\r\n410             </tr>\r\n411             <tr>\r\n412                 <td>Jennifer Acosta</td>\r\n413                 <td>Junior Javascript Developer</td>\r\n414                 <td>Edinburgh</td>\r\n415                 <td>43</td>\r\n416                 <td>2013/02/01</td>\r\n417                 <td>$75,650</td>\r\n418             </tr>\r\n419             <tr>\r\n420                 <td>Cara Stevens</td>\r\n421                 <td>Sales Assistant</td>\r\n422                 <td>New York</td>\r\n423                 <td>46</td>\r\n424                 <td>2011/12/06</td>\r\n425                 <td>$145,600</td>\r\n426             </tr>\r\n427             <tr>\r\n428                 <td>Hermione Butler</td>\r\n429                 <td>Regional Director</td>\r\n430                 <td>London</td>\r\n431                 <td>47</td>\r\n432                 <td>2011/03/21</td>\r\n433                 <td>$356,250</td>\r\n434             </tr>\r\n435             <tr>\r\n436                 <td>Lael Greer</td>\r\n437                 <td>Systems Administrator</td>\r\n438                 <td>London</td>\r\n439                 <td>21</td>\r\n440                 <td>2009/02/27</td>\r\n441                 <td>$103,500</td>\r\n442             </tr>\r\n443             <tr>\r\n444                 <td>Jonas Alexander</td>\r\n445                 <td>Developer</td>\r\n446                 <td>San Francisco</td>\r\n447                 <td>30</td>\r\n448                 <td>2010/07/14</td>\r\n449                 <td>$86,500</td>\r\n450             </tr>\r\n451             <tr>\r\n452                 <td>Shad Decker</td>\r\n453                 <td>Regional Director</td>\r\n454                 <td>Edinburgh</td>\r\n455                 <td>51</td>\r\n456                 <td>2008/11/13</td>\r\n457                 <td>$183,000</td>\r\n458             </tr>\r\n459             <tr>\r\n460                 <td>Michael Bruce</td>\r\n461                 <td>Javascript Developer</td>\r\n462                 <td>Singapore</td>\r\n463                 <td>29</td>\r\n464                 <td>2011/06/27</td>\r\n465                 <td>$183,000</td>\r\n466             </tr>\r\n467             <tr>\r\n468                 <td>Donna Snider</td>\r\n469                 <td>Customer Support</td>\r\n470                 <td>New York</td>\r\n471                 <td>27</td>\r\n472                 <td>2011/01/25</td>\r\n473                 <td>$112,000</td>\r\n474             </tr>\r\n475         </tbody>\r\n476         <tfoot>\r\n477             <tr>\r\n478                 <th>Name</th>\r\n479                 <th>Position</th>\r\n480                 <th>Office</th>\r\n481                 <th>Age</th>\r\n482                 <th>Start date</th>\r\n483                 <th>Salary</th>\r\n484             </tr>\r\n485         </tfoot>\r\n486     </table>\r\n487     <script src=\"./jquery-3.3.1.js\"></script>\r\n488     <script src=\"./jquery.dataTables.min.js\"></script>\r\n489     <script>\r\n490         $(document).ready(function() { 491             $(\'#example\').DataTable(); 492             $(\'#example\').removeClass( \'display\' ).addClass(\'table table-striped table-bordered\'); 493 } ); 494         \r\n495     </script>\r\n496     </body>\r\n497 </html>\r\n```\r\n效果：\r\n\r\n![](/uploads/Images/article/2019-03-07/5c80c0f104a58.png)', 'Lang Hu', 1, '1,3,4', 0, 10, 0, 0, 1551941927, 1556627681, '/uploads/Images/thumbnail/2019-03-07/5c80c127483b3.png', 0);
  INSERT INTO `article` VALUES (11, 'PHP获取真实IP地址', '通过请求头获取客户端真实IP', '```\r\n<?php\r\n\r\n    function get_client_ipaddress($type = 0)\r\n    {\r\n        $type = $type ? 1 : 0;\r\n        static $ip = NULL;\r\n        if ($ip !== NULL)\r\n            return $ip[$type];\r\n        if ($_SERVER[\'HTTP_X_REAL_IP\']) { //nginx 代理模式下，获取客户端真实IP\r\n            $ip = $_SERVER[\'HTTP_X_REAL_IP\'];\r\n        } elseif (isset($_SERVER[\'HTTP_CLIENT_IP\'])) { //客户端的ip\r\n            $ip = $_SERVER[\'HTTP_CLIENT_IP\'];\r\n        } elseif (isset($_SERVER[\'HTTP_X_FORWARDED_FOR\'])) { //浏览当前页面的用户计算机的网关\r\n            $arr = explode(\',\', $_SERVER[\'HTTP_X_FORWARDED_FOR\']);\r\n            $pos = array_search(\'unknown\', $arr);\r\n            if (false !== $pos)\r\n                unset($arr[$pos]);\r\n            $ip = trim($arr[0]);\r\n        } elseif (isset($_SERVER[\'REMOTE_ADDR\'])) {\r\n            $ip = $_SERVER[\'REMOTE_ADDR\']; //浏览当前页面的用户计算机的ip地址\r\n        } else {\r\n            $ip = $_SERVER[\'REMOTE_ADDR\'];\r\n        }\r\n        // IP地址合法验证\r\n        $long = sprintf(\"%u\", ip2long($ip));\r\n        $ip   = $long ? array(\r\n            $ip,\r\n            $long\r\n        ) : array(\r\n            \'0.0.0.0\',\r\n            0\r\n        );\r\n        return $ip[$type];\r\n    }\r\n    \r\n?>\r\n```\r\n直接上代码。', 'Lang Hu', 2, '2', 0, 7, 0, 0, 1551942142, 1556627980, '/uploads/Images/thumbnail/2019-03-07/5c80c1feb541e.jpg', 0);
  INSERT INTO `article` VALUES (12, 'JavaScript 获取并且判断浏览器内核访问类型(QQ/微信)', '　对于开发者而言，微信或者QQ自带的浏览器内核或许不能够为用户带来良好的体验，所有有的时候我们需要引导用户进入自带浏览器体验，所以这个功能主要是解决这个问题。', '1、作用？\r\n\r\n　　对于开发者而言，微信或者QQ自带的浏览器内核或许不能够为用户带来良好的体验，所有有的时候我们需要引导用户进入自带浏览器体验，所以这个功能主要是解决这个问题。\r\n\r\n2、实现方法？\r\n\r\n　　使用Javascript获取用户访问的UA标识，根据标识判断是否在QQ或者微信的浏览器内核中。\r\n\r\n3、实现代码\r\n\r\n　　QQ判断：\r\n```\r\nfunction is_qq(){\r\n    var ua = navigator.userAgent.toLowerCase();\r\n    if(ua.match(/\\sQQ/i)==\" qq\") {\r\n        return true;\r\n    } else {\r\n        return false;\r\n    }\r\n}    \r\n```\r\n　　微信判断：\r\n```\r\nfunction is_weixin(){\r\n    var ua = navigator.userAgent.toLowerCase();\r\n    if(ua.match(/MicroMessenger/i)==\"micromessenger\") {\r\n        return true;\r\n    } else {\r\n        return false;\r\n    }\r\n}\r\n```\r\n\r\n　　在自己的html页面中加入以上代码，在使用时直接调用函数即可。成功返回ture，失败返回false。', 'Lang Hu', 1, '1,3', 0, 34, 0, 0, 1551942299, 1556659721, '/uploads/Images/thumbnail/2019-03-07/5c80c29b3646e.jpg', 0);
  INSERT INTO `article` VALUES (13, '易语言实现ZeroTier One设备列表获取', 'zerotier one  官方的程序中无法直接查看当前网络下的设备列表。特写了这个小程序来获取。', '## 程序截图\r\n![](/uploads/Images/article/2019-03-10/5c84caf714498.jpg)\r\n\r\n### 第一次使用之后，会默认写配置文件，第二次会自动填写相关信息。\r\n\r\n## 代码\r\n```\r\n.版本 2\r\n.支持库 eGrid\r\n\r\n.程序集 窗口程序集_启动窗口\r\n\r\n.子程序 __启动窗口_创建完毕\r\n\r\n\r\n网络ID.内容 ＝ 读配置项 (“ZeroTier.ini”, “AUTH”, “ID”, “”)\r\n验证Token.内容 ＝ 读配置项 (“ZeroTier.ini”, “AUTH”, “TOKEN”, “”)\r\n\r\n设备列表_初始化 ()\r\n\r\n\r\n.子程序 获取JSON数据, 文本型\r\n.参数 id, 文本型\r\n.参数 token, 文本型\r\n.局部变量 Url, 文本型\r\n.局部变量 Result, 文本型\r\n.局部变量 验证信息, 文本型\r\n\r\n\r\nUrl ＝ “https://my.zerotier.com/api/network/” ＋ id ＋ “/member”\r\n验证信息 ＝ “Authorization: bearer ” ＋ token\r\nResult ＝ 到文本 (网页_访问S (Url, 0, , , , 验证信息, , , , , , , , , , , , , ))\r\n返回 (Result)\r\n\r\n\r\n\r\n\r\n.子程序 设备列表_初始化\r\n\r\n设备列表.清空数据 ()\r\n设备列表.行数 ＝ 1\r\n设备列表.置数据 (0, 0, #表格常量.文本型, “名称”)\r\n设备列表.置数据 (0, 1, #表格常量.文本型, “内网IP”)\r\n设备列表.置数据 (0, 2, #表格常量.文本型, “物理IP”)\r\n\r\n\r\n.子程序 _按钮_获取_被单击\r\n.局部变量 id, 文本型\r\n.局部变量 token, 文本型\r\n.局部变量 data, 类_json\r\n.局部变量 index, 整数型\r\n\r\n设备列表_初始化 ()\r\n按钮_获取.禁止 ＝ 真\r\nid ＝ 网络ID.内容\r\ntoken ＝ 验证Token.内容\r\ndata.解析 (获取JSON数据 (id, token))\r\n.计次循环首 (data.成员数 (), index)\r\n    设备列表.插入行 (, index)\r\n    设备列表.置数据 (index, 0, #表格常量.文本型, 文本_替换 (data.取成员 (index － 1).取属性对象 (“name”), , , , #引号, “”))\r\n    设备列表.置数据 (index, 1, #表格常量.文本型, data.取成员 (index － 1).取属性 (“config”).取属性 (“ipAssignments”).取成员文本 (0))\r\n    设备列表.置数据 (index, 2, #表格常量.文本型, 文本_替换 (data.取成员 (index － 1).取属性对象 (“physicalAddress”), , , , #引号, “”))\r\n.计次循环尾 ()\r\n按钮_获取.禁止 ＝ 假\r\n写配置项 (“ZeroTier.ini”, “AUTH”, “ID”, 到文本 (id))\r\n写配置项 (“ZeroTier.ini”, “AUTH”, “TOKEN”, 到文本 (token))\r\n```\r\n\r\n## GitHup\r\n[https://github.com/HULANG-BTB/ZeroTier-One-List](https://github.com/HULANG-BTB/ZeroTier-One-List \"https://github.com/HULANG-BTB/ZeroTier-One-List\")', 'Lang Hu', 1, '16', 0, 82, 0, 0, 1552125355, 1556689211, '/uploads/Images/thumbnail/2019-03-10/5c84cb006c8e0.jpg', 0);
  INSERT INTO `article` VALUES (14, 'ZeroTier One 无公网IP 跨平台实现内网穿透 ', 'ZeroTier One是一款支持多平台的内网穿透工具，工作原理是基于虚拟网卡，将各个地区PC组建在一个局域网内。不需要复杂的配置过程，简单易用。目前还是一款开源的软件。在该公司的GitHUP账户中有开源项', '### ZeroTier One是一款支持多平台的内网穿透工具，工作原理是基于虚拟网卡，将各个地区PC组建在一个局域网内。不需要复杂的配置过程，简单易用。目前还是一款开源的软件。在该公司的GitHUP账户中有开源项目。\r\n\r\n#### GITHUP地址：[https://github.com/zerotier/ZeroTierOne.git](https://github.com/zerotier/ZeroTierOne.git \"https://github.com/zerotier/ZeroTierOne.git\")\r\n\r\n## 目前支持的平台\r\nZeroTier 支持 Windows、macOS、Linux 三大主流平台，iOS、Android 两大移动平台，以及 QNAP（威连通）、Synology（群晖）、Western Digital MyCloud NAS（西部数据）三个 NAS 平台，还支持 LEDE 开源路由器项目。\r\n\r\n## 如何使用\r\n	登陆官网创建账户\r\n	在Network面板中创建自己的网络\r\n	下载安装对应操作系统的程序\r\n	加入到刚才创建的网络中\r\n\r\n### 简单的使用方法，无需更多的配置，下面正式开始讲解如何取使用\r\n\r\n# 0x01 账户创建\r\n#### 1、登陆官网[https://zerotier.com/](https://zerotier.com/ \"https://zerotier.com/\")\r\n#### 2、点击右上角的login按钮\r\n![](/uploads/Images/article/2019-03-11/5c86461849dec.jpg)\r\n#### 3、再次点击右上角或者下方的 Create An Account 创建账户\r\n![](/uploads/Images/article/2019-03-11/5c86466a43cfa.jpg)\r\n\r\n# 0x02 新建网络\r\n#### 1、登陆你刚才创建的账户\r\n#### 2、在顶部菜单栏中点击NetWork，网络管理面板。\r\n#### 3、点击Create Network按钮创建一个网络\r\n![](/uploads/Images/article/2019-03-11/5c8647574623c.png)\r\n#### 注意这里你不需要更多的操作了\r\n#### 4、 点击进入你刚才的网络，记录下网络ID\r\n![](/uploads/Images/article/2019-03-11/5c8647a5665fb.jpg)\r\n#### 保存一下这个id\r\n### 到此网络创建完成\r\n\r\n# 0x03 下载安装客户端\r\n#### 1、点击顶部的Download进入下载界面。\r\n#### 2、选择对应自己系统的安装包下载和安装。（这里以centos 7.x为例）\r\n#### 我修改了部分官方的命令\r\n```\r\nwget https://install.zerotier.com/\r\nmv index.html install.sh\r\nchmod u+x install.sh\r\n./install.sh\r\n```\r\n##### 可以直接复制以上命令\r\n![](/uploads/Images/article/2019-03-11/5c8648f521193.jpg)\r\n##### 安装完成，至此，安装过程全部完成，执行命令获取帮助。\r\n```\r\nzerotier-cli -h\r\n```\r\n![](/uploads/Images/article/2019-03-11/5c86495a6ff1f.jpg)\r\n\r\n# 0x04 加入网络\r\n#### 1、复制刚才第二步中创建的网络的ID\r\n#### 2、执行命令\r\n```\r\nzerotier-cli join [ID]\r\n```\r\n#### 注意替换，ID要去掉括号\r\n![](/uploads/Images/article/2019-03-11/5c864a65ed3b2.jpg)\r\n##### 至此，网络加入完成。通过登陆面板可以查看当前网络下所有的设备列表。\r\n\r\n![](/uploads/Images/article/2019-03-11/5c864b113cf2a.jpg)\r\n\r\n## 另外，如果你是windows系统的话，给你提供一个快速获取设备列表的方法。\r\n\r\n### 传送门：[易语言实现ZeroTier One设备列表获取](/article/15.html \"易语言实现ZeroTier One设备列表获取\")\r\n', 'Lang Hu', 2, '5', 0, 20, 0, 0, 1552305038, 1556687392, '/uploads/Images/thumbnail/2019-03-11/5c864b8e9021a.jpg', 0);
  INSERT INTO `article` VALUES (15, 'HTML5 WEB 存储和应用', '使用HTML5可以在本地存储用户的浏览数据。早些时候,本地存储使用的是 cookie。但是Web 存储需要更加的安全与快速. 这些数据不会被保存在服务器上，但是这些数据只用于用户请求网站数据上.它也可以存储大量的数据，而不影响网站的性能. 数据以 键/值 对存在, web网页的数据只允许该网页访问使用。', '## 什么是HTML5 Web 存储？\r\n* HTML5 web 存储,一个比cookie更好的本地存储方式。\r\n\r\n## 什么是 HTML5 Web 存储?\r\n* 使用HTML5可以在本地存储用户的浏览数据。\r\n* 早些时候,本地存储使用的是 cookie。但是Web 存储需要更加的安全与快速. 这些数据不会被保存在服务器上，但是这些数据只用于用户请求网站数据上.它也可以存储大量的数据，而不影响网站的性能.\r\n* 数据以 键/值 对存在, web网页的数据只允许该网页访问使用。\r\n\r\n## localStorage 和 sessionStorage \r\n\r\n1、客户端存储数据的两个对象为：\r\n\r\n* localStorage - 用于长久保存整个网站的数据，保存的数据没有过期时间，直到手动去除。\r\n* sessionStorage - 用于临时保存同一窗口(或标签页)的数据，在关闭窗口或标签页之后将会删除这些数据。\r\n\r\n\r\n2、在使用 web 存储前,应检查浏览器是否支持 localStorage 和sessionStorage:\r\n```\r\nif(typeof(Storage)!==\"undefined\")\r\n{\r\n    // 是的! 支持 localStorage  sessionStorage 对象!\r\n    // 一些代码.....\r\n} else {\r\n    // 抱歉! 不支持 web 存储。\r\n}\r\n```\r\n## localStorage的优势与局限\r\n###localStorage的优势\r\n\r\n1、localStorage拓展了cookie的4K限制\r\n\r\n2、localStorage会可以将第一次请求的数据直接存储到本地，这个相当于一个5M大小的针对于前端页面的数据库，相比于cookie可以节约带宽，但是这个却是只有在高版本的浏览器中才支持的\r\n\r\n###localStorage的局限\r\n\r\n1、浏览器的大小不统一，并且在IE8以上的IE版本才支持localStorage这个属性\r\n\r\n2、目前所有的浏览器中都会把localStorage的值类型限定为string类型，这个在对我们日常比较常见的JSON对象类型需要一些转换\r\n\r\n3、localStorage在浏览器的隐私模式下面是不可读取的\r\n\r\n4、localStorage本质上是对字符串的读取，如果存储内容多的话会消耗内存空间，会导致页面变卡\r\n\r\n5、localStorage不能被爬虫抓取到\r\n\r\nlocalStorage与sessionStorage的唯一一点区别就是localStorage属于永久性存储，而sessionStorage属于当会话结束的时候，sessionStorage中的键值对会被清空\r\n\r\n这里我们以localStorage来分析\r\n\r\n## 数据存入\r\n```\r\nvar key = \"key\";\r\nvar cntent = \"content\";\r\nvar localStorage = window.localStorage;\r\nlocalStorage.setItem(key, content);\r\n```\r\n\r\n## 数据读取\r\n```\r\nvar key = \"key\";\r\nvar localStorage = window.localStorage;\r\nvar content = localStorage.getItem(key);\r\n```\r\n\r\n## 结语\r\n* 一般我们会将JSON存入localStorage中，但是在localStorage会自动将localStorage转换成为字符串形式\r\n\r\n* 这个时候我们可以使用JSON.stringify()这个方法，来将JSON转换成为JSON字符串', 'Lang Hu', 1, '3,4', 0, 15, 0, 0, 1552312477, 1556627659, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (16, '浏览器热键注册 实现局部刷新 保存等信息', '快捷键，又叫快速键或热键，指通过某些特定的按键、按键顺序或按键组合来完成一个操作，很多快捷键往往与如 Ctrl 键、Shift 键、Alt 键、Fn 键以及 Windows 平台下的 Windows 键和 Mac 机上的 Meta 键等配合使用。利用快捷键可以代替鼠标做一些工作，可以利用键盘快捷键打开、关闭和导航“开始”菜单、桌面、菜单、对话框以及网页，Word里面也可以用到快捷键', '## 什么是热键？\r\n+ 快捷键，又叫快速键或热键，指通过某些特定的按键、按键顺序或按键组合来完成一个操作，很多快捷键往往与如 Ctrl 键、Shift 键、Alt 键、Fn 键以及 Windows 平台下的 Windows 键和 Mac 机上的 Meta 键等配合使用。利用快捷键可以代替鼠标做一些工作，可以利用键盘快捷键打开、关闭和导航“开始”菜单、桌面、菜单、对话框以及网页，Word里面也可以用到快捷键。\r\n\r\n## 为什么要注册浏览器热键？\r\n+ 在WEB开发的过程中，我们往往需要用到某些特定的按键，比如F5刷新页面，Ctrl+s暂时保存当前页面内容，或者设置一些其他的快捷键来方便用户的操作。\r\n\r\n## 注册方法\r\n```\r\n$(document).keydown(function(event){\r\n	var code = event.keyCode; // 按键值 ASCII\r\n	var ctrl = event.ctrlKey; // Ctrl是否按下 true -- false\r\n	if( code == /*定义你的按键*/1 )\r\n	{\r\n		// Todo:在这里写你的代码\r\n		/* code */\r\n		// 以下内容屏蔽原来按键功能\r\n		event.returnvalue = false;\r\n		event.preventDefault();\r\n		return false;\r\n	}\r\n});\r\n```\r\n\r\n## 结语\r\n##### 准确使用热键注册功能，能够使得web方面的工作更加简便、快捷。', 'Lang Hu', 1, '3,4', 0, 24, 0, 0, 1552313062, 1556691655, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (17, 'Editor.MD插件开发之自动保存到本地。', 'Editor.MD在使用的过程中我们获取会因为某些不恰当的操作，导致页面刷新或更改，致使我们已经编写的内容无法找回，本插件为了解决这个问题，使用本地保存的方式快捷保存。', '## 官方内容\r\n\r\n[TOC]\r\n\r\n### Define plugin\r\n\r\n#### Plugin directory\r\n\r\n    editor.md/\r\n        plugins/\r\n            plugin-name/\r\n                ....\r\n\r\n#### Example\r\n\r\n```javascript\r\n(function() {\r\n\r\n    var factory = function (exports) {\r\n\r\n		var $ = jQuery;           // if using module loader(Require.js/Sea.js).\r\n\r\n		exports.customMethod = function() {\r\n		    //....\r\n		};\r\n\r\n		exports.fn.youPluginName = function() {\r\n		    /*\r\n			var _this       = this; // this == the current instance object of Editor.md\r\n			var lang        = this.lang;\r\n			var settings    = this.settings;\r\n			var editor      = this.editor;\r\n			var cursor      = cm.getCursor();\r\n			var selection   = cm.getSelection();\r\n\r\n			cm.focus();\r\n            */\r\n\r\n			//....\r\n		};\r\n\r\n	};\r\n\r\n	// CommonJS/Node.js\r\n	if (typeof require === \"function\" && typeof exports === \"object\" && typeof module === \"object\")\r\n    {\r\n        module.exports = factory;\r\n    }\r\n	else if (typeof define === \"function\")  // AMD/CMD/Sea.js\r\n    {\r\n		if (define.amd) { // for Require.js\r\n\r\n			define([\"editormd\"], function(editormd) {\r\n                factory(editormd);\r\n            });\r\n\r\n		} else { // for Sea.js\r\n			define(function(require) {\r\n                var editormd = require(\"./../../editormd\");\r\n                factory(editormd);\r\n            });\r\n		}\r\n	} \r\n	else\r\n	{\r\n        factory(window.editormd);\r\n	}\r\n\r\n})();\r\n```\r\n\r\n#### Usage plugin\r\n\r\n```html\r\n<script src=\"../plugins/you-plugin-name/you-plugin-name.js\"></script>\r\n<script>\r\n    editormd.customMethod();\r\n\r\n    var testEditor = editormd(\"test-editormd\", {\r\n        path   : \'../lib/\',\r\n        onload : function() {\r\n            this.youPluginName();\r\n            this.pluginA();\r\n            this.executePlugin(\"somePluginName\", \"you-plugin-name/you-plugin-name\"); // load and execute plugin\r\n        }\r\n    });\r\n\r\n    // or\r\n    $(\"#btn\").click(function(){\r\n        testEditor.youPluginName();\r\n    });\r\n</script>\r\n```\r\n\r\n## 以上是官方给出的插件开发的内容。\r\n#### 我们只需要针对我们需要的内容进行修改。\r\n##### 0x01 修改我们插件初始化方法名称\r\n* 修改第七行customMethod为我们自己的方法。我这里修改为ContentAutoSave。\r\n* 此时函数原型为：\r\n```\r\n    var factory = function (exports) {\r\n\r\n        var $ = jQuery;           // if using module loader(Require.js/Sea.js).\r\n        var pluginName   = \"content-auto-save\";\r\n\r\n        exports.fn.ContentAutoSave = function() {\r\n\r\n            }\r\n\r\n    };\r\n```\r\n* 然后五门根据原来的插件模板，保留我们需要的变量，这里我们用到了调用这个插件的editor的对象，以及他的id，所以保留\r\n```\r\nvar _this       = this;\r\nvar id          = _this.id;\r\n```\r\n这两行，此时函数原型为：\r\n```\r\nexports.fn.ContentAutoSave = function() {\r\n// 初始化变量\r\n	var _this       = this;\r\n	var id          = _this.id;\r\n}\r\n```\r\n* 接下里就是定义我们的插件对象了。这里不仔细写了，按照常规的开发，直接给代码：\r\n```\r\nvar ContentAutoSave = {\r\n    options : {\r\n        saveInterval: null,// 存储计时器 句柄\r\n        saveTime: 10000, // 存储间隔时间 ms\r\n        storage: null,\r\n        saveKey: ( location.protocol + location.host + location.pathname + location.search ).replace( /[.:?=\\/-]/g, \'_\' ) + \"_\" + _this.id,\r\n    },\r\n    init: function () {\r\n        // 存储计时器 句柄\r\n        this.options.saveInterval  = null;\r\n        // 存储间隔时间 ms\r\n        this.options.saveTime = 10000;\r\n        var that = this;\r\n        if( typeof(Storage)==\"undefined\" ){\r\n            console.log(\'浏览器不支持 LocalStorage 存储。\');\r\n            return ;\r\n        } else {\r\n            this.options.storage = window.localStorage;\r\n            this.read();\r\n        }\r\n        this.options.saveInterval = (function () {\r\n            this.save();\r\n        }, this.options.saveTime);\r\n        $(document).keydown(function(event){\r\n            if (  (event.ctrlKey || event.metaKey) && event.keyCode == 83 ) {\r\n                that.save();\r\n                event.returnvalue = false;\r\n                event.preventDefault();\r\n                return false;\r\n            }\r\n        });\r\n    },\r\n    read: function () {\r\n        if (this.options.storage.getItem(this.options.saveKey) != null) {\r\n            _this.setValue(this.options.storage.getItem(this.options.saveKey));\r\n            console.log(\'缓存读取成功！\');\r\n        } else {\r\n            console.log(\"本地无缓存数据\");\r\n        }\r\n    },\r\n    save: function () {\r\n        this.options.storage.setItem( this.options.saveKey, _this.getValue());\r\n        var timetamp = Number(new Date()) ;\r\n        console.log(timetamp + \'：缓存保存成功！\');\r\n    }\r\n                };\r\n```\r\n\r\n* 最后在初始化函数中调用对象的init方法：\r\n```\r\nContentAutoSave.init();\r\n```\r\n\r\n#### 完整插件代码：\r\n```\r\n/*!\r\n * Link dialog plugin for Editor.md\r\n *\r\n * @file        content-auto-save.js\r\n * @author      Lang Hu\r\n * @version     1.1.0\r\n * @updateTime  2019-03-11\r\n * @link        http://r-5.net\r\n * @license     MIT\r\n */\r\n\r\n(function() {\r\n\r\n    var factory = function (exports) {\r\n\r\n        var $ = jQuery;           // if using module loader(Require.js/Sea.js).\r\n        var pluginName   = \"content-auto-save\";\r\n\r\n        exports.fn.ContentAutoSave = function() {\r\n                // 初始化变量\r\n                var _this       = this; // this == the current instance object of Editor.md\r\n\r\n                var id          = _this.id;\r\n\r\n                var ContentAutoSave = {\r\n                    options : {\r\n                        saveInterval: null,// 存储计时器 句柄\r\n                        saveTime: 10000, // 存储间隔时间 ms\r\n                        storage: null,\r\n                        saveKey: ( location.protocol + location.host + location.pathname + location.search ).replace( /[.:?=\\/-]/g, \'_\' ) + \"_\" + _this.id,\r\n                    },\r\n                    init: function () {\r\n                        // 存储计时器 句柄\r\n                        this.options.saveInterval  = null;\r\n                        // 存储间隔时间 ms\r\n                        this.options.saveTime = 10000;\r\n                        var that = this;\r\n                        if( typeof(Storage)==\"undefined\" ){\r\n                            console.log(\'浏览器不支持 LocalStorage 存储。\');\r\n                            return ;\r\n                        } else {\r\n                            this.options.storage = window.localStorage;\r\n                            this.read();\r\n                        }\r\n                        this.options.saveInterval = (function () {\r\n                            this.save();\r\n                        }, this.options.saveTime);\r\n                        $(document).keydown(function(event){\r\n                            if (  (event.ctrlKey || event.metaKey) && event.keyCode == 83 ) {\r\n                                that.save();\r\n                                event.returnvalue = false;\r\n                                event.preventDefault();\r\n                                return false;\r\n                            }\r\n                        });\r\n                    },\r\n                    read: function () {\r\n                        if (this.options.storage.getItem(this.options.saveKey) != null) {\r\n                            _this.setValue(this.options.storage.getItem(this.options.saveKey));\r\n                            console.log(\'缓存读取成功！\');\r\n                        } else {\r\n                            console.log(\"本地无缓存数据\");\r\n                        }\r\n                    },\r\n                    save: function () {\r\n                        this.options.storage.setItem( this.options.saveKey, _this.getValue());\r\n                        var timetamp = Number(new Date()) ;\r\n                        console.log(timetamp + \'：缓存保存成功！\');\r\n                    }\r\n                };\r\n\r\n                ContentAutoSave.init();\r\n\r\n            }\r\n\r\n    };\r\n\r\n    // CommonJS/Node.js\r\n    if (typeof require === \"function\" && typeof exports === \"object\" && typeof module === \"object\")\r\n    {\r\n        module.exports = factory;\r\n    }\r\n    else if (typeof define === \"function\")  // AMD/CMD/Sea.js\r\n    {\r\n        if (define.amd) { // for Require.js\r\n\r\n            define([\"editormd\"], function(editormd) {\r\n                factory(editormd);\r\n            });\r\n\r\n        } else { // for Sea.js\r\n            define(function(require) {\r\n                var editormd = require(\"./../../editormd\");\r\n                factory(editormd);\r\n            });\r\n        }\r\n    }\r\n    else\r\n    {\r\n        factory(window.editormd);\r\n    }\r\n\r\n})();\r\n```\r\n#### 值得注意的是，在这里我们用到了一个注册热键的方法：\r\n```\r\n$(document).keydown(function(event){\r\n    if (  (event.ctrlKey || event.metaKey) && event.keyCode == 83 ) {\r\n        that.save();\r\n        event.returnvalue = false;\r\n        event.preventDefault();\r\n        return false;\r\n    }\r\n});\r\n```\r\n通过这个方法，我们事先了Ctrl+S快速保存。\r\n##### 热键注册相关： [浏览器热键注册 实现局部刷新 保存等信息](/article/18.html \"浏览器热键注册 实现局部刷新 保存等信息\")\r\n\r\n#### 结果\r\n【GitHub】：[https://github.com/HULANG-BTB/Editor.md-content-auto-save.git](https://github.com/HULANG-BTB/Editor.md-content-auto-save.git \"https://github.com/HULANG-BTB/Editor.md-content-auto-save.git\")', 'Lang Hu', 1, '1,3,4', 0, 14, 0, 0, 1552362070, 1556627649, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (18, '四川、贵州等地区袱子填写参照表', '烧袱子，其实是汉族信仰习俗主要流行于四川各地，由烧纸钱演化而来。民间多在每年农历七月十五日祭祖或平常祭奠亡灵时烧袱子。意在寄钱给祖先亡灵，好让他们在阴间有钱享用，更好地庇佑子孙。', '# 仅供参考\r\n\r\n### 填写格式\r\n\r\n![](/uploads/Images/article/2019-03-12/5c875b5434aee.jpg)\r\n![](/uploads/Images/article/2019-03-12/5c875b5b64a72.jpg)\r\n![](/uploads/Images/article/2019-03-12/5c875b60ea087.jpg)\r\n![](/uploads/Images/article/2019-03-12/5c875b655ccfb.jpg)\r\n![](/uploads/Images/article/2019-03-12/5c875b69e1080.jpg)\r\n![](/uploads/Images/article/2019-03-12/5c875b6e98549.jpg)\r\n![](/uploads/Images/article/2019-03-12/5c875b730047f.jpg)\r\n![](/uploads/Images/article/2019-03-12/5c875b78db5c9.jpg)\r\n![](/uploads/Images/article/2019-03-12/5c875b7ec45b3.jpg)\r\n\r\n### 基本的都有了', 'Lang Hu', 1, '1', 0, 29, 0, 0, 1552375009, 1556685580, '/uploads/Images/thumbnail/2019-03-12/5c875ce1d05dd.jpg', 0);
  INSERT INTO `article` VALUES (19, '落谷 P1047 校门外的树 ', '某校大门外长度为L的马路上有一排树，每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴，马路的一端在数轴0的位置，另一端在L的位置；数轴上的每个整数点，即0,1,2,…,L，都种有一棵树。', '### 题目描述\r\n##### 某校大门外长度为L的马路上有一排树，每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴，马路的一端在数轴0的位置，另一端在L的位置；数轴上的每个整数点，即0,1,2,…,L，都种有一棵树。\r\n##### 由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数，区域之间可能有重合的部分。现在要把这些区域中的树（包括区域端点处的两棵树）移走。你的任务是计算将这些树都移走后，马路上还有多少棵树。\r\n### 输入输出格式\r\n#### 输入格式：\r\n##### 第一行有2个整数L(1 ≤ L ≤ 10000)和M(1≤M≤100)，L代表马路的长度，M代表区域的数目，LLL和MMM之间用一个空格隔开。\r\n##### 接下来的M行每行包含2个不同的整数，用一个空格隔开，表示一个区域的起始点和终止点的坐标。\r\n#### 输出格式：\r\n##### 1个整数，表示马路上剩余的树的数目。\r\n\r\n### 输入输出样例\r\n#### 输入样例 #1\r\n```\r\n500 3\r\n150 300\r\n100 200\r\n470 471\r\n```\r\n#### 输出样例 #1\r\n```\r\n298\r\n```\r\n### 说明\r\n##### NOIP2005普及组第二题\r\n##### 对于$20%$的数据，区域之间没有重合的部分；\r\n##### 对于其它的数据，区域之间有重合的情况。\r\n### 解析\r\n##### 看到这个题目的时候首先想到的是这一段树可以想象成一段数组，数组中存0或1，分别标识有树或者没有树，初始化所有位置都默认为有树，在每次输入L和R的时候都用循环去更新值，之后观察了一下数据量，L*M的范围大概是10^6,一秒钟内完全可以完成操作，所以这个方案可行。\r\n##### 之后看了一下测试数据，发现输入的时候更新数组需要包含左右端点，于是开始解题：\r\n```\r\n#include <iostream>\r\n\r\nusing namespace std;\r\n\r\nint arr[10000 + 5];\r\nint l, m;\r\nint ans = 0;\r\n\r\nint main()\r\n{\r\n	cin >> l >> m;\r\n	for (int i = 1; i <= m; i++) {\r\n		int left, right;\r\n		cin >> left >> right;\r\n		for (int j = left; j <= right; j++)\r\n			arr[j] = 1;\r\n	}\r\n	for (int i = 0; i <= l; i++)\r\n		if (!arr[i]) ans++;\r\n	cout << ans;\r\n	return 0;\r\n}\r\n```\r\n### 测试 AC ', 'Lang Hu', 1, '18', 0, 11, 0, 0, 1553008400, 1556627656, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (20, '落谷 P1427 小鱼的数字游戏', '小鱼最近被要求参加一个数字游戏，要求它把看到的一串数字（长度不一定，以0结束，最多不超过100个，数字不超过2^32-1），记住了然后反着念出来(表示结束的数字0就不要念出来了)。这对小鱼的那点记忆力来说实', '题目描述\r\n----\r\n\r\n小鱼最近被要求参加一个数字游戏，要求它把看到的一串数字（长度不一定，以0结束，最多不超过100个，数字不超过2^32-1），记住了然后反着念出来(表示结束的数字0就不要念出来了)。这对小鱼的那点记忆力来说实在是太难了，你也不想想小鱼的整个脑袋才多大，其中一部分还是好吃的肉！所以请你帮小鱼编程解决这个问题。\r\n\r\n输入输出格式\r\n------\r\n\r\n**输入格式：**\r\n\r\n一行内输入一串整数，以0结束，以空格间隔。\r\n\r\n**输出格式：**\r\n\r\n一行内倒着输出这一串整数，以空格间隔。\r\n\r\n输入输出样例\r\n------\r\n\r\n**输入样例#1：**\r\n\r\n3 65 23 5 34 1 30 0\r\n\r\n**输出样例#1：**\r\n\r\n30 1 34 5 23 65 3\r\n\r\n----\r\n### 解题思路\r\n\r\n从题目的意思，可以知道我们只需要把输入的数字按照输入的顺序反向输出就可以，再看一下数据范围，数字不超过100个，而且范围是int类型可以存下来的。所以可以用数组直接循环跑。\r\n我这里是直接使用的c++ STL 中string和vector。\r\n### 代码如下\r\n```\r\n/***\r\n*   main.cpp\r\n*   Created by HULANG-BTB on 2019/3/20 11:54:19.\r\n*\r\n***/\r\n#include <iostream>\r\n#include <algorithm>\r\n#include <string>\r\n#include <vector>\r\n\r\nusing namespace std;\r\n\r\nvector<string> s;\r\n\r\nint main() {\r\n    string str;\r\n    while (1) {\r\n        cin >> str;\r\n        if (str == \"0\") {\r\n            break;\r\n        }\r\n        else\r\n        {\r\n            s.push_back(str);\r\n        }\r\n    }\r\n    while (s.size()) {\r\n        cout << s.back() << \" \";\r\n        s.pop_back();\r\n    }\r\n    return 0;\r\n}\r\n```', 'Lang Hu', 1, '18', 0, 11, 0, 0, 1553054708, 1556627651, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (21, 'windows通过符号链接释放C盘空间', 'NTFS 符号链接又称“符号链接”，是 NTFS 文件系统中指向文件系统中的另一个对象的一类对象，被指向的对象叫做“目标”。mklink 是 Windows 下用于创建符号链接的工具，存在于 Windows Vista 及以后版本的 Windows 操作系统中。', '### NTFS 符号链接\r\n* NTFS 符号链接又称“符号链接”，是 NTFS 文件系统中指向文件系统中的另一个对象的一类对象，被指向的对象叫做“目标”。\r\n* mklink 是 Windows 下用于创建符号链接的工具，存在于 Windows Vista 及以后版本的 Windows 操作系统中。\r\n* 使用方式：\r\nMKLINK [[/D] | [/H] | [/J]] 链接名称 目标\r\n##### 说明：\r\n/D 创建目录符号链接而不是文件符号链接（默认为文件符号链接）\r\n/H 创建硬链接而不是符号链接\r\n/J 创建目录连接点\r\n链接名称 指定新的符号链接名称\r\n目标 指定新链接引用的路径（绝对路径或者相对路径均可）\r\n\r\n### chrome浏览器为例\r\n1、找到浏览器安装目录\r\n![](/uploads/Images/article/2019-03-21/5c9311c7c3320.jpg)\r\n2、回到上级目录，将整个Google文件剪切到其他盘（我到D盘）\r\n![](/uploads/Images/article/2019-03-21/5c931206247cf.jpg)\r\n3、通过管理员方式打开cmd并且cd到C盘原来的安装位置。\r\n![](/uploads/Images/article/2019-03-21/5c93129303320.jpg)\r\n![](/uploads/Images/article/2019-03-21/5c9312ac193ff.jpg)\r\n4、执行命令，创建符号链接\r\n```\r\nmklink /D \"C:\\Program Files (x86)\\Google\" \"D:\\Program Files\\Google\"\r\n```\r\n![](/uploads/Images/article/2019-03-21/5c9312fc7a365.jpg)\r\n5、完成\r\n![](/uploads/Images/article/2019-03-21/5c931338f1a9c.jpg)\r\n##### 此时点击文件文件符号会自动链接到新文件夹地址，此方法和linux系统中的ln命令类似。', 'Lang Hu', 1, '19', 0, 9, 0, 0, 1553142679, 1556627663, '/uploads/Images/thumbnail/2019-03-21/5c93139747a6c.jpg', 0);
  INSERT INTO `article` VALUES (22, '落谷 P1428 小鱼比可爱', '人比人，气死人；鱼比鱼，难死鱼。小鱼最近参加了一个“比可爱”比赛，比的是每只鱼的可爱程度。参赛的鱼被从左到右排成一排，头都朝向左边，然后每只鱼会得到一个整数数值，表示这只鱼的可爱程度，很显然整数越大，表示这只鱼越可爱，而且任意两只鱼的可爱程度**可能一样**。由于所有的鱼头都朝向左边，所以每只鱼只能看见在它左边的鱼的可爱程度，它们心里都在计算，', '## 题目描述\r\n\r\n人比人，气死人；鱼比鱼，难死鱼。小鱼最近参加了一个“比可爱”比赛，比的是每只鱼的可爱程度。参赛的鱼被从左到右排成一排，头都朝向左边，然后每只鱼会得到一个整数数值，表示这只鱼的可爱程度，很显然整数越大，表示这只鱼越可爱，而且任意两只鱼的可爱程度**可能一样**。由于所有的鱼头都朝向左边，所以每只鱼只能看见在它左边的鱼的可爱程度，它们心里都在计算，在自己的眼力范围内有多少只鱼不如自己可爱呢。请你帮这些可爱但是鱼脑不够用的小鱼们计算一下。\r\n\r\n## 输入输出格式\r\n\r\n**输入格式：**\r\n\r\n第一行输入一个整数n，表示鱼的数目。\r\n\r\n第二行内输入n个整数，用空格间隔，依次表示从左到右每只小鱼的可爱程度。\r\n\r\n**输出格式：**\r\n\r\n行内输出n个整数，用空格间隔，依次表示每只小鱼眼中有多少只鱼不如自己可爱。\r\n\r\n## 输入输出样例\r\n\r\n**输入样例#1：**\r\n\r\n```\r\n6\r\n4 3 0 5 1 2\r\n```\r\n\r\n**输出样例#1：**\r\n\r\n```\r\n0 0 0 3 1 2\r\n```\r\n\r\n## 说明\r\n\r\nn<=100\r\n\r\n## 题解\r\n\r\n不难想到，对于每一条鱼可以想象成一个数组元素，保存鱼的可爱度，之后对于 每一条鱼而言，我们只需要让他遍历一下左边的所有元素，如果左边鱼的可爱度小于当前鱼的可爱度，那么ans++；遍历完成后输出结果。\r\n\r\n## 答案\r\n\r\n```\r\n/***\r\n*   main.cpp\r\n*   Created by HULANG-BTB on 2019/3/21 13:17:45.\r\n*\r\n***/\r\n#include <iostream>\r\n#include <algorithm>\r\n#include <vector>\r\n\r\nusing namespace std;\r\nint n;\r\nvector<int> v;\r\n\r\nint main() {\r\n    cin >> n;\r\n    for (int i = 0; i < n; i++) {\r\n        int h;\r\n        cin >> h;\r\n        int ans = 0;\r\n        v.push_back(h);\r\n        for (int j = i - 1; j >= 0; j--) {\r\n            if (v[j] < v[i])\r\n                ans++;\r\n        }\r\n        cout << ans << \" \";\r\n    }\r\n    return 0;\r\n}\r\n```', 'Lang Hu', 1, '18', 0, 9, 0, 0, 1553153857, 1556627614, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (23, '算法设计中素数的判定方法', '质数又称素数。一个大于1的自然数，除了1和它自身外，不能被其他自然数整除的数叫做质数；否则称为合数', '## 素数\r\n\r\n质数又称素数。一个大于1的自然数，除了1和它自身外，不能被其他自然数整除的数叫做质数；否则称为合数\r\n\r\n## 性质\r\n\r\n质数具有许多独特的性质：\r\n（1）质数p的约数只有两个：1和p。\r\n（2）初等数学基本定理：任一大于1的自然数，要么本身是质数，要么可以分解为几个质数之积，且这种分解是唯一的。\r\n（3）质数的个数是无限的。\r\n（4）质数的个数公式Π（n）是不减函数。\r\n（5）若n为正整数，在n^2到(n+1)^2之间至少有一个质数。\r\n（6）若n为大于或等于2的正整数，在n到n!之间至少有一个质数。\r\n（7）若质数p为不超过n（n≥4)的最大质数，则p > n/2。\r\n（8）所有大于10的质数中，个位数只有1,3,7,9。\r\n\r\n## 素数的判断\r\n### 1、朴素写法\r\n按照素数的定义，它的因数只有1和它本身，那么可以反过来想，如果再2到n-1之间有一个数字是他的因子，那么这个数字不是一个素数。有了这样一种思维，那么我们就有了最常规的一种写法：\r\n```\r\n/***\r\n*   main.cpp\r\n*   Created by HULANG-BTB on 2019/3/21 15:42:10.\r\n*\r\n***/\r\n#include <iostream>\r\n#include <cmath>\r\n\r\nusing namespace std;\r\n\r\nlong long num;\r\n\r\nbool is(long long n) {\r\n    for (int i = 2; i <= n - 1; i++)\r\n        if (n%i == 0)\r\n            return false;\r\n    return true;\r\n}\r\n\r\nint main() {\r\n    cin >> num;\r\n    if (is(num)) {\r\n        cout << \"Prime\" << endl;\r\n    }\r\n    else {\r\n        cout << \"Not Prime\" << endl;\r\n    }\r\n    return 0;\r\n}\r\n```\r\n从数字2开始一直循环检测，当有一个数字是它的因子的时候，返回false，这个算法的时间复杂度可以理解为O(n)。因为需要把整个2到n-1的数字循环遍历一遍。\r\n\r\n### 2、除法优化\r\n再遍历的过程中，我们可以想到，也许有一段数字我们并不需要去判断，因为由乘法交换律由：1x3 = 3x1\r\n所以我们只需要检测一半的数据。\r\n```\r\n/***\r\n*   main.cpp\r\n*   Created by HULANG-BTB on 2019/3/21 15:42:10.\r\n*\r\n***/\r\n#include <iostream>\r\n#include <cmath>\r\n\r\nusing namespace std;\r\n\r\nlong long num;\r\n\r\nbool is(long long n) {\r\n    for (int i = 2; i <= n/2 ; i++)\r\n        if (n%i == 0)\r\n            return false;\r\n    return true;\r\n}\r\n\r\nint main() {\r\n    cin >> num;\r\n    if (is(num)) {\r\n        cout << \"Prime\" << endl;\r\n    }\r\n    else {\r\n        cout << \"Not Prime\" << endl;\r\n    }\r\n    return 0;\r\n}\r\n```\r\n\r\n虽然再遍历的时候遍历次数减小为原来的一半，但是程序的时间复杂度仍然是O（n）\r\n\r\n### 3、开方优化\r\n\r\n根据第二种优化的思想。我们是不是还可以继续放弃一段判断的数据，这时我们可以想到，如果将我们要判断的数字进行开方，是不是能够再次减少运算的次数，可以考虑不等式(n/2)^2 > n的在n>0总的范围是n > 4,所以在n>4时计算的东西相对计算n/2要小得多，因此：\r\n\r\n```\r\n/***\r\n*   main.cpp\r\n*   Created by HULANG-BTB on 2019/3/21 15:42:10.\r\n*\r\n***/\r\n#include <iostream>\r\n#include <cmath>\r\n\r\nusing namespace std;\r\n\r\nlong long num;\r\n\r\nbool is(long long n) {\r\n    for (int i = 2; i <= (int)sqrt(n) ; i++)\r\n        if (n%i == 0)\r\n            return false;\r\n    return true;\r\n}\r\n\r\nint main() {\r\n    cin >> num;\r\n    if (is(num)) {\r\n        cout << \"Prime\" << endl;\r\n    }\r\n    else {\r\n        cout << \"Not Prime\" << endl;\r\n    }\r\n    return 0;\r\n}\r\n```\r\n\r\n这个算法得时间复杂度可以理解为O（nlogn），因为我们以开方得方式去掉了很大一部分数据。这个算法是不是到此结束了？当然没有，我们可以继续进行优化。\r\n\r\n### 4、规律优化\r\n\r\n我们首先看一下素数得排布\r\n\r\n![](/uploads/Images/article/2019-03-21/5c9348b559c81.jpg)\r\n\r\n经过观测\r\n除了数字2、3外，其他得所有得素数都是分类在6得整数倍数得左右两侧，比如\r\n5 = 6-1\r\n7 = 6+1\r\n11 = 12-1\r\n13 = 12+1\r\n…………\r\n所以我们在第三种优化的基础上，可以得知，如果一个数字不是在6的整数倍的左右两侧，那么这个数字一定是一个合数，所以我们循环的标准打可以从5开始，每次进步的步长为6的去判断。\r\n\r\n根据这个原理有：\r\n```\r\n/***\r\n*   main.cpp\r\n*   Created by HULANG-BTB on 2019/3/21 15:42:10.\r\n*\r\n***/\r\n#include <iostream>\r\n#include <cmath>\r\n\r\nusing namespace std;\r\n\r\nlong long num;\r\n\r\nbool is(long long n) {\r\n    if (n == 1)\r\n        return false;\r\n    if (n == 2 || n == 3)\r\n        return true;\r\n    if (n % 6 != 1 && n % 6 != 5)\r\n        return false;\r\n    long long len = (int)sqrt(double(n));\r\n    for (int i = 5; i <= len; i += 6) {\r\n        if (n % i == 0 || n % (i + 2) == 0)\r\n            return false;\r\n    }\r\n    return true;\r\n}\r\n\r\nint main() {\r\n    cin >> num;\r\n    if (is(num)) {\r\n        cout << \"Prime\" << endl;\r\n    }\r\n    else {\r\n        cout << \"Not Prime\" << endl;\r\n    }\r\n    return 0;\r\n}\r\n```\r\n\r\n在这里对于数字1、2、3需要进行一下特殊判定，因为循环其实位置为5，所以1需要判定，而2和3不在上述提到的规则之内，所以也需要特殊判定。\r\n\r\n这个算法的复杂度仍然理解为O（nlogn），因为我们只是在常数级别上进行了一些优化，但是这个算法在实际的运用中往往时间会更小。', 'Lang Hu', 1, '18', 0, 12, 0, 0, 1553156673, 1556627646, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (24, '二分搜索 算法模板', '算法竞赛二分通用模板，更改返回值类型可用', '## 二分搜索模板\r\n```\r\n/***\r\n*   main.cpp\r\n*   Created by HULANG-BTB on 2019/3/24 10:06:05.\r\n*\r\n***/\r\n#include <iostream>\r\n#include <algorithm>\r\n\r\nusing namespace std;\r\n\r\ndouble myFunc(int x) {\r\n    return x;\r\n}\r\n\r\nint binary_search(int lo, int hi, int find) {\r\n    while (lo < hi) {\r\n        int mid = (lo + hi) >> 1;\r\n        if (myFunc(mid) < find)\r\n            lo = mid + 1;\r\n        else if (find > myFunc(mid))\r\n            hi = mid;\r\n    }\r\n    return lo;\r\n}\r\n\r\nint main() {\r\n\r\n    cout << \"Hello ACM!\" << endl;\r\n\r\n    return 0;\r\n}\r\n```', 'Lang Hu', 1, '21', 0, 12, 0, 0, 1553393574, 1556698177, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (25, '最长上升子序列 算法模板', '提供两种方法，动态规划和二分搜索的模板，快速求最长上升子学列的长度。', '## 动态规划模板 (n^2)\r\n在DP算法中 d[i] 表示以v[i]结尾的最长上升子序列的长度\r\n```\r\n/***\r\n*   main.cpp\r\n*   Created by HULANG-BTB on 2019/3/24 10:24:40.\r\n*\r\n***/\r\n#include <iostream>\r\n#include <algorithm>\r\n\r\n#define MAXN 10000\r\n\r\nusing namespace std;\r\n\r\nint v[MAXN];\r\nint d[MAXN];\r\nint len = 0;\r\nint n;\r\n\r\nint main() {\r\n    cin >> n;\r\n    for (int i = 1; i <= n; i++)\r\n    {\r\n        cin >> v[i];\r\n    }\r\n    d[1] = v[1];\r\n    for (int i = 2; i <= n; i++)\r\n    {\r\n        for (int j = 1; j < i; j++)\r\n        {\r\n            if (d[j] >= d[i] && v[j] < v[i])\r\n                d[i] = d[j] + 1;\r\n            if (d[i] > len)\r\n                len = d[i];\r\n        }\r\n    }\r\n    cout << len;\r\n    return 0;\r\n}\r\n```\r\n\r\n## lower_bound (nlogn)\r\n在此算法中，d[i]表示长度为i的最长子序列的最小值\r\n```\r\n/***\r\n*   main.cpp\r\n*   Created by HULANG-BTB on 2019/3/24 10:24:40.\r\n*\r\n***/\r\n#include <iostream>\r\n#include <algorithm>\r\n\r\n#define MAXN 10000\r\n\r\nusing namespace std;\r\n\r\nint v[MAXN];\r\nint d[MAXN];\r\nint len;\r\nint n;\r\n\r\nint main() {\r\n    cin >> n;\r\n    for (int i = 1; i <= n; i++)\r\n    {\r\n        cin >> v[i];\r\n    }\r\n    d[1] = v[1];\r\n    len = 1;\r\n    for (int i = 2; i <= n; i++)\r\n    {\r\n        if (v[i] > d[len]) {\r\n            d[++len] = v[i];\r\n        }\r\n        else\r\n        {\r\n            d[lower_bound(d + 1, d + 1 + n, v[i]) - d] = v[i];\r\n        }\r\n    }\r\n    cout << len;\r\n    return 0;\r\n}\r\n```', 'Lang Hu', 1, '20,21', 0, 21, 0, 0, 1553396953, 1556697140, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (26, '天梯赛 L1-064 估值一亿的AI核心代码 （20 分)', '输入首先在第一行给出不超过 10 的正整数 N，随后 N 行，每行给出一句不超过 1000 个字符的、以回车结尾的用户的对话，对话为非空字符串，仅包括字母、数字、空格、可见的半角标点', '### 题目描述\r\n![](/uploads/Images/article/2019-03-31/5ca09a373f8a9.png)\r\n\r\n以上图片来自新浪微博。\r\n\r\n本题要求你实现一个稍微更值钱一点的 AI 英文问答程序，规则是：\r\n\r\n*   无论用户说什么，首先把对方说的话在一行中原样打印出来；\r\n*   消除原文中多余空格：把相邻单词间的多个空格换成 1 个空格，把行首尾的空格全部删掉，把标点符号前面的空格删掉；\r\n*   把原文中所有大写英文字母变成小写，除了 `I`；\r\n*   把原文中所有独立的 `can you`、`could you` 对应地换成 `I can`、`I could`—— 这里“独立”是指被空格或标点符号分隔开的单词；\r\n*   把原文中所有独立的 `I` 和 `me` 换成 `you`；\r\n*   把原文中所有的问号 `?` 换成惊叹号 `!`；\r\n*   在一行中输出替换后的句子作为 AI 的回答。\r\n\r\n### 输入格式：\r\n\r\n输入首先在第一行给出不超过 10 的正整数 N，随后 N 行，每行给出一句不超过 1000 个字符的、以回车结尾的用户的对话，对话为非空字符串，仅包括字母、数字、空格、可见的半角标点符号。\r\n\r\n### 输出格式：\r\n\r\n按题面要求输出，每个 AI 的回答前要加上 `AI:` 和一个空格。\r\n\r\n### 输入样例：\r\n\r\n    6\r\n    Hello ?\r\n     Good to chat   with you\r\n    can   you speak Chinese?\r\n    Really?\r\n    Could you show me 5\r\n    What Is this prime? I,don \'t know\r\n    \r\n\r\n### 输出样例：\r\n\r\n    Hello ?\r\n    AI: hello!\r\n     Good to chat   with you\r\n    AI: good to chat with you\r\n    can   you speak Chinese?\r\n    AI: I can speak chinese!\r\n    Really?\r\n    AI: really!\r\n    Could you show me 5\r\n    AI: I could show you 5\r\n    What Is this prime? I,don \'t know\r\n    AI: what Is this prime! you,don\'t know\r\n\r\n### 解题思路\r\n对于这样一个题目，看到之后很无奈，字符串处理，最麻烦的东西。不过如果用c++中的string，会便捷很多，对于输入的一行字符串，\r\n	1、使用replace方法，将所有的两个空格替换成一个空格（while），并且删除首尾空格。\r\n	2、将标点前面的空格删除掉。这个其实不需要考虑很多，实测搜索空格就行，判断下一个是否位标点符号。\r\n	3、字母大小写转换，这个不难，遍历字符串可以解决。\r\n	4、将```can you```和```could you```替换成```I can```和```I could```,这个地方和下一步将```I```和```me```替换成```you```有点坑，如果顺序替换，可能导致替换错误。\r\n	5、将问好替换成感叹号。\r\n	6、输出新句子。\r\n大体的步骤就是这个样子。接下来是代码：\r\n\r\n```\r\n/***\r\n*   main.cpp\r\n*   Created by HULANG-BTB on 2019/3/30 22:04:00.\r\n*\r\n***/\r\n#include <iostream>\r\n#include <algorithm>\r\n#include <string>\r\n#include <cstdio>\r\n\r\nusing namespace std;\r\n\r\nint n;\r\nstring line;\r\n\r\nvoid strtolower(string & s) {\r\n	for (int i = 0; i < s.size(); i++)\r\n		if (s[i] >= \'A\' && s[i] <= \'Z\' && s[i] != \'I\')\r\n			s[i] = s[i] - \'A\' + \'a\';\r\n}\r\n\r\nbool isletter(char c) {\r\n	return (c >= \'A\' && c <= \'Z\') || (c >= \'a\' && c <= \'z\');\r\n}\r\n\r\nvoid strreplace(string & s, string rs, string ms) {\r\n	while (s.find(rs) != -1) s.replace(s.find(rs), rs.size(), ms);\r\n}\r\n\r\nvoid strreplaceI(string & s, string rs, string ms) {\r\n	int index = -1;\r\n	while (s.find(rs, index + 1) != -1) {\r\n		index = s.find(rs, index + 1);\r\n		if (index == 0 && !isletter(s[index+rs.size()]))\r\n			s.replace(index, rs.size(), ms);\r\n		else if (index > 0 && !isletter(s[index + rs.size()]) && !isletter(s[index-1]))\r\n			s.replace(index, rs.size(), ms);\r\n		index += 1;\r\n	}\r\n}\r\n\r\nvoid trim(string & s) {\r\n	while (s[0] == \' \') s.erase(s.begin());\r\n	while (s[s.size() - 1] == \' \') s.erase(s.end() - 1);\r\n}\r\n\r\nint main() {\r\n    \r\n	cin >> n;\r\n	getchar();\r\n	for (int i = 0; i < n; i++)\r\n	{\r\n		if (i != 0)\r\n			cout << endl;\r\n		getline(cin, line);\r\n		cout << line << endl;\r\n		strtolower(line);\r\n		trim(line);\r\n		strreplace(line, string(\"  \"), string(\" \"));\r\n		strreplace(line, string(\" ?\"), string(\"!\"));\r\n		strreplace(line, string(\"?\"), string(\"!\"));\r\n		strreplaceI(line, string(\"can you\"), string(\"* can\"));\r\n		strreplaceI(line, string(\"could you\"), string(\"* could\"));\r\n		strreplaceI(line, string(\"I\"), string(\"you\"));\r\n		strreplaceI(line, string(\"me\"), string(\"you\"));\r\n		strreplace(line, string(\"*\"), string(\"I\"));\r\n		strreplace(line, string(\" \'\"), string(\"\'\"));\r\n		cout << \"AI: \" << line;\r\n	}\r\n    return 0;\r\n}\r\n```\r\n\r\n解释说明：\r\n1、通过strtolower函数将字符串大写转小写，过滤字母I。\r\n2、通过strreplace连续替换行中出现的字符串，多次替换。删除多余空格。\r\n3、通过trim函数将首位空格去掉。\r\n4、通过strreplaceI替换单独字符串，即字符串前面和后面是字符或者空格等。\r\n 细节处理：注意替换的时候这里是将```Can I```替换成```* can```最后将*替换成I。\r\n ', 'Lang Hu', 1, '18', 0, 66, 0, 0, 1554029885, 1556686181, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (27, '洛谷 P1024 一元三次方程求解', '有形如：ax^3+bx^2+cx^1+d=0这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d均为实数)，并约定该方程存在三个不同实根(根的范围在−100至100之间)，且根与根之差的绝对值≥1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格)，并精确到小数点后2位', '题目描述\r\n----\r\n\r\n有形如：$$ax^3+bx^2+cx^1+d=0$$ 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d均为实数)，并约定该方程存在三个不同实根(根的范围在−100至100之间)，且根与根之差的绝对值≥1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格)，并精确到小数点后2位。\r\n\r\n提示：记方程$$f(x)=0$$，若存在2个数$$x1$$和$$x2$$，且$$x1<x2$$，$$f(x1)*f(x2)<0$$，则在$$(x1,x2)$$之间一定有一个根。\r\n\r\n输入输出格式\r\n------\r\n\r\n**输入格式：**\r\n\r\n一行，4个实数A,B,C,D\r\n\r\n**输出格式：**\r\n\r\n一行，3个实根，并精确到小数点后2位。\r\n\r\n输入输出样例\r\n------\r\n\r\n**输入样例#1：**\r\n```\r\n1 -5 -4 20\r\n```\r\n**输出样例#1：**\r\n```\r\n-2.00 2.00 5.00\r\n```\r\n解题思路\r\n------\r\n根据题目描述中的给出的提示，不妨直接选定两个值，计算出$$f(x1)$$和$$f(x2)$$的乘积，这里值得考虑的是，这个x1和x2的范围应该到多大，再次读题，发现题目中有一个关键的条件。** 根与根之差的绝对值≥1 **，所以我们不妨从-100开始一直到100遍历，每次让$$x1=i$$ 且 $$x2=i+1$$，然后再去计算。当判断这个区间内有跟的时候在对这个长度为1的区间进行二分。\r\n除了题目给出的提示外，我们还应该想到，除了零点左右异号之外，还有一个条件，如果零点刚好在我们的整数点上，可能会出现$$f(x1)*f(x2)=0$$的情况，所以我们也需要处理一下。\r\n二分的过程中，如果$$f(mid)*f(hi)$$的值符号为正，则证明$$mid$$和$$hi$$这两个点在0点的同一侧，直接让$$hi=mid$$即可。\r\n题解\r\n------\r\n```c++\r\n/***\r\n*   main.cpp\r\n*   Created by AloneH on 2019/4/25 10:18:05.\r\n*\r\n***/\r\n#include <iostream>\r\n#include <algorithm>\r\n#include <cmath>\r\n#include <iomanip>\r\n\r\nusing namespace std;\r\n\r\ndouble a, b, c, d;\r\n\r\ndouble fx(double x) {\r\n    return a * pow(x, 3) + b * pow(x, 2) + c * x + d;\r\n}\r\n\r\ndouble getans(double lo, double hi) {\r\n    double ans = 0;\r\n    while (abs(hi - lo) > 0.00000001) {\r\n        double mid = (lo + hi) / 2;\r\n        ans = fx(mid);\r\n        if (ans * fx(hi) > 0) {\r\n            hi = mid;\r\n        }\r\n        else {\r\n            lo = mid;\r\n        }\r\n    }\r\n    return lo;\r\n}\r\n\r\nint main() {\r\n    cout.setf(ios::fixed);\r\n    cin >> a >> b >> c >> d;\r\n    for (double i = -100; i <= 100; i++)\r\n    {\r\n        double fi = fx(i);\r\n        double fj = fx(i + 1);\r\n        if (fi * fj < 0) {\r\n            cout << setprecision(2) << getans(i, i + 1) << \" \";\r\n        }\r\n        else if (fi == 0) {\r\n            cout << setprecision(2) << i << \" \";\r\n        }\r\n    }\r\n    return 0;\r\n}\r\n```', 'Lang Hu', 1, '21|18', 0, 74, 0, 0, 1556164462, 1556627658, '/uploads/Images/thumbnail/default.png', 0);
  INSERT INTO `article` VALUES (28, '洛谷 P2678 跳石头', '这项比赛将在一条笔直的河道中进行，河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间，有 N 块岩石（不含起点和终点的岩石）。在比赛过程中，选手们将从起点出发，每一步跳向相邻的岩石，直至到达终点。\r\n\r\n为了提高比赛难度，组委会计划移走一些岩石，使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制，组委会至多从起点和终点之间移走 M 块岩石（不能移走起点和终点的岩石）。', '### 题目背景\r\n------\r\n\r\n一年一度的“跳石头”比赛又要开始了!\r\n\r\n### 题目描述\r\n------\r\n\r\n这项比赛将在一条笔直的河道中进行，河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间，有 N 块岩石（不含起点和终点的岩石）。在比赛过程中，选手们将从起点出发，每一步跳向相邻的岩石，直至到达终点。\r\n\r\n为了提高比赛难度，组委会计划移走一些岩石，使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制，组委会至多从起点和终点之间移走 M 块岩石（不能移走起点和终点的岩石）。\r\n\r\n### 输入格式\r\n------\r\n\r\n第一行包含三个整数 L,N,M 分别表示起点到终点的距离，起点和终点之间的岩石数，以及组委会至多移走的岩石数。保证 $$L \\geq 1$$ 且 $$N \\geq M \\geq 0$$。\r\n\r\n接下来 $$N$$ 行，每行一个整数，第 $$i$$ 行的整数 $$ Di(0 < Di < L)$$， 表示第 $$i$$ 块岩石与起点的距离。这些岩石按与起点距离从小到大的顺序给出，且不会有两个岩石出现在同一个位置。\r\n\r\n### 输出格式\r\n------\r\n\r\n一个整数，即最短跳跃距离的最大值。\r\n\r\n### 输入输出样例\r\n\r\n**输入#1** \r\n```\r\n25 5 2 \r\n2\r\n11\r\n14\r\n17\r\n21\r\n```\r\n**输出#1**\r\n```\r\n4\r\n```\r\n### 说明/提示\r\n------\r\n输入输出样例 1 说明：将与起点距离为 2和 14 的两个岩石移走后,最短的跳跃距离为 4(从与起点距离 17 的岩石跳到距离 21 的岩石,或者从距离 21 的岩石跳到终点)。\r\n\r\n另：对于 20%的数据,$$0 \\leq M \\leq N \\leq 10$$。\r\n对于50%50\\\\%50%的数据,$$0 \\leq M \\leq N \\leq 100$$。\r\n对于 100%100\\\\%100%的数据,$$0 \\leq M \\leq N \\leq 50000$$,$$1 \\leq L \\leq 10^9\\leq 10$$\r\n\r\n解题思路\r\n---\r\n\r\n对于这样一个题目，我们可以使用二分搜索答案的方式，通过题目可以知道，最大距离的范围是0~L，那么我们只需要在0-L的数字中找到一个最大的数字，使得移除的石头数目刚好等于题目要求的数目即可。\r\n\r\n完全可以从前往后开始遍历，起点为$$cnt=0$$，在如果$$a[i]-cnt \\leq mid$$那么石头I就是可以移除的。遍历完成之后，如果可以移除的石头数目大于题目要求的数目，那么我们需要缩小hi，否则便放大lo。\r\n\r\n\r\n题解\r\n------\r\n```C++\r\n/***\r\n*   main.cpp\r\n*   Created by AloneH on 2019/4/25 9:43:37.\r\n*\r\n***/\r\n#include <iostream>\r\n#include <algorithm>\r\n\r\nusing namespace std;\r\n\r\nlong long l, n, m;\r\nint a[100000 + 5];\r\n\r\nint main() {\r\n    cin >> l >> n >> m;\r\n    for (int i = 0; i < n; i++)\r\n    {\r\n        cin >> a[i];\r\n    }\r\n    long long lo = 0LL;\r\n    long long hi = l;\r\n    while (lo < hi) {\r\n        long long mid = (lo + hi) >> 1;\r\n        long long ns = 0;\r\n        long long cnt = 0;\r\n        for (int i = 0; i < n; i++) {\r\n            if (a[i] - cnt <= mid) {\r\n                ns++;\r\n            }\r\n            else {\r\n                cnt = a[i];\r\n            }\r\n        }\r\n        if (ns > m) {\r\n            hi = mid;\r\n        }\r\n        else {\r\n            lo = mid + 1;\r\n        }\r\n    }\r\n    cout << lo;\r\n}\r\n```', 'Lang Hu', 1, '21|18', 0, 46, 0, 0, 1556165664, 1556694897, '/uploads/Images/thumbnail/default.png', 0);
  
  -- ----------------------------
  -- Table structure for category
  -- ----------------------------
  DROP TABLE IF EXISTS `category`;
  CREATE TABLE `category`  (
    `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '记录值',
    `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '分类名称',
    `create_time` int(11) UNSIGNED NULL DEFAULT NULL COMMENT '创建时间',
    `update_time` int(11) NULL DEFAULT NULL COMMENT '修改时间',
    `del` int(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
    PRIMARY KEY (`id`) USING BTREE
  ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  
  -- ----------------------------
  -- Records of category
  -- ----------------------------
  INSERT INTO `category` VALUES (1, '前端', NULL, NULL, 0);
  INSERT INTO `category` VALUES (2, '后端', NULL, NULL, 0);
  
  -- ----------------------------
  -- Table structure for comment
  -- ----------------------------
  DROP TABLE IF EXISTS `comment`;
  CREATE TABLE `comment`  (
    `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '记录值',
    `article_id` int(10) UNSIGNED NOT NULL COMMENT '文章ID',
    `parent_id` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '回复ID',
    `context` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '内容',
    `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '匿名' COMMENT '联系方式 姓名',
    `email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系方式 邮箱',
    `website` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系方式 地址',
    `ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '回复时IP',
    `city` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '城市',
    `create_time` int(11) UNSIGNED NOT NULL COMMENT '创建时间',
    `update_time` int(11) UNSIGNED NOT NULL COMMENT '修改时间',
    `del` int(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
    PRIMARY KEY (`id`) USING BTREE
  ) ENGINE = MyISAM AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  
  -- ----------------------------
  -- Records of comment
  -- ----------------------------
  INSERT INTO `comment` VALUES (1, 3, 0, '1', '匿名', '1', '1', '1', '1', 1, 1556591256, 0);
  
  -- ----------------------------
  -- Table structure for navigation
  -- ----------------------------
  DROP TABLE IF EXISTS `navigation`;
  CREATE TABLE `navigation`  (
    `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键 记录值',
    `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '导航栏名字',
    `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '地址 带http://',
    `status` tinyint(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '状态 0-正常显示 1-隐藏',
    `sequence` smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT '显示顺序 默认0',
    `type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '导航类型 0-自定义 1-分类导航',
    `open_type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '打开方式 0-当前窗口 1-新标签页',
    `create_time` int(11) UNSIGNED NULL DEFAULT NULL COMMENT '创建时间',
    `update_time` int(11) UNSIGNED NULL DEFAULT NULL COMMENT '更新时间',
    PRIMARY KEY (`id`) USING BTREE
  ) ENGINE = MyISAM AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  
  -- ----------------------------
  -- Records of navigation
  -- ----------------------------
  INSERT INTO `navigation` VALUES (1, '首页', '/index/index/index', 0, 1, 0, 0, NULL, NULL);
  INSERT INTO `navigation` VALUES (2, '分类', '/index/category/index', 0, 2, 0, 0, NULL, NULL);
  INSERT INTO `navigation` VALUES (3, '标签', '/index/tag/index', 0, 3, 0, 0, NULL, NULL);
  INSERT INTO `navigation` VALUES (4, '时间轴', '/index/timeline/index', 0, 4, 0, 0, NULL, NULL);
  INSERT INTO `navigation` VALUES (5, '关于', '/index/about/index', 0, 5, 0, 0, NULL, NULL);
  INSERT INTO `navigation` VALUES (6, '联系', '/index/contact/index', 0, 6, 0, 0, NULL, NULL);
  INSERT INTO `navigation` VALUES (7, '打赏', '/index/index/index', 0, 7, 0, 0, NULL, NULL);
  INSERT INTO `navigation` VALUES (9, '百度', 'http://baidu.com', 0, 8, 0, 1, NULL, NULL);
  
  -- ----------------------------
  -- Table structure for option
  -- ----------------------------
  DROP TABLE IF EXISTS `option`;
  CREATE TABLE `option`  (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
    `value` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
    PRIMARY KEY (`id`) USING BTREE
  ) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  
  -- ----------------------------
  -- Records of option
  -- ----------------------------
  INSERT INTO `option` VALUES (1, 'web_title', 'Bit客栈');
  INSERT INTO `option` VALUES (2, 'web_subtitle', '二级标题');
  INSERT INTO `option` VALUES (3, 'web_keyword', '学习|生活|日志');
  INSERT INTO `option` VALUES (4, 'web_description', '这是一个跟不上时代脚步得2B青年你奋斗得博客');
  INSERT INTO `option` VALUES (5, 'web_domain', 'http://oibit.cn');
  INSERT INTO `option` VALUES (6, 'web_copyright', '版权信息');
  INSERT INTO `option` VALUES (7, 'upload_size', '1024');
  INSERT INTO `option` VALUES (8, 'upload_type', 'png|rar|jpg|gif');
  INSERT INTO `option` VALUES (9, 'web_cache', '0');
  INSERT INTO `option` VALUES (10, 'mail_host', 'smtp.qq.com');
  INSERT INTO `option` VALUES (11, 'mail_port', '465');
  INSERT INTO `option` VALUES (12, 'mail_user', 'test');
  INSERT INTO `option` VALUES (13, 'mail_pass', 'test');
  INSERT INTO `option` VALUES (14, 'mail_from', 'none');
  INSERT INTO `option` VALUES (15, 'web_favicon', './favicon.cio');
  
  -- ----------------------------
  -- Table structure for tag
  -- ----------------------------
  DROP TABLE IF EXISTS `tag`;
  CREATE TABLE `tag`  (
    `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '记录值',
    `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '标签名',
    `create_time` int(11) UNSIGNED NULL DEFAULT NULL COMMENT '创建时间',
    `update_time` int(11) UNSIGNED NULL DEFAULT NULL COMMENT '修改时间',
    `del` int(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
    PRIMARY KEY (`id`) USING BTREE
  ) ENGINE = MyISAM AUTO_INCREMENT = 26 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  
  -- ----------------------------
  -- Records of tag
  -- ----------------------------
  INSERT INTO `tag` VALUES (1, '标签', NULL, 1556547430, 0);
  INSERT INTO `tag` VALUES (2, 'ＰＨＰ', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (3, 'JavaScript', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (4, 'ＨＴＭＬ', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (5, '后端', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (6, '人工智能', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (7, '神经网络', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (8, '机器学习', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (9, 'Arduino', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (10, 'Android', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (11, 'Python', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (12, 'QT', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (13, 'C++', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (14, 'JAVA', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (15, 'C', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (16, '易语言', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (17, '其他', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (18, '算法', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (19, '环境搭建', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (20, '动态规划', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (21, '二分搜索', NULL, NULL, 0);
  INSERT INTO `tag` VALUES (25, '修改时间', 1556546810, 1556547482, 0);
  
  -- ----------------------------
  -- Table structure for upload
  -- ----------------------------
  DROP TABLE IF EXISTS `upload`;
  CREATE TABLE `upload`  (
    `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
    `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '保存路径',
    `size` int(11) NOT NULL COMMENT '大小',
    `create_time` int(11) UNSIGNED NULL DEFAULT NULL COMMENT '上传时间',
    `update_time` int(11) UNSIGNED NULL DEFAULT NULL COMMENT '修改时间',
    PRIMARY KEY (`id`) USING BTREE
  ) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  
  -- ----------------------------
  -- Records of upload
  -- ----------------------------
  INSERT INTO `upload` VALUES (5, '\\uploads\\images\\20190429\\a378618549e3599e64c3dc2243f00573.png', 12790, 1556545898, 1556545898);
  INSERT INTO `upload` VALUES (6, '\\uploads\\images\\20190429\\5f2d14a975930415be0585507aa80d2a.png', 7419, 1556545925, 1556545925);
  INSERT INTO `upload` VALUES (7, '\\uploads\\images\\20190429\\5d24bc73462629465e3af1344f22a58f.png', 3619, 1556545930, 1556545930);
  INSERT INTO `upload` VALUES (8, '\\uploads\\images\\20190429\\9c9d4db562b0d1f6100b0142e9b42edb.png', 3650, 1556546421, 1556546421);
  
  -- ----------------------------
  -- Table structure for user
  -- ----------------------------
  DROP TABLE IF EXISTS `user`;
  CREATE TABLE `user`  (
    `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
    `group_id` int(11) NOT NULL DEFAULT 1 COMMENT '用户组',
    `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
    `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
    `nickname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '昵称',
    `phone` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '电话',
    `email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '邮件',
    `avator` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'default.png' COMMENT '头像',
    `login_time` int(11) NULL DEFAULT 0 COMMENT '登录时间',
    `login_ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0.0.0.0' COMMENT '登录IP',
    `create_time` int(11) NULL DEFAULT NULL COMMENT '创建时间',
    `update_time` int(11) NULL DEFAULT NULL COMMENT '修改时间',
    `type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '用户' COMMENT '类型',
    `status` int(1) NOT NULL DEFAULT 1 COMMENT '状态',
    `token` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'Token',
    `salt` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码盐',
    `verification` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '验证',
    PRIMARY KEY (`id`) USING BTREE
  ) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  
  -- ----------------------------
  -- Records of user
  -- ----------------------------
  INSERT INTO `user` VALUES (1, 2, 'AloneH', '04d19d2a202c3ce030e1eac8d3ca6d825ac142e6', 'AloneH', '18000000000', 'admin@oibit.cn', 'default.png', 0, '0.0.0.0', NULL, NULL, '1', 1, '1f71d346a2d5e2d1093f73d282ef7113', 'Rs23', NULL);
  
  -- ----------------------------
  -- Table structure for user_group
  -- ----------------------------
  DROP TABLE IF EXISTS `user_group`;
  CREATE TABLE `user_group`  (
    `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '组名',
    `rules` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '权限节点',
    `create_time` int(11) NULL DEFAULT NULL COMMENT '添加时间',
    `update_time` int(11) NULL DEFAULT NULL COMMENT '更新时间',
    `status` enum('normal','ban') CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '状态',
    PRIMARY KEY (`id`) USING BTREE
  ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '会员组表' ROW_FORMAT = Compact;
  
  -- ----------------------------
  -- Records of user_group
  -- ----------------------------
  INSERT INTO `user_group` VALUES (1, '普通用户', '', 1556550772, 1556550772, 'normal');
  INSERT INTO `user_group` VALUES (2, '管理员', '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42', 1556700038, 1556700038, 'normal');
  
  -- ----------------------------
  -- Table structure for user_rule
  -- ----------------------------
  DROP TABLE IF EXISTS `user_rule`;
  CREATE TABLE `user_rule`  (
    `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `pid` int(10) NULL DEFAULT NULL COMMENT '父ID',
    `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '名称',
    `title` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '标题',
    `remark` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',
    `ismenu` tinyint(1) NULL DEFAULT NULL COMMENT '是否菜单',
    `create_time` int(10) NULL DEFAULT NULL COMMENT '创建时间',
    `update_time` int(10) NULL DEFAULT NULL COMMENT '更新时间',
    `weigh` int(10) NULL DEFAULT 0 COMMENT '权重',
    `status` enum('normal','hidden') CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '状态',
    PRIMARY KEY (`id`) USING BTREE
  ) ENGINE = InnoDB AUTO_INCREMENT = 43 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '会员规则表' ROW_FORMAT = Compact;
  
  -- ----------------------------
  -- Records of user_rule
  -- ----------------------------
  INSERT INTO `user_rule` VALUES (1, 0, 'admin', '后台管理', '', 0, 1556550804, 1556550804, 0, 'normal');
  INSERT INTO `user_rule` VALUES (2, 1, 'home', '首页模块', '', 0, 1556550828, 1556550885, 0, 'normal');
  INSERT INTO `user_rule` VALUES (3, 2, 'admin/index/index', '首页', '', 0, 1556550859, 1556550907, 0, 'normal');
  INSERT INTO `user_rule` VALUES (4, 1, 'home', '控制面板', '', 0, 1556550971, 1556550971, 0, 'normal');
  INSERT INTO `user_rule` VALUES (5, 4, 'admin/home/index', '控制台', '', 0, 1556551000, 1556551000, 0, 'normal');
  INSERT INTO `user_rule` VALUES (6, 1, 'option', '网站设置', '', 0, 1556551029, 1556551029, 0, 'normal');
  INSERT INTO `user_rule` VALUES (7, 6, 'admin/option/web', '网站设置', '页面', 0, 1556551058, 1556551058, 0, 'normal');
  INSERT INTO `user_rule` VALUES (8, 6, 'admin/option/email', '邮件设置', '页面', 0, 1556551110, 1556551110, 0, 'normal');
  INSERT INTO `user_rule` VALUES (9, 6, 'admin/option/update', '更改设置', '更改数据', 0, 1556551163, 1556551163, 0, 'normal');
  INSERT INTO `user_rule` VALUES (10, 1, 'article', '文章管理', '', 0, 1556551178, 1556551178, 0, 'normal');
  INSERT INTO `user_rule` VALUES (11, 10, 'admin/article/add', '添加文章', '页面', 0, 1556551206, 1556551206, 0, 'normal');
  INSERT INTO `user_rule` VALUES (12, 10, 'admin/article/index', '文章列表', '页面', 0, 1556551242, 1556551242, 0, 'normal');
  INSERT INTO `user_rule` VALUES (13, 10, 'admin/article/recycle', '回收站', '页面', 0, 1556551268, 1556551268, 0, 'normal');
  INSERT INTO `user_rule` VALUES (14, 10, 'admin/article/insert', '插入数据', '数据', 0, 1556551312, 1556551312, 0, 'normal');
  INSERT INTO `user_rule` VALUES (15, 10, 'admin/article/delete', '删除文章', '', 0, 1556551337, 1556551420, 0, 'normal');
  INSERT INTO `user_rule` VALUES (16, 10, 'admin/article/recovery', '恢复文章', '', 0, 1556551363, 1556551363, 0, 'normal');
  INSERT INTO `user_rule` VALUES (17, 10, 'admin/article/picture', '上传图片', '', 0, 1556551396, 1556551396, 0, 'normal');
  INSERT INTO `user_rule` VALUES (18, 10, 'admin/article/edit', '编辑文章', '页面', 0, 1556551463, 1556551463, 0, 'normal');
  INSERT INTO `user_rule` VALUES (19, 10, 'admin/article/update', '更新数据', '', 0, 1556551504, 1556551504, 0, 'normal');
  INSERT INTO `user_rule` VALUES (20, 10, 'admin/article/read', '读取数据', '', 0, 1556551533, 1556551533, 0, 'normal');
  INSERT INTO `user_rule` VALUES (21, 1, 'tag', '标签管理', '', 0, 1556551553, 1556551553, 0, 'normal');
  INSERT INTO `user_rule` VALUES (22, 21, 'admin/tag/index', '标签列表', '页面', 0, 1556551596, 1556551596, 0, 'normal');
  INSERT INTO `user_rule` VALUES (23, 21, 'admin/tag/read', '读取数据', '数据', 0, 1556551625, 1556551625, 0, 'normal');
  INSERT INTO `user_rule` VALUES (24, 21, 'admin/tag/modify', '修改数据', '数据', 0, 1556551647, 1556551647, 0, 'normal');
  INSERT INTO `user_rule` VALUES (25, 21, 'admin/tag/delete', '删除标签', '数据', 0, 1556551669, 1556551685, 0, 'normal');
  INSERT INTO `user_rule` VALUES (26, 21, 'admin/tag/add', '添加标签', '', 0, 1556551733, 1556551733, 0, 'normal');
  INSERT INTO `user_rule` VALUES (27, 21, 'admin/tag/recycle', '回收站', '页面', 0, 1556551761, 1556551761, 0, 'normal');
  INSERT INTO `user_rule` VALUES (28, 21, 'admin/tag/recovery', '恢复标签', '数据', 0, 1556551795, 1556551795, 0, 'normal');
  INSERT INTO `user_rule` VALUES (29, 1, 'category', '分类管理', '', 0, 1556551553, 1556551553, 0, 'normal');
  INSERT INTO `user_rule` VALUES (30, 29, 'admin/category/index', '分类列表', '页面', 0, 1556551596, 1556551596, 0, 'normal');
  INSERT INTO `user_rule` VALUES (31, 29, 'admin/category/read', '读取数据', '数据', 0, 1556551625, 1556551625, 0, 'normal');
  INSERT INTO `user_rule` VALUES (32, 29, 'admin/category/modify', '修改数据', '数据', 0, 1556551647, 1556551647, 0, 'normal');
  INSERT INTO `user_rule` VALUES (33, 29, 'admin/category/delete', '删除分类', '数据', 0, 1556551669, 1556551685, 0, 'normal');
  INSERT INTO `user_rule` VALUES (34, 29, 'admin/category/add', '添加分类', '', 0, 1556551733, 1556551733, 0, 'normal');
  INSERT INTO `user_rule` VALUES (35, 29, 'admin/category/recycle', '回收站', '页面', 0, 1556551761, 1556551761, 0, 'normal');
  INSERT INTO `user_rule` VALUES (36, 29, 'admin/category/recovery', '恢复分类', '数据', 0, 1556551795, 1556551795, 0, 'normal');
  INSERT INTO `user_rule` VALUES (37, 1, 'comment', '评论管理', '', 0, 1556591795, 1556591795, 0, 'normal');
  INSERT INTO `user_rule` VALUES (38, 37, 'admin/comment/index', '评论列表', '页面', 0, 1556591828, 1556591828, 0, 'normal');
  INSERT INTO `user_rule` VALUES (39, 37, 'admin/comment/recycle', '回收站', '', 0, 1556591847, 1556591847, 0, 'normal');
  INSERT INTO `user_rule` VALUES (40, 37, 'admin/comment/read', '读取评论', '数据', 0, 1556591871, 1556591871, 0, 'normal');
  INSERT INTO `user_rule` VALUES (41, 37, 'admin/comment/delete', '删除评论', '数据', 0, 1556591937, 1556591937, 0, 'normal');
  INSERT INTO `user_rule` VALUES (42, 37, 'admin/comment/recovery', '恢复评论', '数据', 0, 1556591966, 1556591991, 0, 'normal');
  
  SET FOREIGN_KEY_CHECKS = 1;
  