Browse Source

first commit

zhuliang 7 years ago
parent
commit
bd50cb28e3
100 changed files with 34190 additions and 0 deletions
  1. 189 0
      Application/Common/Common/function.php
  2. 1 0
      Application/Common/Common/index.html
  3. 4 0
      Application/Common/Conf/config.php
  4. 14 0
      Application/Common/Conf/debug.php
  5. 1 0
      Application/Common/Conf/index.html
  6. 1 0
      Application/Common/index.html
  7. 1 0
      Application/Home/Common/index.html
  8. 9 0
      Application/Home/Conf/config.php
  9. 1 0
      Application/Home/Conf/index.html
  10. 5 0
      Application/Home/Conf/tags.php
  11. 62 0
      Application/Home/Controller/AttornController.class.php
  12. 123 0
      Application/Home/Controller/BaseController.class.php
  13. 34 0
      Application/Home/Controller/CatalogController.class.php
  14. 32 0
      Application/Home/Controller/CommonController.class.php
  15. 35 0
      Application/Home/Controller/IndexController.class.php
  16. 293 0
      Application/Home/Controller/ItemController.class.php
  17. 99 0
      Application/Home/Controller/MemberController.class.php
  18. 188 0
      Application/Home/Controller/PageController.class.php
  19. 71 0
      Application/Home/Controller/TemplateController.class.php
  20. 495 0
      Application/Home/Controller/UpdateController.class.php
  21. 176 0
      Application/Home/Controller/UserController.class.php
  22. 1 0
      Application/Home/Controller/index.html
  23. 216 0
      Application/Home/Lang/en-us.php
  24. 220 0
      Application/Home/Lang/zh-cn.php
  25. 17 0
      Application/Home/Model/BaseModel.class.php
  26. 182 0
      Application/Home/Model/ItemModel.class.php
  27. 52 0
      Application/Home/Model/UserModel.class.php
  28. 34 0
      Application/Home/Model/UserTokenModel.class.php
  29. 1 0
      Application/Home/Model/index.html
  30. 44 0
      Application/Home/View/Attorn/index.html
  31. 77 0
      Application/Home/View/Catalog/edit.html
  32. 11 0
      Application/Home/View/Common/footer.html
  33. 23 0
      Application/Home/View/Common/header.html
  34. 38 0
      Application/Home/View/Common/message.html
  35. 132 0
      Application/Home/View/Index/index.html
  36. 143 0
      Application/Home/View/Item/add.html
  37. 38 0
      Application/Home/View/Item/delete.html
  38. 57 0
      Application/Home/View/Item/export.html
  39. 52 0
      Application/Home/View/Item/index.html
  40. 70 0
      Application/Home/View/Item/pwd.html
  41. 269 0
      Application/Home/View/Item/setting.html
  42. 176 0
      Application/Home/View/Item/show.html
  43. 187 0
      Application/Home/View/Item/show_regular.html
  44. 89 0
      Application/Home/View/Item/show_single_page.html
  45. 71 0
      Application/Home/View/Item/showbyuid.html
  46. 44 0
      Application/Home/View/MdTemplate/api-doc.en-us.html
  47. 45 0
      Application/Home/View/MdTemplate/api-doc.zh-cn.html
  48. 12 0
      Application/Home/View/MdTemplate/database.en-us.html
  49. 13 0
      Application/Home/View/MdTemplate/database.zh-cn.html
  50. 57 0
      Application/Home/View/Member/edit.html
  51. 89 0
      Application/Home/View/Page/diff.html
  52. 148 0
      Application/Home/View/Page/edit.html
  53. 47 0
      Application/Home/View/Page/history.html
  54. 21 0
      Application/Home/View/Page/index.html
  55. 152 0
      Application/Home/View/Page/single.html
  56. 67 0
      Application/Home/View/User/login.html
  57. 58 0
      Application/Home/View/User/register.html
  58. 19 0
      Application/Home/View/User/setting.html
  59. 1 0
      Application/Home/View/index.html
  60. 1 0
      Application/Home/index.html
  61. 1 0
      Application/README.md
  62. 1 0
      Application/Runtime/index.html
  63. 1 0
      Application/index.html
  64. 16 0
      Dockerfile
  65. 1 0
      Public/README.md
  66. 1 0
      Public/Uploads/index.html
  67. 1109 0
      Public/bootstrap/css/bootstrap-responsive.css
  68. 9 0
      Public/bootstrap/css/bootstrap-responsive.min.css
  69. 6167 0
      Public/bootstrap/css/bootstrap.css
  70. 9 0
      Public/bootstrap/css/bootstrap.min.css
  71. BIN
      Public/bootstrap/img/glyphicons-halflings-white.png
  72. BIN
      Public/bootstrap/img/glyphicons-halflings.png
  73. 2280 0
      Public/bootstrap/js/bootstrap.js
  74. 11 0
      Public/bootstrap/js/bootstrap.min.js
  75. 38 0
      Public/css/index.css
  76. 51 0
      Public/css/item/index.css
  77. 171 0
      Public/css/item/show.css
  78. 83 0
      Public/css/item/show_single_page.css
  79. 182 0
      Public/css/jquery.fullPage.css
  80. 52 0
      Public/css/login.css
  81. 491 0
      Public/css/page/edit.css
  82. 46 0
      Public/css/page/index.css
  83. 35 0
      Public/css/showdoc.css
  84. 46 0
      Public/css/tab-tpl.css
  85. 411 0
      Public/diff/difflib.js
  86. 83 0
      Public/diff/diffview.css
  87. 198 0
      Public/diff/diffview.js
  88. 342 0
      Public/editor.md/Gulpfile.js
  89. 22 0
      Public/editor.md/LICENSE
  90. 119 0
      Public/editor.md/README.md
  91. 4450 0
      Public/editor.md/css/editormd.css
  92. 98 0
      Public/editor.md/css/editormd.logo.css
  93. 2 0
      Public/editor.md/css/editormd.logo.min.css
  94. 5 0
      Public/editor.md/css/editormd.min.css
  95. 3554 0
      Public/editor.md/css/editormd.preview.css
  96. 5 0
      Public/editor.md/css/editormd.preview.min.css
  97. 4667 0
      Public/editor.md/editormd.amd.js
  98. 4 0
      Public/editor.md/editormd.amd.min.js
  99. 4621 0
      Public/editor.md/editormd.js
  100. 0 0
      Public/editor.md/editormd.min.js

+ 189 - 0
Application/Common/Common/function.php

@@ -0,0 +1,189 @@
+<?php
+
+
+/**
+ * 获得当前的域名
+ *
+ * @return  string
+ */
+function get_domain()
+{
+    /* 协议 */
+    $protocol = (isset($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) != 'off')) ? 'https://' : 'http://';
+
+    /* 域名或IP地址 */
+    if (isset($_SERVER['HTTP_X_FORWARDED_HOST']))
+    {
+        $host = $_SERVER['HTTP_X_FORWARDED_HOST'];
+    }
+    elseif (isset($_SERVER['HTTP_HOST']))
+    {
+        $host = $_SERVER['HTTP_HOST'];
+    }
+    else
+    {
+        /* 端口 */
+        if (isset($_SERVER['SERVER_PORT']))
+        {
+            $port = ':' . $_SERVER['SERVER_PORT'];
+
+            if ((':80' == $port && 'http://' == $protocol) || (':443' == $port && 'https://' == $protocol))
+            {
+                $port = '';
+            }
+        }
+        else
+        {
+            $port = '';
+        }
+
+        if (isset($_SERVER['SERVER_NAME']))
+        {
+            $host = $_SERVER['SERVER_NAME'] . $port;
+        }
+        elseif (isset($_SERVER['SERVER_ADDR']))
+        {
+            $host = $_SERVER['SERVER_ADDR'] . $port;
+        }
+    }
+
+    return $protocol . $host;
+}
+
+/**
+ * 获得网站的URL地址
+ *
+ * @return  string
+ */
+function site_url()
+{
+    return get_domain() . substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'));
+}
+
+
+//导出称word
+function output_word($data,$fileName=''){
+
+    if(empty($data)) return '';
+
+    $data = '
+        <html xmlns:v="urn:schemas-microsoft-com:vml"
+        xmlns:o="urn:schemas-microsoft-com:office:office"
+        xmlns:w="urn:schemas-microsoft-com:office:word"
+        xmlns="http://www.w3.org/TR/REC-html40">
+        <head><meta http-equiv=Content-Type content="text/html;  
+        charset=utf-8">
+		<style type="text/css">
+			table  
+			{  
+				border-collapse: collapse;
+				border: none;  
+				width: 100%;  
+			}  
+			td  
+			{  
+				border: solid #CCC 1px;  
+			}  
+			.codestyle{
+				word-break: break-all;
+				background:silver;mso-highlight:silver;
+			}
+		</style>
+        <meta name=ProgId content=Word.Document>
+        <meta name=Generator content="Microsoft Word 11">
+        <meta name=Originator content="Microsoft Word 11">
+        <xml><w:WordDocument><w:View>Print</w:View></xml></head>
+        <body>'.$data.'</body></html>';
+    
+    $filepath = tmpfile();
+	$data = str_replace("<thead>\n<tr>","<thead><tr style='background-color: rgb(0, 136, 204); color: rgb(255, 255, 255);'>",$data);
+	$data = str_replace("<pre><code>","<table width='100%' class='codestyle'><pre><code>",$data);
+	$data = str_replace("</code></pre>","</code></pre></table>",$data);
+    $len = strlen($data);
+    fwrite($filepath, $data);
+    header("Content-type: application/octet-stream");
+    header("Content-Disposition: attachment; filename={$fileName}.doc");
+    header('Content-Description: File Transfer');
+    header('Content-Type: application/octet-stream');
+    header('Content-Disposition: attachment; filename='.$fileName.'.doc');
+    header('Content-Transfer-Encoding: binary');
+    header('Expires: 0');
+    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+    header('Pragma: public');
+    header('Content-Length: ' . $len);
+    rewind($filepath);
+    echo fread($filepath,$len);
+}
+
+
+function clear_runtime($path = RUNTIME_PATH){  
+    //给定的目录不是一个文件夹  
+    if(!is_dir($path)){  
+        return null;  
+    }  
+  
+    $fh = opendir($path);  
+    while(($row = readdir($fh)) !== false){  
+        //过滤掉虚拟目录  
+        if($row == '.' || $row == '..'|| $row == 'index.html'){  
+            continue;  
+        }  
+  
+        if(!is_dir($path.'/'.$row)){
+            unlink($path.'/'.$row);  
+        }  
+        clear_runtime($path.'/'.$row);  
+          
+    }  
+    //关闭目录句柄,否则出Permission denied  
+    closedir($fh);    
+    return true;  
+}
+
+//获取ip
+function getIPaddress(){
+    $IPaddress='';
+    if (isset($_SERVER)){
+        if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])){
+            $IPaddress = $_SERVER["HTTP_X_FORWARDED_FOR"];
+        } else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
+            $IPaddress = $_SERVER["HTTP_CLIENT_IP"];
+        } else {
+            $IPaddress = $_SERVER["REMOTE_ADDR"];
+        }
+    } else {
+        if (getenv("HTTP_X_FORWARDED_FOR")){
+            $IPaddress = getenv("HTTP_X_FORWARDED_FOR");
+        } else if (getenv("HTTP_CLIENT_IP")) {
+            $IPaddress = getenv("HTTP_CLIENT_IP");
+        } else {
+            $IPaddress = getenv("REMOTE_ADDR");
+        }
+    }
+    return $IPaddress;
+
+}
+
+function http_post($url, $param) {
+    $oCurl = curl_init ();
+    if (stripos ( $url, "https://" ) !== FALSE) {
+        curl_setopt ( $oCurl, CURLOPT_SSL_VERIFYPEER, FALSE );
+        curl_setopt ( $oCurl, CURLOPT_SSL_VERIFYHOST, false );
+    }
+    if (is_string ( $param )) {
+        $strPOST = $param;
+    } else {
+        $aPOST = array ();
+        foreach ( $param as $key => $val ) {
+            $aPOST [] = $key . "=" . urlencode ( $val );
+        }
+        $strPOST = join ( "&", $aPOST );
+    }
+    curl_setopt ( $oCurl, CURLOPT_URL, $url );
+    curl_setopt ( $oCurl, CURLOPT_RETURNTRANSFER, 1 );
+    curl_setopt ( $oCurl, CURLOPT_POST, true );
+    curl_setopt ( $oCurl, CURLOPT_POSTFIELDS, $strPOST );
+    $sContent = curl_exec ( $oCurl );
+    curl_close ( $oCurl );
+    return $sContent;
+}

+ 1 - 0
Application/Common/Common/index.html

@@ -0,0 +1 @@
+ 

+ 4 - 0
Application/Common/Conf/config.php

@@ -0,0 +1,4 @@
+<?php
+//showdoc not install 
+//
+//

+ 14 - 0
Application/Common/Conf/debug.php

@@ -0,0 +1,14 @@
+<?php
+
+// 调试模式下面默认设置 可以在应用配置目录下重新定义 debug.php 覆盖
+return  array(
+    'LOG_RECORD'            =>  false,  // 进行日志记录
+    'LOG_EXCEPTION_RECORD'  =>  false,    // 是否记录异常信息日志
+    'LOG_LEVEL'             =>  'ERR',  // 允许记录的日志级别
+    'DB_FIELDS_CACHE'       =>  false, // 字段缓存信息
+    'DB_DEBUG'				=>  false, // 开启调试模式 记录SQL日志
+    'TMPL_CACHE_ON'         =>  false,        // 是否开启模板编译缓存,设为false则每次都会重新编译
+    'TMPL_STRIP_SPACE'      =>  false,       // 是否去除模板文件里面的html空格与换行
+    'SHOW_ERROR_MSG'        =>  true,    // 显示错误信息
+    'URL_CASE_INSENSITIVE'  =>  false,  // URL区分大小写
+);

+ 1 - 0
Application/Common/Conf/index.html

@@ -0,0 +1 @@
+ 

+ 1 - 0
Application/Common/index.html

@@ -0,0 +1 @@
+ 

+ 1 - 0
Application/Home/Common/index.html

@@ -0,0 +1 @@
+ 

+ 9 - 0
Application/Home/Conf/config.php

@@ -0,0 +1,9 @@
+<?php 
+return array(
+	//'配置项'=>'配置值'
+    'LANG_SWITCH_ON' => true,   // 开启语言包功能
+    'LANG_AUTO_DETECT' => false, // 自动侦测语言 开启多语言功能后有效
+    'DEFAULT_LANG' => 'zh-cn', // 默认语言
+    'LANG_LIST'        => 'zh-cn,en-us', // 允许切换的语言列表 用逗号分隔
+    'VAR_LANGUAGE'     => 'l', // 默认语言切换变量
+);

+ 1 - 0
Application/Home/Conf/index.html

@@ -0,0 +1 @@
+ 

+ 5 - 0
Application/Home/Conf/tags.php

@@ -0,0 +1,5 @@
+<?php
+return array(
+    // 添加下面一行定义即可
+    'app_begin' => array('Behavior\CheckLangBehavior'),
+);

+ 62 - 0
Application/Home/Controller/AttornController.class.php

@@ -0,0 +1,62 @@
+<?php
+namespace Home\Controller;
+use Think\Controller;
+class AttornController extends BaseController {
+
+    //转让页面
+    public function index(){
+        $item_id =  I("item_id");
+        $login_user = $this->checkLogin();
+        if (!$this->checkItemCreator($login_user['uid'] , $item_id)) {
+            $this->message(L('no_permissions'));
+            return;
+        }
+        $this->assign("item_id" , $item_id);
+
+        $this->display();        
+    }
+
+    //保存
+    public function save(){
+        $login_user = $this->checkLogin();
+
+        $username = I("username");
+        $item_id = I("item_id/d");
+        $password = I("password");
+
+        $item  = D("Item")->where("item_id = '$item_id' ")->find();
+
+        if(! D("User")-> checkLogin($item['username'],$password)){
+            $return['error_code'] = 10102 ;
+            $return['error_message'] = L('incorrect_password') ;
+            $this->sendResult($return);
+            return ;
+        }
+
+        $member = D("User")->where(" username = '%s' ",array($username))->find();
+
+        if (!$member) {
+            $return['error_code'] = 10201 ;
+            $return['error_message'] = L('user_does_not_exist') ;
+            $this->sendResult($return);
+            return ;
+        }
+
+        $data['username'] = $member['username'] ;
+        $data['uid'] = $member['uid'] ;
+        
+
+        $id = D("Item")->where(" item_id = '$item_id' ")->save($data);
+
+        $return = D("Item")->where("item_id = '$item_id' ")->find();
+
+        if (!$return) {
+            $return['error_code'] = 10103 ;
+            $return['error_message'] = 'request  fail' ;
+        }
+
+        $this->sendResult($return);
+        
+    }
+
+}

+ 123 - 0
Application/Home/Controller/BaseController.class.php

@@ -0,0 +1,123 @@
+<?php
+namespace Home\Controller;
+use Think\Controller;
+class BaseController extends Controller {
+
+	public function message($msg , $redirect = ''){
+		$this->assign("msg" , $msg);
+		$this->assign("redirect" , $redirect);
+		$this->display ("Common/message");
+	}
+
+	public function checkLogin($redirect = true){
+    	if (strtolower(C("DB_TYPE")) == 'mysql' ) {
+            echo 'ShowDoc does not support mysql any more . https://www.showdoc.cc/help?page_id=31990 ';
+            clear_runtime();
+            exit();
+    	}
+		if ( ! session("login_user")) {
+			$cookie_token = cookie('cookie_token');
+			if ($cookie_token) {
+				$ret = D("UserToken")->getToken($cookie_token);
+				if ($ret && $ret['token_expire'] > time() ) {
+					$login_user = D("User")->where("uid = $ret[uid]")->find();
+					unset($ret['password']);
+					session("login_user" , $login_user);
+					return $login_user ;
+				}
+			}
+			if ($redirect) {
+				$this->message("你尚未登录!",U('Home/User/login'));
+				exit();
+			}
+		}else{
+			return  session("login_user") ;
+		}
+	}
+
+	/**
+	 * 返回json数据
+	 */
+	public function sendResult($array){
+		if (isset($array['error_code'])) {
+			$result['error_code'] = $array['error_code'] ;
+			$result['error_message'] = $array['error_message'] ;
+		}
+		else{
+			$result['error_code'] = 0 ;
+			$result['data'] = $array ;
+		}
+		echo json_encode($result);
+	}
+
+	//判断某用户是否有项目管理权限(项目成员member_group_id为1,以及 项目创建者)
+	protected function checkItemPermn($uid , $item_id){
+
+		if (!$uid) {
+			return false;
+		}
+
+		if (session("mamage_item_".$item_id)) {
+			return true;
+		}
+
+		$item = D("Item")->where("item_id = '%d' ",array($item_id))->find();
+		if ($item['uid'] && $item['uid'] == $uid) {
+			session("mamage_item_".$item_id , 1 );
+			return true;
+		}
+		$ItemMember = D("ItemMember")->where("item_id = '%d' and uid = '%d' and member_group_id = 1 ",array($item_id,$uid))->find();
+		if ($ItemMember) {
+			session("mamage_item_".$item_id , 1 );
+			return true;
+		}
+		return false;
+	}
+
+	//判断某用户是否为项目创建者
+	protected function checkItemCreator($uid , $item_id){
+		if (!$uid) {
+			return false;
+		}
+		if (session("creat_item_".$item_id)) {
+			return true;
+		}
+
+		$item = D("Item")->where("item_id = '%d' ",array($item_id))->find();
+		if ($item['uid'] && $item['uid'] == $uid) {
+			session("creat_item_".$item_id , 1 );
+			return true;
+		}
+		return false;
+	}
+
+	//判断某用户是否有项目访问权限(公开项目的话所有人可访问,私有项目则项目成员、项目创建者和访问密码输入者可访问)
+	protected function checkItemVisit($uid , $item_id, $refer_url= ''){
+		if (session("visit_item_".$item_id)) {
+			return true;
+		}
+
+		if ($this->checkItemCreator($uid , $item_id)) {
+			session("visit_item_".$item_id , 1 );
+			return true;
+		}
+
+		$ItemMember = D("ItemMember")->where("item_id = '%d' and uid = '%d'  ",array($item_id,$uid))->find();
+		if ($ItemMember) {
+			session("visit_item_".$item_id , 1 );
+			return true;
+		}
+
+		$item = D("Item")->where("item_id = '%d' ",array($item_id))->find();
+		if ($item['password']) {
+			//跳转到输入访问密码框
+			header("location:".U("Home/item/pwd",array("item_id"=>$item_id,"refer_url"=>base64_encode($refer_url))));
+		}else{
+			session("visit_item_".$item_id , 1 );
+			return true;
+		}
+
+	}
+
+
+}

+ 34 - 0
Application/Home/Controller/CatalogController.class.php

@@ -0,0 +1,34 @@
+<?php
+namespace Home\Controller;
+use Think\Controller;
+class CatalogController extends BaseController {
+
+    //编辑页面
+    public function edit(){
+
+        $cat_id = I("cat_id/d");
+
+        $Catalog = D("Catalog")->where(" cat_id = '$cat_id' ")->find();
+
+        if ($Catalog) {
+            $this->assign("Catalog" , $Catalog);
+        }
+
+        if ($Catalog['parent_cat_id']) {
+            $this->assign("default_parent_cat_id" , $Catalog['parent_cat_id']);
+        }
+        
+        $item_id = $Catalog['item_id'] ? $Catalog['item_id'] : I("item_id");
+
+        $login_user = $this->checkLogin();
+        if (!$this->checkItemPermn($login_user['uid'] , $item_id)) {
+            $this->message(L('no_permissions'));
+            return;
+        }
+
+        $this->assign("item_id" , $item_id);
+
+        $this->display();        
+    }
+
+}

+ 32 - 0
Application/Home/Controller/CommonController.class.php

@@ -0,0 +1,32 @@
+<?php
+namespace Home\Controller;
+use Think\Controller;
+class CommonController extends BaseController {
+
+
+    //保存
+    public function qrcode(){
+        Vendor('Phpqrcode.phpqrcode');
+        $url = I("url");
+        $url = urldecode($url) ? urldecode($url) : $url;
+        $size = I("size") ? I("size") : 6;
+        $object = new \QRcode();
+        $object->png($url, false, 3 , $size, 2);             
+    }
+
+    public function checkForUpdate(){
+    	$option_data = D("Options")->where("option_name='version' ")->find();
+    	$post_data = array(
+    		"version" => $option_data['option_value'] ,
+    		);
+    	$version = $option_data['option_value'];
+        // TODO 此功能是留着检测更新用的。未完成。代码有空再写吧
+    	//$url = "https://www.showdoc.cc/";
+    	//$result = http_post($url , $post_data);
+    	//$version_num = str_replace("v", '', $num);
+    	//$result = version_compare($version_num, "2.1.5",'<');
+    	//echo $result;
+
+    }
+
+}

+ 35 - 0
Application/Home/Controller/IndexController.class.php

@@ -0,0 +1,35 @@
+<?php
+namespace Home\Controller;
+use Think\Controller;
+class IndexController extends BaseController {
+    public function index(){
+        $tmp = @file_get_contents('./Application/Common/Conf/config.php');
+        if (strstr($tmp, "showdoc not install")) {
+            header("location:./install");
+            exit();
+        }
+
+        //跳转到web目录
+        header("location:./web/#/");
+        exit();
+
+    	$this->checkLogin(false);
+    	$login_user = session("login_user");
+    	$this->assign("login_user" ,$login_user);
+    	if (LANG_SET == 'en-us') {
+    		$demo_url = "https://www.showdoc.cc/demo-en";
+    		$help_url = "https://www.showdoc.cc/help-en";
+    		$creator_url = "https://github.com/star7th";
+    	}
+    	else{
+    		$demo_url = "https://www.showdoc.cc/demo";
+    		$help_url = "https://www.showdoc.cc/help";
+    		$creator_url = "https://blog.star7th.com/";
+    	}
+    	$this->assign("demo_url" ,$demo_url);
+    	$this->assign("help_url" ,$help_url);
+    	$this->assign("creator_url" ,$creator_url);
+
+        $this->display();
+    }
+}

+ 293 - 0
Application/Home/Controller/ItemController.class.php

@@ -0,0 +1,293 @@
+<?php
+namespace Home\Controller;
+use Think\Controller;
+class ItemController extends BaseController {
+    //项目列表页
+    public function index(){
+        $login_user = $this->checkLogin();        
+
+        //跳转到web目录
+        header("location:./web/#/item/index");
+        exit();
+        
+        $share_url = get_domain().__APP__.'/uid/'.$login_user['uid'];
+
+        $this->assign("login_user" , $login_user);
+    	$this->assign("share_url" , $share_url);
+        $this->display();
+    }
+    //我公开的项目列表
+    public function showByUid(){
+        $login_user = $this->checkLogin(false); //如果用户有登录,则赋值给$login_user
+        $uid = I("uid/d");
+        $show_user = D("User")->where(" uid = '$uid' ")->find();
+        if ($show_user) {
+            $items  = D("Item")->where(" password = '' and  ( uid = '$show_user[uid]' or item_id in ( select item_id from ".C('DB_PREFIX')."item_member where uid = '$show_user[uid]' ) ) ")->select();
+            $this->assign("items" , $items);
+            $this->assign("show_user" , $show_user);
+            $this->assign("login_user" , $login_user);
+            
+        }
+        if (LANG_SET == 'en-us') {
+            $help_url = "https://www.showdoc.cc/help-en";
+        }
+        else{
+            $help_url = "https://www.showdoc.cc/help";
+        }
+
+        $this->assign("help_url" , $help_url);
+        $this->display();
+
+    }
+
+    //新建项目
+    public function add(){
+        $login_user = $this->checkLogin();
+        $this->display ();
+    }
+
+    //根据项目类型展示项目
+    public function show(){
+        $this->checkLogin(false);
+        $item_id = I("item_id/d");
+        $item_domain = I("item_domain/s");
+        $current_page_id = I("page_id/d");
+
+        //判断个性域名
+        if ($item_domain) {
+            $item = D("Item")->where("item_domain = '%s'",array($item_domain))->find();
+            if ($item['item_id']) {
+                $item_id = $item['item_id'] ;
+            }
+        }
+
+        //跳转到web目录
+        header("location:./web/#/".$item_id."?page_id=".$current_page_id);
+        exit();
+        
+        
+        $login_user = session("login_user");
+        $uid = $login_user['uid'] ? $login_user['uid'] : 0 ;
+            
+        $this->checkItemVisit($uid , $item_id);
+
+
+        $item = D("Item")->where("item_id = '$item_id' ")->find();
+        if ($item['item_type'] == 1 ) {
+            $this->_show_regular_item($item);
+        }
+        elseif ($item['item_type'] == 2 ) {
+            $this->_show_single_page_item($item);
+        }else{
+           $this->_show_regular_item($item); 
+        }
+        
+
+    }
+
+    //展示常规项目
+    private function _show_regular_item($item){
+        $item_id = $item['item_id'];
+
+        $current_page_id = I("page_id/d");
+        $keyword = I("keyword");
+
+        $login_user = session("login_user");
+        $uid = $login_user['uid'] ? $login_user['uid'] : 0 ;
+            
+        //是否有搜索词
+        if ($keyword) {
+            $keyword = \SQLite3::escapeString($keyword) ;
+            $pages = D("Page")->where("item_id = '$item_id' and ( page_title like '%{$keyword}%' or page_content like '%{$keyword}%' ) ")->order(" `s_number` asc  ")->field("page_id,author_uid,cat_id,page_title,addtime")->select();
+        
+        }else{
+            //获取所有父目录id为0的页面
+            $pages = D("Page")->where("cat_id = '0' and item_id = '$item_id' ")->order(" `s_number` asc  ")->field("page_id,author_uid,cat_id,page_title,addtime")->select();
+            //获取所有二级目录
+            $catalogs = D("Catalog")->where("item_id = '$item_id' and level = 2  ")->order(" `s_number` asc  ")->select();
+            if ($catalogs) {
+                foreach ($catalogs as $key => &$catalog) {
+                    //该二级目录下的所有子页面
+                    $temp = D("Page")->where("cat_id = '$catalog[cat_id]' ")->order(" `s_number` asc  ")->field("page_id,author_uid,cat_id,page_title,addtime")->select();
+                    $catalog['pages'] = $temp ? $temp: array();
+
+                    //该二级目录下的所有子目录
+                    $temp = D("catalog")->where("parent_cat_id = '$catalog[cat_id]' ")->order(" `s_number` asc  ")->select();
+                    $catalog['catalogs'] = $temp ? $temp: array();
+                    if($catalog['catalogs']){
+                        //获取所有三级目录的子页面
+                        foreach ($catalog['catalogs'] as $key3 => &$catalog3) {
+                            //该二级目录下的所有子页面
+                            $temp = D("Page")->where("cat_id = '$catalog3[cat_id]' ")->order(" `s_number` asc  ")->field("page_id,author_uid,cat_id,page_title,addtime")->select();
+                            $catalog3['pages'] = $temp ? $temp: array();
+                        }                        
+                    }               
+                }
+            }
+        }
+
+        $domain = $item['item_domain'] ? $item['item_domain'] : $item['item_id'];
+        $share_url = get_domain().__APP__.'/'.$domain;
+
+        $ItemPermn = $this->checkItemPermn($uid , $item_id) ;
+
+        $ItemCreator = $this->checkItemCreator($uid , $item_id);
+
+        if (LANG_SET == 'en-us') {
+            $help_url = "https://www.showdoc.cc/help-en";
+        }
+        else{
+            $help_url = "https://www.showdoc.cc/help";
+        }
+        
+        $this->assign("help_url" , $help_url);
+        $this->assign("current_page_id" , $current_page_id);
+        $this->assign("keyword" , $keyword);
+        $this->assign("ItemPermn" , $ItemPermn);
+        $this->assign("ItemCreator" , $ItemCreator);
+        $this->assign("share_url" , $share_url);
+        $this->assign("catalogs" , $catalogs);
+        $this->assign("pages" , $pages);
+        $this->assign("item" , $item);
+        $this->assign("login_user" , $login_user);
+        $this->display("show_regular");
+    }
+
+    //展示单页项目
+    private function _show_single_page_item($item){
+        $item_id = $item['item_id'];
+
+        $current_page_id = I("page_id/d");
+
+        $login_user = session("login_user");
+        $uid = $login_user['uid'] ? $login_user['uid'] : 0 ;
+
+        //获取页面
+        $page = D("Page")->where(" item_id = '$item_id' ")->find();
+
+        $domain = $item['item_domain'] ? $item['item_domain'] : $item['item_id'];
+        $share_url = get_domain().__APP__.'/'.$domain;
+
+        $ItemPermn = $this->checkItemPermn($uid , $item_id) ;
+
+        $ItemCreator = $this->checkItemCreator($uid , $item_id);
+
+        $this->assign("current_page_id" , $current_page_id);
+        $this->assign("ItemPermn" , $ItemPermn);
+        $this->assign("ItemCreator" , $ItemCreator);
+        $this->assign("share_url" , $share_url);
+        $this->assign("catalogs" , $catalogs);
+        $this->assign("page" , $page);
+        $this->assign("item" , $item);
+        $this->assign("login_user" , $login_user);
+        $this->display("show_single_page");
+    }
+    //删除项目
+    public function delete(){
+        $item_id =  I("item_id");
+        $login_user = $this->checkLogin();
+        if (!$this->checkItemCreator($login_user['uid'] , $item_id)) {
+            $this->message(L('no_permissions'));
+            return;
+        }
+        $this->assign("item_id" , $item_id);
+        $this->display(); 
+    }
+
+    //删除项目
+    public function ajaxDelete(){
+        $login_user = $this->checkLogin();
+
+        $item_id = I("item_id/d");
+        $password = I("password");
+
+        $item  = D("Item")->where("item_id = '$item_id' ")->find();
+
+        if(! D("User")-> checkLogin($item['username'],$password)){
+            $return['error_code'] = 10102 ;
+            $return['error_message'] = L('incorrect_password') ;
+            $this->sendResult($return);
+            return ;
+        }
+
+
+        D("Page")->where("item_id = '$item_id' ")->delete();
+        D("Catalog")->where("item_id = '$item_id' ")->delete();
+        D("PageHistory")->where("item_id = '$item_id' ")->delete();
+        D("ItemMember")->where("item_id = '$item_id' ")->delete();
+        $return = D("Item")->where("item_id = '$item_id' ")->delete();
+
+        if (!$return) {
+            $return['error_code'] = 10103 ;
+            $return['error_message'] = 'request  fail' ;
+        }
+
+        $this->sendResult($return);
+    }
+
+    //输入访问密码
+    public function pwd(){
+        $item_id = I("item_id/d");
+        $CloseVerify = C('CloseVerify');
+        $refer_url = I('refer_url');
+        //var_dump(urldecode($refer_url));
+        $this->assign('CloseVerify',$CloseVerify);
+        $this->assign('refer_url',$refer_url);
+        if (!IS_POST) {
+          $this->assign("item_id" , $item_id);
+          $this->display ();
+
+        }else{
+          $password = I("password");
+          $v_code = I("v_code");
+          if ( $CloseVerify ||  ( $v_code && $v_code == session('v_code') )) {
+            $item = D("Item")->where("item_id = '$item_id' ")->find();
+            if ($item['password'] == $password) {
+                session("visit_item_".$item_id , 1 );
+                if ($refer_url) {
+                    header("location:".base64_decode($refer_url));
+                }else{
+                    header("location:".U("Home/Item/show").'&item_id='.$item_id);
+                }
+                
+            }else{
+                
+                $this->message(L('access_password_are_incorrect'));
+            }
+
+          }else{
+            $this->message(L('verification_code_are_incorrect'));
+          }
+
+        }
+    }
+
+    //导出word
+    public function export(){
+        $login_user = $this->checkLogin();
+        $item_id = I("item_id/d");  
+        $uid = $login_user['uid'] ;
+        $this->checkItemPermn($uid , $item_id) ; 
+
+        $item = D("Item")->where("item_id = '$item_id' ")->find();
+
+        //对于单页项目,直接导出。对于普通项目,则让其选择目录
+        if ($item['item_type'] == 2 ) {
+            $url = 'server/index.php?s=/api/export/word&item_id='.$item_id ;
+            header("location:{$url}");
+        }else{
+            $this->assign("item_id",$item_id);
+            $this->display();
+        }
+    }
+
+    public function setting(){
+        $login_user = $this->checkLogin();
+        $item_id = I("item_id/d");  
+        $uid = $login_user['uid'] ;
+        $this->checkItemPermn($uid , $item_id) ; 
+        $this->assign("item_id",$item_id);
+        $this->display();
+    }
+
+}

+ 99 - 0
Application/Home/Controller/MemberController.class.php

@@ -0,0 +1,99 @@
+<?php
+namespace Home\Controller;
+use Think\Controller;
+class MemberController extends BaseController {
+
+    //编辑页面
+    public function edit(){
+        $item_id =  I("item_id");
+        $login_user = $this->checkLogin();
+        if (!$this->checkItemCreator($login_user['uid'] , $item_id)) {
+            $this->message(L('no_permissions'));
+            return;
+        }
+        $this->assign("item_id" , $item_id);
+
+        $this->display();        
+    }
+
+    //保存
+    public function save(){
+        $item_id =  I("item_id/d");
+        $member_group_id =  I("member_group_id/d");
+        $login_user = $this->checkLogin();
+        if (!$this->checkItemCreator($login_user['uid'] , $item_id)) {
+            $this->message(L('no_permissions'));
+            return;
+        }
+        $username = I("username");
+        $member = D("User")->where(" username = '%s' ",array($username))->find();
+
+        if (!$member) {
+            $return['error_code'] = 10201 ;
+            $return['error_message'] =L('user_does_not_exist') ;
+            $this->sendResult($return);
+            return ;
+        }
+
+        $data['username'] = $member['username'] ;
+        $data['uid'] = $member['uid'] ;
+        $data['item_id'] = $item_id ;
+        $data['member_group_id'] = $member_group_id ;
+        $data['addtime'] = time() ;
+        
+
+        $id = D("ItemMember")->add($data);
+        $return = D("ItemMember")->where(" item_member_id = '$id' ")->find();
+
+        if (!$return) {
+            $return['error_code'] = 10103 ;
+            $return['error_message'] = 'request  fail' ;
+        }
+
+        $this->sendResult($return);
+        
+    }
+
+    //获取成员列表
+    public function getList(){
+        $item_id = I("item_id/d");
+        if ($item_id > 0 ) {
+            $ret = D("ItemMember")->where(" item_id = '$item_id' ")->order(" addtime asc  ")->select();
+        }
+        if ($ret) {
+           $this->sendResult($ret);
+        }else{
+            $return['error_code'] = 10103 ;
+            $return['error_message'] = 'request  fail' ;
+            $this->sendResult($return);
+        }
+    }
+
+    //删除成员
+    public function delete(){
+        $item_id = I("item_id/d")? I("item_id/d") : 0;
+        $login_user = $this->checkLogin();
+        if (!$this->checkItemCreator($login_user['uid'] , $item_id)) {
+            $this->message(L('no_permissions'));
+            return;
+        }
+        $username = I("username")? I("username") : 0;
+
+        if ($username) {
+            
+            $ret = D("ItemMember")->where(" item_id = '%d' and username = '%s'  ",array($item_id,$username))->delete();
+
+        }
+        if ($ret) {
+           $this->sendResult($ret);
+        }else{
+            $return['error_code'] = 10103 ;
+            $return['error_message'] = 'request  fail' ;
+            $this->sendResult($return);
+        }
+    }
+
+
+
+
+}

+ 188 - 0
Application/Home/Controller/PageController.class.php

@@ -0,0 +1,188 @@
+<?php
+namespace Home\Controller;
+use Think\Controller;
+class PageController extends BaseController {
+
+    //展示某个项目的单个页面
+    public function index(){
+        import("Vendor.Parsedown.Parsedown");
+        $page_id = I("page_id/d");
+        $this->assign("page_id" , $page_id);
+        $this->display();
+    }
+
+    //展示单个页面
+    public function single(){
+        $page_id = I("page_id/d");
+
+        //跳转到web目录
+        header("location:./web/#/page/".$page_id);
+        exit();
+
+        import("Vendor.Parsedown.Parsedown");
+        $page = D("Page")->where(" page_id = '$page_id' ")->find();
+        $login_user = $this->checkLogin(false);
+        if (!$this->checkItemVisit($login_user['uid'] , $page['item_id'],$_SERVER['REQUEST_URI'])) {
+            $this->message(L('no_permissions'));
+            return;
+        }
+
+        $ItemPermn = $this->checkItemPermn($login_user['uid'] , $page['item_id']) ;
+        $ItemCreator = $this->checkItemCreator($login_user['uid'],$page['item_id']);
+
+        $page['page_md_content'] = $page['page_content'];
+        //$page['page_html_content'] = $Parsedown->text(htmlspecialchars_decode($page['page_content']));
+        $this->assign("page" , $page);
+        $this->assign("page_id" , $page_id);
+        $this->assign("login_user" , $login_user);
+        $this->display();
+    }
+
+    //返回单个页面的源markdown代码
+    public function md(){
+        $page_id = I("page_id/d");
+        $page = D("Page")->where(" page_id = '$page_id' ")->find();
+        echo $page['page_content'];
+    }
+
+    //编辑页面
+    public function edit(){
+        $login_user = $this->checkLogin();
+        $page_id = I("page_id/d");
+        $item_id = I("item_id/d");
+
+        $page_history_id = I("page_history_id/d");
+        $copy_page_id = I("copy_page_id/d");
+
+        if ($page_id > 0 ) {
+            if ($page_history_id) {
+                $page = D("PageHistory")->where(" page_history_id = '$page_history_id' ")->find();
+                $page_content = gzuncompress(base64_decode($page['page_content'])); 
+                $page['page_content'] = $page_content ? $page_content : $page['page_content'] ;
+            }else{
+                $page = D("Page")->where(" page_id = '$page_id' ")->find();
+            }
+            $default_cat_id = $page['cat_id'];
+        }
+        //如果是复制接口
+        elseif ($copy_page_id) {
+            $copy_page = D("Page")->where(" page_id = '$copy_page_id' ")->find();
+            $page['page_title'] = $copy_page['page_title']."-copy";
+            $page['page_content'] = $copy_page['page_content'];
+            $page['item_id'] = $copy_page['item_id'];
+            $default_cat_id = $copy_page['cat_id'];
+
+        }else{
+            //查找用户上一次设置的目录
+            $last_page = D("Page")->where(" author_uid ='$login_user[uid]' and $item_id = '$item_id' ")->order(" addtime desc ")->limit(1)->find();
+            $default_cat_id = $last_page['cat_id'];
+
+
+        }
+
+        $item_id = $page['item_id'] ?$page['item_id'] :$item_id;
+
+        
+        if (!$this->checkItemPermn($login_user['uid'] , $item_id)) {
+            $this->message(L('no_permissions'));
+            return;
+        }
+
+        $Catalog = D("Catalog")->where(" cat_id = '$default_cat_id' ")->find();
+        if ($Catalog['parent_cat_id']) {
+            $default_second_cat_id = $Catalog['parent_cat_id'];
+            $default_child_cat_id = $default_cat_id;
+
+        }else{
+            $default_second_cat_id = $default_cat_id;
+        }
+        $this->assign("api_doc_templ" , 'MdTemplate/api-doc.'.LANG_SET);
+        $this->assign("database_doc_templ" , 'MdTemplate/database.'.LANG_SET);
+        $this->assign("page" , $page);
+        $this->assign("item_id" , $item_id);
+        $this->assign("default_second_cat_id" , $default_second_cat_id);
+        $this->assign("default_child_cat_id" , $default_child_cat_id);
+
+
+        $this->display();        
+    }
+
+
+    //历史版本
+    public function history(){
+        $page_id = I("page_id/d") ? I("page_id/d") : 0 ;
+        $this->assign("page_id" , $page_id);
+
+        $PageHistory = D("PageHistory")->where("page_id = '$page_id' ")->order(" addtime desc")->limit(10)->select();
+
+        if ($PageHistory) {
+            foreach ($PageHistory as $key => &$value) {
+                $page_content = gzuncompress(base64_decode($value['page_content'])); 
+                $value['page_content'] = $page_content ? $page_content : $value['page_content'] ;
+                $value['addtime'] = date("Y-m-d H:i:s" , $value['addtime']);
+            }
+        }
+
+        $this->assign("PageHistory" , $PageHistory);
+
+        $this->display();        
+
+    }
+
+    //上传图片
+    public function uploadImg(){
+        $qiniu_config = C('UPLOAD_SITEIMG_QINIU') ;
+        if ($_FILES['editormd-image-file']['name'] == 'blob') {
+            $_FILES['editormd-image-file']['name'] .= '.jpg';
+        }
+        if (strstr(strtolower($_FILES['editormd-image-file']['name']), ".php") ) {
+            return false;
+        }
+        if (!empty($qiniu_config['driverConfig']['secrectKey'])) {
+          //上传到七牛
+          $Upload = new \Think\Upload(C('UPLOAD_SITEIMG_QINIU'));
+          $info = $Upload->upload($_FILES);
+          $url = $info['editormd-image-file']['url'] ;
+          echo json_encode(array("url"=>$url,"success"=>1));
+        }else{
+            $upload = new \Think\Upload();// 实例化上传类
+            $upload->maxSize  = 3145728 ;// 设置附件上传大小
+            $upload->allowExts  = array('jpg', 'gif', 'png', 'jpeg');// 设置附件上传类型
+            $upload->rootPath = './Public/Uploads/';// 设置附件上传目录
+            $upload->savePath = '';// 设置附件上传子目录
+            $info = $upload->upload() ;
+            if(!$info) {// 上传错误提示错误信息
+              $this->error($upload->getError());
+              return;
+            }else{// 上传成功 获取上传文件信息
+              $url = get_domain().__ROOT__.substr($upload->rootPath,1).$info['editormd-image-file']['savepath'].$info['editormd-image-file']['savename'] ;
+              echo json_encode(array("url"=>$url,"success"=>1));
+            }
+        }
+
+    }
+
+    public function diff(){
+        $login_user = $this->checkLogin();
+        $page_history_id = I("page_history_id/d");
+        $page_id = I("page_id/d");
+
+        $page = D("Page")->where(" page_id = '$page_id' ")->find();
+        $cur_page_content = $page['page_content'];
+
+        $item_id = $page['item_id'] ?$page['item_id'] :$item_id;
+
+        if (!$this->checkItemPermn($login_user['uid'] , $item_id)) {
+            $this->message(L('no_permissions'));
+            return;
+        }
+
+        $page = D("PageHistory")->where(" page_history_id = '$page_history_id' ")->find();
+        $page_content = gzuncompress(base64_decode($page['page_content'])); 
+        $history_page_content = $page_content ? $page_content : $page['page_content'] ;
+        
+        $this->assign("cur_page_content" , $cur_page_content);
+        $this->assign("history_page_content" , $history_page_content);
+        $this->display(); 
+    }
+}

+ 71 - 0
Application/Home/Controller/TemplateController.class.php

@@ -0,0 +1,71 @@
+<?php
+namespace Home\Controller;
+use Think\Controller;
+class TemplateController extends BaseController {
+
+
+    //保存
+    public function save(){
+        $login_user = $this->checkLogin();
+
+        $template_title = I("template_title");
+        $template_content = I("template_content");
+
+        $data['username'] = $login_user['username'] ;
+        $data['uid'] = $login_user['uid'] ;
+        $data['template_title'] = $template_title ;
+        $data['template_content'] = $template_content ;
+        $data['addtime'] = time() ;
+        
+
+        $id = D("Template")->add($data);
+        $return = D("Template")->where(" id = '$id' ")->find();
+
+        if (!$return) {
+            $return['error_code'] = 10103 ;
+            $return['error_message'] = 'request  fail' ;
+        }
+
+        $this->sendResult($return);
+        
+    }
+
+    //获取我的模板列表
+    public function getList(){
+        $login_user = $this->checkLogin();
+        if ($login_user['uid'] > 0 ) {
+            $ret = D("Template")->where(" uid = '$login_user[uid]' ")->order(" addtime desc  ")->select();
+        }
+        if ($ret) {
+            foreach ($ret as $key => &$value) {
+                $value['addtime'] = date("Y-m-d H:i:s" , $value['addtime']);
+                $value['template_content'] = htmlspecialchars_decode($value['template_content']);
+            }
+           $this->sendResult($ret);
+        }else{
+            $return['error_code'] = 10103 ;
+            $return['error_message'] = 'request  fail' ;
+            $this->sendResult($return);
+        }
+    }
+
+    //删除目录
+    public function delete(){
+        $id = I("id/d")? I("id/d") : 0;
+        $login_user = $this->checkLogin();
+        if ($id && $login_user['uid']) {
+            $ret = D("Template")->where(" id = '$id' and uid = '$login_user[uid]'")->delete();
+        }
+        if ($ret) {
+           $this->sendResult($ret);
+        }else{
+            $return['error_code'] = 10103 ;
+            $return['error_message'] = 'request  fail' ;
+            $this->sendResult($return);
+        }
+    }
+
+
+
+
+}

+ 495 - 0
Application/Home/Controller/UpdateController.class.php

@@ -0,0 +1,495 @@
+<?php
+namespace Home\Controller;
+use Think\Controller;
+class UpdateController extends BaseController {
+    
+ 	//升级数据库
+    public function db(){
+        $this->_clear_runtime();
+    	if (strtolower(C("DB_TYPE")) == 'mysql' ) {
+    		//$this->mysql();
+            echo 'ShowDoc does not support mysql any more . https://www.showdoc.cc/help?page_id=31990 ';
+    	}
+        elseif (strtolower(C("DB_TYPE")) == 'sqlite' ) {
+            $this->sqlite();
+        }
+    	$this->_clear_runtime();
+    }
+    public function sqlite(){
+        //catalog表增加parent_cat_id字段
+        $columns = M("catalog")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'parent_cat_id') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."catalog ADD parent_cat_id INT( 10 ) NOT NULL DEFAULT '0' ;";
+                D("catalog")->execute($sql);
+            }
+        }
+
+        //catalog表增加level字段
+        $columns = M("catalog")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'level') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."catalog ADD level INT( 10 ) NOT NULL DEFAULT '2'  ;";
+                D("catalog")->execute($sql);
+            }
+        }
+
+        //item表增加item_domain字段
+        $columns = M("item")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'item_domain') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."item ADD item_domain text NOT NULL DEFAULT '';";
+                D("item")->execute($sql);
+            }
+        }
+        //创建user_token表
+        $sql = "CREATE TABLE IF NOT EXISTS `user_token` (
+        `id`  INTEGER PRIMARY KEY ,
+        `uid` int(10) NOT NULL DEFAULT '0',
+        `token` CHAR(200) NOT NULL DEFAULT '',
+        `token_expire` int(11) NOT NULL DEFAULT '0' ,
+        `ip` CHAR(200) NOT NULL DEFAULT '',
+        `addtime` int(11) NOT NULL DEFAULT '0'
+        )";
+        D("UserToken")->execute($sql);
+
+        //创建template表
+        $sql = "CREATE TABLE IF NOT EXISTS `template` (
+        `id`  INTEGER PRIMARY KEY ,
+        `uid` int(10) NOT NULL DEFAULT '0',
+        `username` CHAR(200) NOT NULL DEFAULT '',
+        `template_title` CHAR(200) NOT NULL DEFAULT '' ,
+        `template_content` text NOT NULL DEFAULT '',
+        `addtime` int(11) NOT NULL DEFAULT '0'
+        )";
+        D("UserToken")->execute($sql);
+
+        //page表增加page_comments字段
+        $columns = D("Page")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'page_comments') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."page ADD page_comments text NOT NULL DEFAULT ''  ;";
+                D("Page")->execute($sql);
+            }
+        }
+
+        //page_history 表增加page_comments字段
+        $columns = D("PageHistory")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'page_comments') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."page_history ADD page_comments text NOT NULL DEFAULT '';";
+                D("PageHistory")->execute($sql);
+            }
+        }
+
+        //item_member表增加member_group_id字段
+        $columns = M("ItemMember")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'member_group_id') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."item_member ADD member_group_id INT( 1 ) NOT NULL DEFAULT '1'  ;";
+                D("ItemMember")->execute($sql);
+            }
+        }
+
+        //item表增加item_type字段
+        $columns = M("Item")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'item_type') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."item ADD item_type INT( 1 ) NOT NULL DEFAULT '1'  ;";
+                D("Item")->execute($sql);
+            }
+        }
+
+        //创建options表
+        $sql = "CREATE TABLE IF NOT EXISTS `options` (
+        `option_id`  INTEGER PRIMARY KEY ,
+        `option_name` CHAR(200) NOT NULL UNIQUE ,
+        `option_value` CHAR(200) NOT NULL 
+        )";
+        D("UserToken")->execute($sql);
+
+        //创建item_token表
+        $sql = "CREATE TABLE IF NOT EXISTS `item_token` (
+        `id`  INTEGER PRIMARY KEY ,
+        `item_id` int(11) NOT NULL DEFAULT '0' ,
+        `api_key` CHAR(200) NOT NULL UNIQUE ,
+        `api_token` CHAR(200) NOT NULL ,
+        `addtime` int(11) NOT NULL DEFAULT '0' ,
+        `last_check_time` int(11) NOT NULL DEFAULT '0' 
+        )";
+        D("UserToken")->execute($sql);
+
+        //创建item_top表
+        $sql = "CREATE TABLE IF NOT EXISTS `item_top` (
+        `id`  INTEGER PRIMARY KEY ,
+        `item_id` int(11) NOT NULL DEFAULT '0' ,
+        `uid` int(11) NOT NULL DEFAULT '0' ,
+        `addtime` int(11) NOT NULL DEFAULT '0' 
+        )";
+        D("UserToken")->execute($sql);
+
+        //item表增加is_archived字段
+        $columns = M("Item")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'is_archived') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."item ADD is_archived INT( 1 ) NOT NULL DEFAULT '0'  ;";
+                D("Item")->execute($sql);
+            }
+        }
+
+
+        echo 'OK!';
+    }
+
+    private function _clear_runtime($path = RUNTIME_PATH){  
+        //给定的目录不是一个文件夹  
+        if(!is_dir($path)){  
+            return null;  
+        }  
+      
+        $fh = opendir($path);  
+        while(($row = readdir($fh)) !== false){  
+            //过滤掉虚拟目录  
+            if($row == '.' || $row == '..'|| $row == 'index.html'){  
+                continue;  
+            }  
+      
+            if(!is_dir($path.'/'.$row)){
+                unlink($path.'/'.$row);  
+            }  
+            $this->_clear_runtime($path.'/'.$row);  
+              
+        }  
+        //关闭目录句柄,否则出Permission denied  
+        closedir($fh);    
+        return true;  
+    }
+
+    //转移mysql的数据到sqlite
+    public function toSqlite(){
+        $this->_clear_runtime();
+        if (strtolower(C("DB_TYPE")) == 'mysql' ) {
+            $this->mysql();
+            $this->_moveTable("catalog");
+            $this->_moveTable("item");
+            $this->_moveTable("item_member");
+            $this->_moveTable("page");
+            $this->_moveTable("page_history");
+            $this->_moveTable("template");
+            $this->_moveTable("user");
+            $this->_moveTable("user_token");
+            $db_config = array(
+                'DB_TYPE'   => 'Sqlite', 
+                'DB_NAME'   => 'Sqlite/showdoc.db.php', 
+                );
+            $array = M("item")->db(2,$db_config)->select();
+            if ($array) {
+                echo "ok";
+            }else{
+                echo 'fail';
+            }
+            
+        }
+        else{
+            echo "mysql not found";
+        }
+        $this->_clear_runtime();
+    }
+
+    //升级mysql数据库  
+    public function mysql(){
+
+        //user表的username字段增大了长度,防止长邮箱的用户名注册不了
+        $sql = "alter table ".C('DB_PREFIX')."user modify column username varchar(50) CHARACTER SET utf8 NOT NULL DEFAULT '' ";
+        M("Catalog")->execute($sql);
+
+        //item表增加last_update_time字段
+        $columns = M("item")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'last_update_time') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."item ADD last_update_time INT( 11 ) NOT NULL DEFAULT '0' COMMENT '最后更新时间';";
+                D("Item")->execute($sql);
+            }
+        }
+        
+
+        //更改catalog表的order字段名为s_number
+        $columns = M("Catalog")->getDbFields();
+        if ($columns) {
+            foreach ($columns as $key => $value) {
+                if ($value == 'order') {
+                    $sql = "ALTER TABLE  `".C('DB_PREFIX')."catalog` CHANGE  `order`  `s_number` INT( 10 ) NOT NULL DEFAULT  '99' COMMENT  '顺序号。数字越小越靠前。若此值全部相等时则按id排序';";
+                    M("Catalog")->execute($sql);
+                }
+            }
+        }
+
+        //更改page表的order字段名为s_number
+        $columns = M("Page")->getDbFields();
+        if ($columns) {
+            foreach ($columns as $key => $value) {
+                if ($value == 'order') {
+                    $sql = "ALTER TABLE  `".C('DB_PREFIX')."page` CHANGE  `order`  `s_number` INT( 10 ) NOT NULL DEFAULT  '99' COMMENT  '顺序号。数字越小越靠前。若此值全部相等时则按id排序';";
+                    M("Page")->execute($sql);
+                }
+            }
+        }
+
+        //更改page_history表的order字段名为s_number
+        $columns = M("PageHistory")->getDbFields();
+        if ($columns) {
+            foreach ($columns as $key => $value) {
+                if ($value == 'order') {
+                    $sql = "ALTER TABLE  `".C('DB_PREFIX')."page_history` CHANGE  `order`  `s_number` INT( 10 ) NOT NULL DEFAULT  '99' COMMENT  '顺序号。数字越小越靠前。若此值全部相等时则按id排序';";
+                    M("PageHistory")->execute($sql);
+                }
+            }
+        }
+
+        //为catalog表增加addtime索引
+        $indexs = M("Catalog")->query(" show index from ".C('DB_PREFIX')."catalog");
+        if ($indexs) {
+            $has_it = 0 ;//是否存在该索引
+            foreach ($indexs as $key => $value) {
+                if ($value['column_name'] =='addtime') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0 ) {
+                M("Catalog")->execute("ALTER TABLE ".C('DB_PREFIX')."catalog ADD INDEX ( `addtime` ) ;");
+            }
+        }
+
+        //为item表增加addtime索引
+        $indexs = M("Item")->query(" show index from ".C('DB_PREFIX')."item");
+        if ($indexs) {
+            $has_it = 0 ;//是否存在该索引
+            foreach ($indexs as $key => $value) {
+                if ($value['column_name'] =='addtime') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0 ) {
+                M("Item")->execute("ALTER TABLE ".C('DB_PREFIX')."item ADD INDEX ( `addtime` ) ;");
+            }
+        }
+
+        //为page表增加addtime索引
+        $indexs = M("Page")->query(" show index from ".C('DB_PREFIX')."page");
+        if ($indexs) {
+            $has_it = 0 ;//是否存在该索引
+            foreach ($indexs as $key => $value) {
+                if ($value['column_name'] =='addtime') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0 ) {
+                M("page")->execute("ALTER TABLE ".C('DB_PREFIX')."page ADD INDEX ( `addtime` ) ;");
+            }
+        }
+
+        //为page_history表增加addtime索引
+        $indexs = M("PageHistory")->query(" show index from ".C('DB_PREFIX')."page_history");
+        if ($indexs) {
+            $has_it = 0 ;//是否存在该索引
+            foreach ($indexs as $key => $value) {
+                if ($value['column_name'] =='addtime') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0 ) {
+                M("PageHistory")->execute("ALTER TABLE ".C('DB_PREFIX')."page_history ADD INDEX ( `addtime` ) ;");
+            }
+        }
+
+        //为page_history表增加page_id索引
+        $indexs = M("PageHistory")->query(" show index from ".C('DB_PREFIX')."page_history");
+        if ($indexs) {
+            $has_it = 0 ;//是否存在该索引
+            foreach ($indexs as $key => $value) {
+                if ($value['column_name'] =='page_id') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0 ) {
+                M("PageHistory")->execute("ALTER TABLE ".C('DB_PREFIX')."page_history ADD INDEX ( `page_id` ) ;");
+            }
+        }
+
+
+        //catalog表增加parent_cat_id字段
+        $columns = M("catalog")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'parent_cat_id') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."catalog ADD parent_cat_id INT( 10 ) NOT NULL DEFAULT '0' COMMENT '上一级目录的id';";
+                D("catalog")->execute($sql);
+            }
+        }
+
+        //catalog表增加level字段
+        $columns = M("catalog")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'level') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."catalog ADD level INT( 10 ) NOT NULL DEFAULT '2' COMMENT '2为二级目录,3为三级目录';";
+                D("catalog")->execute($sql);
+            }
+        }
+        //item表增加item_domain字段
+        $columns = M("item")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'item_domain') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."item ADD item_domain varchar( 50 ) NOT NULL DEFAULT '' COMMENT 'item的个性域名';";
+                D("item")->execute($sql);
+            }
+        }
+
+        $sql = "CREATE TABLE IF NOT EXISTS `".C('DB_PREFIX')."user_token` (
+        `id` int(10) NOT NULL AUTO_INCREMENT,
+        `uid` int(10) NOT NULL DEFAULT '0',
+        `token` varchar(200) NOT NULL DEFAULT '',
+        `token_expire` int(11) NOT NULL DEFAULT '0' ,
+        `ip` varchar(200) NOT NULL DEFAULT '',
+        `addtime` int(11) NOT NULL DEFAULT '0',
+        PRIMARY KEY (`id`),
+        KEY `token` (`token`)
+        ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COMMENT='' AUTO_INCREMENT=1 ";
+        D("User")->execute($sql);
+
+        //创建template表
+        $sql = "CREATE TABLE IF NOT EXISTS `".C('DB_PREFIX')."template` (
+        `id` int(10) NOT NULL AUTO_INCREMENT,
+        `uid` int(10) NOT NULL DEFAULT '0',
+        `username` varchar(200) NOT NULL DEFAULT '',
+        `template_title` varchar(200) NOT NULL DEFAULT '' ,
+        `template_content` text NOT NULL ,
+        `addtime` int(11) NOT NULL DEFAULT '0',
+        PRIMARY KEY (`id`),
+        KEY `uid` (`uid`)
+        )ENGINE=MyISAM  DEFAULT CHARSET=utf8 COMMENT='' AUTO_INCREMENT=1";
+        D("UserToken")->execute($sql);
+
+        //page表增加page_comments字段
+        $columns = M("Page")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'page_comments') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."page ADD page_comments varchar( 255 ) NOT NULL DEFAULT '' COMMENT '页面注释';";
+                D("Page")->execute($sql);
+            }
+        }
+        //page_history表增加page_comments字段
+        $columns = M("PageHistory")->getDbFields();
+        if ($columns) {
+            $has_it = 0 ;//是否存在该字段
+            foreach ($columns as $key => $value) {
+                if ($value == 'page_comments') {
+                    $has_it = 1 ;
+                }
+            }
+            if ($has_it === 0) {
+                $sql = "ALTER TABLE ".C('DB_PREFIX')."page_history ADD page_comments varchar( 255 ) NOT NULL DEFAULT '' COMMENT '页面注释';";
+                D("PageHistory")->execute($sql);
+            }
+        }
+
+        if(D("User")->where("uid = 1 ")->find()){
+        $db_config = array(
+            'DB_TYPE'   => 'Sqlite', 
+            'DB_NAME'   => 'Sqlite/showdoc.db.php', 
+            );
+            M("User")->db(2,$db_config)->where("uid = 1 ")->delete();    
+        }
+    }
+
+    private function _moveTable($table){
+        $db_config = array(
+            'DB_TYPE'   => 'Sqlite', 
+            'DB_NAME'   => 'Sqlite/showdoc.db.php', 
+            );
+        $array = M($table)->select();
+        if ($array) {
+            foreach ($array as $key => $value) {
+               M($table)->db(2,$db_config)->add($value);
+            }
+        }
+    }
+
+
+}

+ 176 - 0
Application/Home/Controller/UserController.class.php

@@ -0,0 +1,176 @@
+<?php
+namespace Home\Controller;
+use Think\Controller;
+class UserController extends BaseController {
+
+
+	//注册
+	public function register(){
+
+        //跳转到web目录
+        header("location:./web/#/user/register");
+        exit();
+
+		if (!IS_POST) {
+			  $this->assign('CloseVerify',C('CloseVerify'));
+			  $this->display ();
+			}else{
+			  $username = I("username");
+			  $password = I("password");
+			  $confirm_password = I("confirm_password");
+			  $v_code = I("v_code");
+			  if (C('CloseVerify') || $v_code && $v_code == session('v_code') ) {
+		  		if ( $password != '' && $password == $confirm_password) {
+
+			  		if ( ! D("User")->isExist($username) ) {
+						$ret = D("User")->register($username,$password);
+						if ($ret) {
+					      $this->message(L('register_succeeded'),U('Home/User/login'));					    
+						}else{
+						  $this->message('register fail');
+						}
+			  		}else{
+			  			$this->message(L('username_exists'));
+			  		}
+
+			  	}else{
+			  		$this->message(L('code_much_the_same'));
+			  	}
+			  }else{
+				    $this->message(L('verification_code_are_incorrect'));
+			  }
+			  
+
+			}
+	}
+
+
+
+	//登录
+	public function login()
+	{
+
+        //跳转到web目录
+        header("location:./web/#/user/login");
+        exit();
+        
+
+		if (!IS_POST) {
+			//如果有cookie记录,则自动登录
+			$cookie_token = cookie('cookie_token');
+			if ($cookie_token) {
+				$ret = D("UserToken")->getToken($cookie_token);
+				if ($ret && $ret['token_expire'] > time() ) {
+					D("User")->setLastTime($ret['uid']);
+					$login_user = D("User")->where(array('uid' => $ret['uid']))->field('password', true)->find();
+					session("login_user" , $login_user);
+					$this->message(L('auto_login_succeeded'),U('Home/Item/index'));
+					exit();
+				}
+			}
+			$this->assign('CloseVerify',C('CloseVerify'));
+		  	$this->display ();
+
+		}else{
+		  $username = I("username");
+		  $password = I("password");
+		  $v_code = I("v_code");
+		  if (C('CloseVerify')) { //如果关闭验证码
+		  	$ret = D("User")->checkLogin($username,$password);
+		    if ($ret) {
+		      session("login_user" , $ret );
+		      D("User")->setLastTime($ret['uid']);
+		      $token = D("UserToken")->createToken($ret['uid']);
+	          cookie('cookie_token',$token,60*60*24*90);//此处由服务端控制token是否过期,所以cookies过期时间设置多久都无所谓
+		      unset($ret['password']);
+	          $this->message(L('login_succeeded'),U('Home/Item/index'));		        
+		    }else{
+		      $this->message(L('username_or_password_incorrect'));
+		    }
+		  }else{
+			  if ($v_code && $v_code == session('v_code')) {
+			    $ret = D("User")->checkLogin($username,$password);
+			    if ($ret) {
+			      session("login_user" , $ret );
+			  D("User")->setLastTime($ret['uid']);
+		      	  $token = D("UserToken")->createToken($ret['uid']);
+          		  cookie('cookie_token',$token,60*60*24*90);//此处由服务端控制token是否过期,所以cookies过期时间设置多久都无所谓
+			      unset($ret['password']);
+
+		          $this->message(L('login_succeeded'),U('Home/Item/index'));		        
+			    }else{
+			      $this->message(L('username_or_password_incorrect'));
+			    }
+
+			  }else{
+			    $this->message(L('verification_code_are_incorrect'));
+			  }	
+		  }
+		  
+
+		}
+	}
+
+	//生成验证码
+	public function verify(){
+	  //生成验证码图片
+	  Header("Content-type: image/PNG");
+	  $im = imagecreate(44,18); // 画一张指定宽高的图片
+	  $back = ImageColorAllocate($im, 245,245,245); // 定义背景颜色
+	  imagefill($im,0,0,$back); //把背景颜色填充到刚刚画出来的图片中
+	  $vcodes = "";
+	  srand((double)microtime()*1000000);
+	  //生成4位数字
+	  for($i=0;$i<4;$i++){
+	  $font = ImageColorAllocate($im, rand(100,255),rand(0,100),rand(100,255)); // 生成随机颜色
+	  $authnum=rand(1,9);
+	  $vcodes.=$authnum;
+	  imagestring($im, 5, 2+$i*10, 1, $authnum, $font);
+	  }
+	  $_SESSION['v_code'] = $vcodes;
+
+	  for($i=0;$i<200;$i++) //加入干扰象素
+	  {
+	    $randcolor = ImageColorallocate($im,rand(0,255),rand(0,255),rand(0,255));
+	    imagesetpixel($im, rand()%70 , rand()%30 , $randcolor); // 画像素点函数
+	  }
+	  ImagePNG($im);
+	  ImageDestroy($im);
+	}
+
+	public function setting(){
+		$user = $this->checkLogin();
+		if (!IS_POST) {
+		  $this->assign("user",$user);
+		  $this->display ();
+
+		}else{
+			$username = $user['username'];
+			$password = I("password");
+			$new_password = I("new_password");
+			$ret = D("User")->checkLogin($username,$password);
+			if ($ret) {
+					$ret = D("User")->updatePwd($user['uid'],$new_password);
+					if ($ret) {
+						$this->message(L('modify_succeeded'),U("Home/Item/index"));
+					}else{
+						$this->message(L('modify_faild'));
+
+					}
+
+				}else{	
+					$this->message(L('old_password_incorrect'));
+				}
+
+		}
+	}
+
+	//退出登录
+	public function exist(){
+		$login_user = $this->checkLogin();
+		session("login_user" , NULL);
+		cookie('cookie_token',NULL);
+		session(null);
+		$this->message(L('logout_succeeded'),U('Home/index/index'));
+	}
+}

+ 1 - 0
Application/Home/Controller/index.html

@@ -0,0 +1 @@
+ 

+ 216 - 0
Application/Home/Lang/en-us.php

@@ -0,0 +1,216 @@
+<?php
+return array(
+
+    //Attorn
+    'attorn_item'=>'Attorn item',
+    'username'=>'Username',
+    'receiver_name'=>"Receiver's username",
+    'verify_identity'=>'Verify identity',
+    'your_password'=>'Your password',
+    'attorn'=>'Attorn',
+    'close'=>'close',
+
+    //Catalog
+    'new_or_edit_catalog' => 'New/Edit catalog',
+    'catalog_name' => 'Catalog name',
+    's_number' => 'Order',
+    's_number_explain' => 'Optional: order number',
+    'last_catalog' => 'Parent catalog',
+    'save' => 'Sava',
+    'delete_catalog' => 'Delete catalog',
+    'catalog_list' => 'Catalog list',
+    'click_to_edit' => 'Click to edit',
+
+
+    //index
+    'help' => 'Help',
+    'demo' => 'Demo',
+    'index_login_or_register' => 'Login / Register',
+    'my_item' => 'My items',
+    'section_title1' => 'ShowDoc',
+    'section_description1' => ' A tool greatly applicable for an IT team',
+    'section_title2' => 'API Document',
+    'section_description2' => 'ShowDoc can compile exquisite API documents <br>in a very fast and convenient way',
+    'section_title3' => 'Data Dictionary',
+    'section_description3' => 'A good Data Dictionary can easily exhibit database structure to other people<br>ShowDoc can compile exquisite Data Dictionary',
+    'section_title4' => 'Explanation Document',
+    'section_description4' => 'You can absolutely use ShowDoc to compile the explanation documents for some tools',
+    'section_title5' => 'Team Work',
+    'section_description5' => 'Your team will work with ShowDoc together very well ',
+    'section_title6' => 'Open Source',
+    'section_description6' => 'ShowDoc is a free, open source tool that <br>you can deploy it to your own server',
+    'section_title7' => 'Hosted online',
+    'section_description7' => 'Www.showdoc.cc provide security and stability of the document hosting service',
+    'section_title8' => 'Try it now',
+    'section_description8' => 'Over 6000+ IT team is using ShowDoc',
+
+
+    //Common message
+    'redirect_message' => 'If your browser does not automatically jump, please click on this link.',
+    'click_to_goback' => 'Click to goback',
+    'home' => 'Home',
+    
+
+    //item/add
+    'item_name' => "Item's name",
+    'item_description' => "Item's description",
+    'item_domain' => '(Optional)domain hack',
+    'item_domain_illegal' => 'Domain hack must be a combination of letters and numbers',
+    'domain_already_exists' => 'Domain already exists',
+    'visit_password_placeholder' => 'Access password(Optional: private project required)',
+    'submit' => 'Submit',
+    'goback' => 'Goback',
+    //item/delete
+    'delete_item' => 'Delete item',
+    'verify_your_identity' => 'Verify your identity',
+    'creator_password' => "creator's password",
+    'delete' => 'Delete',
+    'close' => 'Close',
+    //item/index
+    'personal_setting'=>'Personal setting',
+    'share_home'=>'Share home',
+    'web_home'=>'Website home',
+    'logout'=>'Logout',
+    'add_an_item'=>'Add an item',
+    'new_item'=>'New item',
+    'share_my_home'=>'Share my home',
+    'feedback' => "feedback",
+    'home_address'=>'Home address',
+    'home_address_description'=>'The others will be able to see all of your public items When he visits your home page.You can copy the address to your friends.',
+    //item/pwd
+    'input_visit_password'=>'Please enter the access password',
+    'password'=>'Passwod',
+    'verification_code'=>'Verification code',
+    'submit'=>'Submit',
+    'login_or_register'=>'Login/Register',
+    //item/show
+    'item'=>'Item',
+    'share'=>'Share',
+    'export'=>'Export',
+    'update_info'=>'Modify',
+    'manage_members'=>'Members',
+    'attorn'=>'Attorn',
+    'delete'=>'Delete',
+    'more_item'=>'More items',
+    'login_or_register'=>'Login/Register',
+    'about_showdoc'=>'About ShowDoc',
+    'my_item'=>'My items',
+    'new_page'=>'New page',
+    'new_catalog'=>'New catalog',
+    'share_address_to_your_friends'=>'Share address to your friends',
+    'share'=>'Share',
+    'copy_interface_to_new'=>'Copy page  to new ',
+    'copy'=>'Copy',
+    'edit_interface'=>'Edit page',
+    'edit'=>'Edit',
+    'delete_interface'=>'Delete page',
+    'comfirm_delete'=>'Are you sure that you want to delete it?',
+    'delete'=>'Delete',
+    'share'=>'Share',
+    'item_address'=>'Item address',
+    'copy_address_to_your_friends'=>'You can copy the address to your friend.',
+    'share_page'=>'Share page',
+    'page_address'=>'Page address',
+    'copy_address_to_your_friends'=>'You can copy the address to your friend.',
+    //item/showbyuid
+    'more'=>'More',
+    'my_item'=>'My items',
+    'login_or_register'=>'Login/Register',
+    'about_showdoc'=>'About ShowDoc',
+    'all_pubilc_item'=>"'s all public items",
+
+    //member
+    'new_member'=>'New member',
+    'username'=>'Username',
+    'save'=>'Save',
+    'member_list'=>'member list',
+    'click_to_delete'=>'Click to delete',
+    'close'=>'Close',
+    "member_group_id" => "Read-only(can read item ,but not edit or delete )",
+    //page
+    'input_page_title'=>'Please enter a page title',
+    'level_2_directory'=>'Second-level catalog',
+    'level_3_directory'=>'Third-level catalog',
+    's_number_explain'=>'Optional: order number',
+    'history_version'=>'History version',
+    'save'=>'Save',
+    'cancel'=>'Cancel',
+    'inser_apidoc_template'=>'Insert apidoc template',
+    'inser_database_doc_template'=>'Insert db-doc template',
+    'json_tools'=>'Json tools',
+    'json_to_table'=>'Json to table',
+    'beautify_json'=>'Beautify Json',
+    'beautify_json_description'=>'Make your json more beautiful ',
+    'http_test_api'=>'Api test online',
+    'json_to_table_description'=>'Please paste a section of JSON, the program will automatically parse and generate JSON parameters table. This feature is suitable for the rapid preparation of API documents returned to the parameter table',
+    'confirm'=>'Confirm',
+    'cancel'=>'Cancel',
+    'history_version'=>'History version',
+    'update_time'=>'Modification time',
+    'update_by_who'=>'Modified by who',
+    'operation'=>'Operation',
+    'recover_to_this_version'=>'Restore to this version',
+    'close'=>'Close',
+    'finish'=>'Finish',
+    'api_test_title'=>'Test for GET and POST',
+    'api_address_description'=>'Api address(e.g:ttp://www.abc.com/api/login)',
+    'api_address'=>'Api address',
+    'params_description'=>'Params(e.g:user_id=121&age=22&date=2016-06-02)',
+    'params'=>'Params',
+    'clear'=>'Clear',
+    'result'=>'Result',
+    'save_to_templ'=>'Save as template',
+    'more_templ'=>'More template',
+    'saved_templ_list'=>'Template list you saved',
+    'page_comments'=>'Page comments',
+    'add_page_comments'=>'Add comments before save',
+    'cur_page_content'=>'The latest version ',
+    'history_page_content'=>'History version',
+    'overview'=>'Overview',
+    //user
+    'login'=>'Login',
+    'username'=>'Username',
+    'password'=>'Passwod',
+    'verification_code'=>'Verification code',
+    'no_account'=>'Go to register →',
+    'register_new_account'=>'Register new user',
+    'username_description'=>'English name or Email',
+    'password'=>'Passwod',
+    'password_again'=>'Enter password again',
+    'verification_code'=>'Verification code',
+    'register'=>'Register',
+    'had_a_account'=>' Sign on right now→',
+    'update_personal_info'=>'Modify personal information',
+    'new_password_description'=>'The new password',
+    'old_password_description'=>'Original password',
+    'submit'=>'Submit',
+    'goback'=>'Goback',
+
+    //message 弹出信息有关的文案
+    'no_permissions'=>'No permissions',
+    'incorrect_password'=>'Incorrect password',
+    'user_does_not_exist'=>'User does not exist',
+    'operation_succeeded'=>'Operation succeeded',
+    'operation_failed'=>'Operation failed',
+    'access_password_are_incorrect'=>'Access password are incorrect',
+    'verification_code_are_incorrect'=>'Verification code are incorrect',
+    'no_permissions_to_delete_page'=>'No permissions!The page is created by {$author_username}',
+    'delete_succeeded'=>'Delete succeeded',
+    'delete_failed'=>'Delete failed',
+    'register_succeeded'=>'Register succeeded',
+    'username_or_password_incorrect'=>'Username or password are incorrect',
+    'username_exists'=>'Username exists',
+    'code_much_the_same'=>'Password much be the same',
+    'verification_code_are_incorrect'=>'Verification code are incorrect',
+    'auto_login_succeeded'=>'Automatic login success! Jumping...',
+    'login_succeeded'=>'Login succeeded',
+    'modify_succeeded'=>'Modify succeeded',
+    'modify_faild'=>'Modify failed',
+    'old_password_incorrect'=>'The original password is not correct',
+    'logout_succeeded'=>'Logout succeeded',
+
+    //error_message
+    "no_delete_empty_catalog"=>'In order to secure, do not allow direct delete an empty catalog. Please delete or move all the pages in the catalog',
+    
+    "default_title" =>'Default',
+);

+ 220 - 0
Application/Home/Lang/zh-cn.php

@@ -0,0 +1,220 @@
+<?php
+return array(
+
+    //Attorn
+    'attorn_item'=>'转让项目',
+    'username'=>'用户名',
+    'receiver_name'=>'项目接收者用户名',
+    'verify_identity'=>'验证身份',
+    'your_password'=>'你的登录密码',
+    'attorn'=>'转让',
+    'close'=>'关闭',
+
+    //Catalog
+    'new_or_edit_catalog' => '新建/编辑目录',
+    'catalog_name' => '目录名',
+    's_number' => '序号',
+    's_number_explain' => '可选:顺序数字',
+    'last_catalog' => '上级目录',
+    'save' => '保存',
+    'delete_catalog' => '删除目录',
+    'catalog_list' => '目录列表',
+    'click_to_edit' => '点击可编辑',
+
+
+    //index
+    'help' => '帮助',
+    'demo' => '示例',
+    'index_login_or_register' => '登录 / 注册',
+    'my_item' => '我的项目',
+    'section_title1' => 'ShowDoc',
+    'section_description1' => '一个非常适合IT团队的在线API文档、技术文档工具',
+    'section_title2' => 'API文档',
+    'section_description2' => ' APP、web前端与服务器常用API来进行交互<br>用ShowDoc可以非常方便快速地编写出美观的API文档',
+    'section_title3' => '数据字典',
+    'section_description3' => '好的数据字典可以很方便地向别人描述你的数据库结构<br>用ShowDoc可以编辑出美观的数字字典',
+    'section_title4' => '说明文档',
+    'section_description4' => '你完全可以使用 ShowDoc来编写一些工具的说明书<br>也可以编写一些技术规范说明文档以供团队查阅',
+    'section_title5' => '团队协作',
+    'section_description5' => '团队权限管理机制让团队良好地协同编写文档',
+    'section_title6' => '免费开源',
+    'section_description6' => 'ShowDoc提供免费开源的版本<br>你可以选择将ShowDoc部署到你的服务器',
+    'section_title7' => '在线托管',
+    'section_description7' => '<a href="https://www.showdoc.cc" target="_blank">www.showdoc.cc</a> 提供安全稳定的在线文档托管服务<br>你可以放心地选择托管你的文档数据在云端',
+    'section_title8' => '立即体验',
+    'section_description8' => '超过6000+互联网团队正在使用ShowDoc',
+
+
+    //Common message
+    'redirect_message' => '如果你的浏览器没有自动跳转,请点击此链接',
+    'click_to_goback' => '点击这里返回上一页',
+    'home' => '首页',
+    
+
+    //item/add
+    'item_name' => '项目名',
+    'item_description' => '项目描述',
+    'item_domain' => '(可选)个性域名',
+    'item_domain_illegal' => '个性域名只能是字母或数字的组合',
+    'domain_already_exists' => '个性域名已经存在',
+    'visit_password_placeholder' => '访问密码(可选,私密项目请设置密码)',
+    'submit' => '提交',
+    'goback' => '返回',
+    //item/delete
+    'delete_item' => '删除项目',
+    'verify_your_identity' => '验证你的身份',
+    'creator_password' => '创建人登录密码',
+    'delete' => '删除',
+    'close' => '关闭',
+    //item/index
+    'personal_setting'=>'个人设置',
+    'share_home'=>'分享主页',
+    'web_home'=>'网站首页',
+    'logout'=>'退出登录',
+    'add_an_item'=>'添加一个新项目',
+    'new_item'=>'新建项目',
+    'share_my_home'=>'分享我的主页',
+    'feedback' => "反馈",
+    'home_address'=>'主页地址',
+    'home_address_description'=>'别人访问您的主页时,将可以看到您的所有公开项目(但没有新建项目等权限)。你可以复制地址给你的好友',
+    //item/pwd
+    'input_visit_password'=>'请输入访问密码',
+    'password'=>'密码',
+    'verification_code'=>'验证码',
+    'submit'=>'提交',
+    'login_or_register'=>'登录/注册',
+    //item/show
+    'item'=>'项目',
+    'share'=>'分享',
+    'export'=>'导出',
+    'update_info'=>'修改信息',
+    'manage_members'=>'成员管理',
+    'attorn'=>'转让',
+    'delete'=>'删除',
+    'more_item'=>'更多项目',
+    'login_or_register'=>'登录/注册',
+    'about_showdoc'=>'关于ShowDoc',
+    'my_item'=>'我的项目',
+    'new_page'=>'新建页面',
+    'new_catalog'=>'新建目录',
+    'share_address_to_your_friends'=>'分享该接口地址给你的好友',
+    'share'=>'分享',
+    'copy_interface_to_new'=>'复制该页面到新页面',
+    'copy'=>'复制',
+    'edit_interface'=>'编辑页面',
+    'edit'=>'编辑',
+    'delete_interface'=>'删除页面',
+    'comfirm_delete'=>'确认删除吗?',
+    'delete'=>'删除',
+    'share'=>'分享',
+    'item_address'=>'项目地址',
+    'copy_address_to_your_friends'=>'你可以复制地址给你的好友',
+    'share_page'=>'分享页面',
+    'page_address'=>'页面地址',
+    'copy_address_to_your_friends'=>'你可以复制地址给你的好友',
+    //item/showbyuid
+    'more'=>'更多',
+    'my_item'=>'我的项目',
+    'login_or_register'=>'登录/注册',
+    'about_showdoc'=>'关于ShowDoc',
+    'all_pubilc_item'=>'的所有公开项目',
+
+    //member
+    'new_member'=>'新增成员',
+    'username'=>'用户名',
+    'save'=>'保存',
+    'member_list'=>'成员列表',
+    'click_to_delete'=>'点击可删除',
+    'close'=>'关闭',
+    "member_group_id" => "只读(只能查看项目,不能修改/删除)",
+    
+    //page
+    'input_page_title'=>'请输入页面标题',
+    'level_2_directory'=>'二级目录',
+    'level_3_directory'=>'三级目录',
+    's_number_explain'=>'可选:顺序数字',
+    'history_version'=>'历史版本',
+    'save'=>'保存',
+    'cancel'=>'取消',
+    'inser_apidoc_template'=>'插入API接口模板',
+    'inser_database_doc_template'=>'插入数据字典模板',
+    'json_tools'=>'JSON工具',
+    'json_to_table'=>'JSON转参数表格',
+    'beautify_json'=>'JSON格式化',
+    'beautify_json_description'=>'请粘贴一段json,程序将自动以美观的方式格式化显示',
+    'http_test_api'=>'在线测试API',
+    'json_to_table_description'=>'请粘贴一段json,程序将自动将json解析并生成参数表格。此功能适合用于快速编写API文档的返回参数表格',
+    'confirm'=>'确定',
+    'cancel'=>'取消',
+    'history_version'=>'历史版本',
+    'update_time'=>'修改时间',
+    'update_by_who'=>'修改人',
+    'operation'=>'操作',
+    'recover_to_this_version'=>'恢复到此版本',
+    'close'=>'关闭',
+    'finish'=>'完成',
+    'api_test_title'=>'GET和POST测试',
+    'api_address_description'=>'接口地址(如:http://www.abc.com/api/login)',
+    'api_address'=>'接口地址',
+    'params_description'=>'参数(如:user_id=121&age=22&date=2016-06-02)',
+    'params'=>'参数',
+    'clear'=>'清除',
+    'result'=>'返回结果',
+    'save_to_templ'=>'另存为模板',
+    'more_templ'=>'更多模板',
+    'saved_templ_list'=>'保存的模板列表',
+    'page_comments'=>'页面注释',
+    'add_page_comments'=>'保存前添加页面注释',
+    'cur_page_content'=>'当前最新版本',
+    'history_page_content'=>'历史版本',
+    'overview'=>'预览',
+
+    //user
+    'login'=>'登录',
+    'username'=>'用户名',
+    'password'=>'密码',
+    'verification_code'=>'验证码',
+    'no_account'=>'没有账号?马上去注册→',
+    'register_new_account'=>'注册新用户',
+    'username_description'=>'用户名(可填英文昵称或邮箱)',
+    'password'=>'密码',
+    'password_again'=>'再次输入密码',
+    'verification_code'=>'验证码',
+    'register'=>'注册',
+    'had_a_account'=>'已有账号?马上去登录→',
+    'update_personal_info'=>'修改个人信息',
+    'new_password_description'=>'新密码,若不修改请留空',
+    'old_password_description'=>'原密码,若不修改密码请留空',
+    'submit'=>'提交',
+    'goback'=>'返回',
+
+    //message 弹出信息有关的文案
+    'no_permissions'=>'你无权限',
+    'incorrect_password'=>'密码错误',
+    'user_does_not_exist'=>'不存在此用户',
+    'operation_succeeded'=>'操作成功!',
+    'operation_failed'=>'操作失败!',
+    'access_password_are_incorrect'=>'访问密码不正确',
+    'verification_code_are_incorrect'=>'验证码不正确',
+    'no_permissions_to_delete_page'=>'你无权限!此页面由{$author_username}创建',
+    'delete_succeeded'=>'删除成功!',
+    'delete_failed'=>'删除失败!',
+    'register_succeeded'=>'注册成功!',
+    'username_or_password_incorrect'=>'用户名或密码不正确',
+    'username_exists'=>'用户名已经存在啦!',
+    'code_much_the_same'=>'两次输入的密码不一致!',
+    'verification_code_are_incorrect'=>'验证码不正确',
+    'auto_login_succeeded'=>'自动登录成功!正在跳转...',
+    'login_succeeded'=>'登录成功!',
+    'modify_succeeded'=>'修改成功!',
+    'modify_faild'=>'修改失败!',
+    'old_password_incorrect'=>'原密码不正确',
+    'logout_succeeded'=>'退出成功!',
+
+    //error_message
+    "no_delete_empty_catalog"=>'为了安全,不允许直接删除非空目录。请先删除或转移该目录下的所有页面',
+    
+    "default_title" =>'默认页面',
+
+
+);

+ 17 - 0
Application/Home/Model/BaseModel.class.php

@@ -0,0 +1,17 @@
+<?php
+namespace Home\Model;
+use Think\Model;
+/**
+ *
+ *        
+ *        
+ */
+class BaseModel extends Model {
+    // 自动验证 //默认,验证条件:0存在字段就进行验证 , 验证时间:1新增/编辑 数据时候验证
+    protected $_validate = array ();
+    // 自动填充 //默认 新增数据的时候处理
+    protected $_auto = array ();
+    // 只读字段,插入后不能通过save更新
+    protected $readonlyField = array ();
+    
+}

+ 182 - 0
Application/Home/Model/ItemModel.class.php

@@ -0,0 +1,182 @@
+<?php
+namespace Home\Model;
+use Home\Model\BaseModel;
+
+class ItemModel extends BaseModel {
+
+    public function export($item_id){
+        $item = D("Item")->where("item_id = '$item_id' ")->field(" item_type, item_name ,item_description,password ")->find();
+        //获取所有父目录id为0的页面
+        $pages = D("Page")->where("cat_id = '0' and item_id = '$item_id' ")->field(" page_title ,page_content,s_number,page_comments ")->order(" `s_number` asc  ")->select();
+        //获取所有二级目录
+        $catalogs = D("Catalog")->where("item_id = '$item_id' and level = 2  ")->field("cat_id, cat_name ,level,s_number ")->order(" `s_number` asc  ")->select();
+        if ($catalogs) {
+            foreach ($catalogs as $key => &$catalog) {
+                //该二级目录下的所有子页面
+                $temp = D("Page")->where("cat_id = '$catalog[cat_id]' ")->field(" page_title ,page_content,s_number,page_comments ")->order(" `s_number` asc  ")->select();
+                $catalog['pages'] = $temp ? $temp: array();
+                //该二级目录下的所有子目录
+                $temp = D("catalog")->where("parent_cat_id = '$catalog[cat_id]' ")->field(" cat_id,cat_name ,level,s_number ")->order(" `s_number` asc  ")->select();
+                $catalog['catalogs'] = $temp ? $temp: array();
+                if($catalog['catalogs']){
+                    //获取所有三级目录的子页面
+                    foreach ($catalog['catalogs'] as $key3 => &$catalog3) {
+                        //该二级目录下的所有子页面
+                        $temp = D("Page")->where("cat_id = '$catalog3[cat_id]' ")->field(" page_title ,page_content,s_number,page_comments ")->order(" `s_number` asc  ")->select();
+                        $catalog3['pages'] = $temp ? $temp: array();
+                        unset($catalog3['cat_id']);
+                    }                        
+                }
+                unset($catalog['cat_id']);               
+            }
+        }
+        $item['pages'] = array(
+            "pages" =>$pages,
+            "catalogs" =>$catalogs,
+            );
+        unset($pages);
+        unset($catalogs);
+        $item['members'] = D("ItemMember")->where("item_id = '$item_id' ")->field(" member_group_id ,uid,username ")->select();
+        return  json_encode($item);
+        
+    }
+    public function import($json,$uid,$item_name= '',$item_description= '',$item_password = '',$item_domain = ''){
+        $userInfo = D("User")->userInfo($uid);
+        $item = json_decode($json ,1 );
+        unset($json);
+        if ($item) {
+            if ($item['item_domain']) {
+                $item2 = D("Item")->where("item_domain = '%s'  ".array($item['item_domain']))->find();
+                if ($item2) {
+                    //个性域名已经存在
+                    return false;
+                }
+                if(!ctype_alnum($item_domain) ||  is_numeric($item_domain) ){
+                    //echo '个性域名只能是字母或数字的组合';exit;
+                    return false;
+                }
+            }else{
+                $item['item_domain'] = '';
+            }
+            $item_data = array(
+                "item_name"=>$item_name ? $item_name :$item['item_name'],
+                "item_domain"=>$item_domain ? $item_domain :$item['item_domain'],
+                "item_type"=>$item['item_type'],
+                "item_description"=>$item_description ? $item_description :$item['item_description'],
+                "password"=>$item_password ? $item_password :$item['password'],
+                "uid"=>$userInfo['uid'],
+                "username"=>$userInfo['username'],
+                "addtime"=>time(),
+                );
+            $item_id = D("Item")->add($item_data);
+        }
+        if ($item['pages']) {
+            //父页面们(一级目录)
+            if ($item['pages']['pages']) {
+                foreach ($item['pages']['pages'] as $key => &$value) {
+                    $page_data = array(
+                        "author_uid"=>$userInfo['uid'],
+                        "author_username"=>$userInfo['username'],
+                        "page_title" =>$value['page_title'],
+                        "page_content" =>$value['page_content'],
+                        "s_number" =>$value['s_number'],
+                        "page_comments" =>$value['page_comments'],
+                        "item_id" => $item_id,
+                        "cat_id" => 0 ,
+                        "addtime" =>time(),
+                        );
+                    D("Page")->add($page_data);
+                    unset($page_data);
+                }
+                unset($item['pages']['pages']);
+            }
+            //二级目录
+            if ($item['pages']['catalogs']) {
+                foreach ($item['pages']['catalogs'] as $key => &$value) {
+                    $catalog_data = array(
+                        "cat_name" => $value['cat_name'],
+                        "level" => $value['level'],
+                        "s_number" => $value['s_number'],
+                        "item_id" => $item_id,
+                        "addtime" =>time(),
+                        );
+                    $cat_id = D("Catalog")->add($catalog_data);
+                    //二级目录的页面们
+                    if ($value['pages']) {
+                        foreach ($value['pages'] as $key2 => &$value2) {
+                            $page_data = array(
+                                "author_uid"=>$userInfo['uid'],
+                                "author_username"=>$userInfo['username'],
+                                "page_title" =>$value2['page_title'],
+                                "page_content" =>$value2['page_content'],
+                                "s_number" =>$value2['s_number'],
+                                "page_comments" =>$value2['page_comments'],
+                                "item_id" => $item_id,
+                                "cat_id" => $cat_id ,
+                                "addtime" =>time(),
+                                );
+                            D("Page")->add($page_data);
+                            unset($page_data);
+                            unset($value2);
+                        }
+                    }
+                    //判断是否存在三级目录
+                    if ($value['catalogs']) {
+                            foreach ($value['catalogs'] as $key3 => &$value3) {
+                                $catalog_data = array(
+                                    "cat_name" => $value3['cat_name'],
+                                    "level" => $value3['level'],
+                                    "s_number" => $value3['s_number'],
+                                    "parent_cat_id" => $cat_id,
+                                    "item_id" => $item_id,
+                                    "addtime" =>time(),
+                                    );
+                                $cat_id2 = D("Catalog")->add($catalog_data);
+                                //三级目录的页面们
+                                if ($value3['pages']) {
+                                    foreach ($value3['pages'] as $key4 => &$value4) {
+                                        $page_data = array(
+                                            "author_uid"=>$userInfo['uid'],
+                                            "author_username"=>$userInfo['username'],
+                                            "page_title" =>$value4['page_title'],
+                                            "page_content" =>$value4['page_content'],
+                                            "s_number" =>$value4['s_number'],
+                                            "page_comments" =>$value4['page_comments'],
+                                            "item_id" => $item_id,
+                                            "cat_id" => $cat_id2 ,
+                                            "addtime" =>time(),
+                                            );
+                                        D("Page")->add($page_data);
+                                        unset($page_data);
+                                        unset($value4);
+                                    }
+                                }
+                             unset($value3);
+                            }
+                    }
+                    unset($value);
+                }
+                 
+            }
+        }
+
+        if ($item['members']) {
+            foreach ($item['members'] as $key => $value) {
+                $member_data = array(
+                    "member_group_id"=>$value['member_group_id'],
+                    "uid"=>$value['uid'],
+                    "username"=>$value['username'],
+                    "item_id"=>$item_id,
+                    "addtime"=>time(),
+                    );
+                D("ItemMember")->add($member_data);
+            }
+        }
+        return $item_id;
+    }
+
+    public function copy($item_id,$uid,$item_name= '',$item_description= '',$item_password = '',$item_domain){
+        return $this->import($this->export($item_id),$uid,$item_name,$item_description,$item_password,$item_domain);
+    }
+    
+}

+ 52 - 0
Application/Home/Model/UserModel.class.php

@@ -0,0 +1,52 @@
+<?php
+namespace Home\Model;
+use Home\Model\BaseModel;
+
+class UserModel extends BaseModel {
+
+    /**
+     * 用户名是否已经存在
+     * 
+     */
+    public function isExist($username){
+        return  $this->where("username = '%s'",array($username))->find();
+    }
+
+    /**
+     * 注册新用户
+     * 
+     */
+    public function register($username,$password){
+        $password = md5(base64_encode(md5($password)).'576hbgh6');
+        return $this->add(array('username'=>$username ,'password'=>$password , 'reg_time'=>time()));
+    }
+
+    //修改用户密码
+    public function updatePwd($uid, $password){
+        $password = md5(base64_encode(md5($password)).'576hbgh6');
+        return $this->where("uid ='%d' ",array($uid))->save(array('password'=>$password));   
+    }
+
+    /**
+     * 返回用户信息
+     * @return 
+     */
+    public function userInfo($uid){
+        return  $this->where("uid = '%d'",array($uid))->find();
+    }
+    
+    /**
+     *@param username:登录名  
+     *@param password 登录密码   
+     */
+    
+    public function checkLogin($username,$password){
+        $password = md5(base64_encode(md5($password)).'576hbgh6');
+        $where=array($username,$password);
+        return $this->where("username='%s' and password='%s'",$where)->find();
+    }
+    //设置最后登录时间
+    public function setLastTime($uid){
+        return $this->where("uid='%s'",array($uid))->save(array("last_login_time"=>time()));
+    }
+}

+ 34 - 0
Application/Home/Model/UserTokenModel.class.php

@@ -0,0 +1,34 @@
+<?php
+namespace Home\Model;
+use Home\Model\BaseModel;
+/**
+ * 
+ * @author star7th      
+ */
+class UserTokenModel extends BaseModel {
+
+	public function createToken($uid,$token_expire = 0 ){
+		$token_expire = $token_expire > 0  ? (time() + $token_expire ) : (time() + 60*60*24*90 );
+		$token = md5(md5($uid.$token_expire.time().rand()."showdoc")."rdgsvgsrgr67hghf54t").md5($uid.$token_expire.time().rand()."showdoc");
+		$data['uid'] = $uid ;
+		$data['token'] = $token ;
+		$data['token_expire'] = $token_expire ;
+		$data['ip'] = getIPaddress() ;
+		$data['addtime'] = time() ;
+		$ret = $this->add($data);
+		if ($ret) {
+			//删除过期的token 
+			$this->where( "token_expire < ".time() )->delete();
+			return $token ;
+		}
+		return false ;
+	}
+
+	public function getToken($token){
+		return $this->where("token='%s'",array($token))->find();
+	}
+
+	public function setLastTime($token){
+		return $this->where("token='%s'",array($token))->save(array("last_check_time"=>time()));
+	}
+}

+ 1 - 0
Application/Home/Model/index.html

@@ -0,0 +1 @@
+ 

+ 44 - 0
Application/Home/View/Attorn/index.html

@@ -0,0 +1,44 @@
+<include file="Common/header" />
+<style type="text/css">
+.single-cat{
+  margin: 10px;
+}
+</style>
+ <div id="edit-cat" class="modal hide fade">
+  <!-- 编辑框 -->
+  <div class="cat-edit">
+      <div class="modal-header">
+      <h4>{$Think.Lang.attorn_item}</h4>
+      </div>
+      <input type="hidden" id="item_id" value="{$item_id}">
+      <div class="add-cat">
+          <form class="form-horizontal">
+            <div class="control-group">
+              <label class="control-label" for="inputEmail">{$Think.Lang.username}</label>
+              <div class="controls">
+                <input type="text" id="username" placeholder="{$Think.Lang.receiver_name}" value="">
+              </div>
+            </div>
+            <div class="control-group">
+              <label class="control-label" for="inputEmail">{$Think.Lang.verify_identity}</label>
+              <div class="controls">
+                <input type="password" id="password" placeholder="{$Think.Lang.your_password}" value="">
+              </div>
+            </div>
+            <div class="control-group">
+              <div class="controls">
+                <button type="submit" class="btn" id="save-cat">{$Think.Lang.attorn}</button>
+              </div>
+            </div>
+          </form>
+
+      </div>
+    </div>
+
+    <div class="modal-footer">
+      <a href="#" class="btn exist-cat">{$Think.Lang.close}</a>
+    </div>
+ </div>
+
+ <include file="Common/footer" />
+ <script src="__PUBLIC__/js/attorn/index.js"></script>

+ 77 - 0
Application/Home/View/Catalog/edit.html

@@ -0,0 +1,77 @@
+<include file="Common/header" />
+<style type="text/css">
+.single-cat{
+  margin: 5px;
+}
+.cat-list{
+  max-height: 300px;
+}
+.cat-content,.second-cat-content,.third-cat-content{
+     max-height: 95px;
+     overflow-y: auto;
+ }
+</style>
+ <div id="edit-cat" class="modal hide fade">
+  <!-- 编辑框 -->
+  <div class="cat-edit">
+      <div class="modal-header">
+      <h4>{$Think.Lang.new_or_edit_catalog}</h4>
+      </div>
+      <input type="hidden" id="item_id" value="{$item_id}">
+      <input type="hidden" id="cat_id" value="{$Catalog.cat_id}">
+      <div class="add-cat">
+          <form class="form-horizontal">
+            <div class="control-group">
+              <label class="control-label" for="inputEmail">{$Think.Lang.catalog_name}</label>
+              <div class="controls">
+                <input type="text" id="cat_name" placeholder="{$Think.Lang.catalog_name}" value="{$Catalog.cat_name}">
+              </div>
+            </div>
+            <div class="control-group">
+              <label class="control-label" for="inputPassword">{$Think.Lang.s_number}</label>
+              <div class="controls">
+                <input type="text" id="s_number" placeholder="{$Think.Lang.s_number_explain}" value="{$Catalog.s_number}">
+              </div>
+            </div>
+             <div class="control-group">
+              <label class="control-label" for="inputPassword">{$Think.Lang.last_catalog}</label>
+              <div class="controls">
+                  <select name="parent_cat_id" id="parent_cat_id" ></select>
+              </div>
+            </div>
+            <div class="control-group">
+              <div class="controls">
+                <button  class="btn" id="save-cat">{$Think.Lang.save}</button>
+                <button  class="btn btn-link" id="delete-cat">{$Think.Lang.delete_catalog}</button>
+              </div>
+            </div>
+          </form>
+
+      </div>
+    </div>
+  <!-- 目录列表 -->
+  <div class="cat-list">
+    <div class="modal-header">
+    <!-- <h4>{$Think.Lang.catalog_list}&nbsp;</h4> -->
+    </div>
+
+    <div style="margin-left:10px;">
+      <h5>二级目录列表<small>({$Think.Lang.click_to_edit})</small></h5>
+      <div id="show-second-cat"  class="second-cat-content">
+      </div>
+      <h5>三级目录列表<small>({$Think.Lang.click_to_edit})</small></h5>
+      <div id="show-third-cat"  class="third-cat-content">
+      </div>
+    </div>
+
+
+  </div>
+
+    <div class="modal-footer">
+      <a href="#" class="btn exist-cat">{$Think.Lang.close}</a>
+    </div>
+ </div>
+
+<input type="hidden" id="default_parent_cat_id"  value="{$default_parent_cat_id}">
+ <include file="Common/footer" />
+ <script src="__PUBLIC__/js/catalog/edit.js?v=1.1.10thirde12"></script>

+ 11 - 0
Application/Home/View/Common/footer.html

@@ -0,0 +1,11 @@
+   
+	<script src="__PUBLIC__/js/common/jquery.min.js"></script>
+    <script src="__PUBLIC__/bootstrap/js/bootstrap.min.js"></script>
+    <script src="__PUBLIC__/js/common/showdoc.js?v=1.1"></script>
+    <script src="__PUBLIC__/layer/layer.js"></script>
+    <script src="__PUBLIC__/js/dialog.js"></script>
+    <div style="display:none">
+    	{:C("STATS_CODE")}
+    </div>
+  </body>
+</html> 

+ 23 - 0
Application/Home/View/Common/header.html

@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html >
+  <head>
+    <meta charset="utf-8">
+    <title>{$item.item_name} ShowDoc</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta name="description" content="">
+    <meta name="author" content="">
+    <link href="__PUBLIC__/bootstrap/css/bootstrap.min.css" rel="stylesheet">
+    <link href="__PUBLIC__/css/showdoc.css" rel="stylesheet">
+      <script type="text/javascript">
+      var DocConfig = {
+          host: window.location.origin,
+          app: "{:U('/')}",
+          server: "server/index.php?s=",
+          pubile:"__PUBLIC__",
+      }
+
+      DocConfig.hostUrl = DocConfig.host + "/" + DocConfig.app;
+      </script>
+      <script src="__PUBLIC__/js/lang.{:LANG_SET}.js?v=212"></script>
+  </head>
+  <body>

+ 38 - 0
Application/Home/View/Common/message.html

@@ -0,0 +1,38 @@
+
+<include file="Common/header" />
+<style type="text/css">
+.message {
+  width: 600px;
+  min-height: 80px;
+  padding: 20px 20px 10px 20px;
+  margin: 50px auto 0 auto;
+  border-width: 5px;
+  overflow: hidden;
+}
+.message .content {
+  overflow: hidden;
+}
+.message h4 {
+  margin: 10px 0;
+  line-height: 30px;
+}
+
+</style>
+<div class="message alert alert-{$type}">
+	<div class="icon pull-left"><i class="{if $type=='success'}icon-ok{else if $type=='error'}icon-remove{else if $type=='tips'}icon-exclamation-sign{else if $type=='sql'}icon-warning-sign{/if}"></i></div>
+	<div class="content">
+		<h4><?php echo $msg;?></h4>
+		<?php if($redirect){ ?>
+		<p><a href="<?php echo $redirect;?>">{$Think.Lang.redirect_message}</a></p>
+		<script type="text/javascript">
+			setTimeout(function () {
+				location.href = "<?php echo $redirect;?>";
+			}, 3000);
+		</script>
+		<?php }else{ ?>
+		<p>[<a href="javascript:history.go(-1);">{$Think.Lang.click_to_goback}</a>] &nbsp; [<a href="__APP__/">{$Think.Lang.home}</a>]</p>
+		<?php } ?>
+	</div>
+</div>
+
+<include file="Common/footer" />

+ 132 - 0
Application/Home/View/Index/index.html

@@ -0,0 +1,132 @@
+
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+<title>ShowDoc</title>
+ <link rel="stylesheet" href="__PUBLIC__/bootstrap/css/bootstrap.min.css">
+
+ <link rel="stylesheet" href="__PUBLIC__/css/jquery.fullPage.css">
+ <style>
+.section { text-align: center; font: 30px "Microsoft Yahei"; color: #fff;}
+.header{
+ padding-right: 100px;
+ padding-top: 30px;
+ font-size: 18px; 
+ position: fixed;
+    right: 0;
+    left: 0;
+    z-index: 1030;
+    margin-bottom: 0;
+}
+.header a {
+    color: white;
+    font-size: 12px;
+    font-weight: bold;
+}
+</style>
+</head>
+
+<body>
+<div class="row header  ">
+  <div class="right pull-right">
+    <ul class="inline pull-right">
+	  <if condition="$login_user">
+	    <li ><a href="{:U('Home/Item/index')}">{$Think.lang.my_item}</a></li>
+	    <else />
+	    <li ><a href="{:U('Home/User/login')}">{$Think.lang.index_login_or_register}</a></li>
+	  </if>
+    </ul>
+    </div>  
+  </div>
+
+<div id="dowebok">
+    <div class="section">
+        <div class="slide">
+            <img src="__PUBLIC__/logo/b_64.png" alt="">
+            <h1>{$Think.lang.section_title1}</h1>
+            <br>
+            <p>{$Think.lang.section_description1}</p>
+            <br>
+            <p>
+                <a class="btn   btn-large " href="{$demo_url}" target="_blank">{$Think.lang.demo}</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+                <a class="btn  btn-large" href="{$help_url}" target="_blank" >{$Think.lang.help}&nbsp;</i></a>
+            </p>
+        </div>
+        <div class="slide">
+            <h1>{$Think.lang.section_title2}</h1>
+            <br>
+            <p> {$Think.lang.section_description2}</p>
+            <br>
+        </div>
+        <div class="slide">
+            <h1>{$Think.lang.section_title3}</h1>
+            <br>
+            <p>{$Think.lang.section_description3}</p>
+            <br>
+        </div>
+        <div class="slide">
+            <h1>{$Think.lang.section_title4}</h1>
+            <br>
+            <p>{$Think.lang.section_description4}</p>
+            <br>
+        </div>
+
+        <div class="slide">
+            <h1>{$Think.lang.section_title5}</h1>
+            <br>
+            <p>{$Think.lang.section_description5}</p>
+            <br>
+        </div>
+
+        <div class="slide">
+            <h1>{$Think.lang.section_title6}</h1>
+            <br>
+            <p>{$Think.lang.section_description6}</p>
+            <br>
+        </div>
+
+        <div class="slide">
+            <h1>{$Think.lang.section_title7}</h1>
+            <br>
+            <p>{$Think.lang.section_description7}</p>
+            <br>
+        </div>
+        <div class="slide">
+            <h1></h1>
+            <br>
+            <p>{$Think.lang.section_description8}</p>
+            <br>
+            <p>
+                <a class="btn   btn-large " href="{:U('Home/User/register')}">{$Think.lang.section_title8}</a>
+            </p>
+        </div>
+    </div>
+</div>
+ <include file="Common/footer" />
+<script src="__PUBLIC__/js/jquery.fullPage.min.js"></script>
+<script>
+$(function(){
+    $('#dowebok').fullpage({
+        sectionsColor : ['#1bbc9b', '#4BBFC3', '#2C606A', '#f90','#7CBD9D','#A77DC2','#85CE92','#1bbc9b'],
+        navigation:false,
+    });
+
+    $(window).resize(function(){
+        autoScrolling();
+    });
+
+    function autoScrolling(){
+        var $ww = $(window).width();
+        if($ww < 1024){
+            $.fn.fullpage.setAutoScrolling(false);
+        } else {
+            $.fn.fullpage.setAutoScrolling(true);
+        }
+    }
+
+    autoScrolling();
+});
+</script>
+</body>
+</html>

+ 143 - 0
Application/Home/View/Item/add.html

@@ -0,0 +1,143 @@
+<include file="Common/header" />
+<link rel="stylesheet" href="__PUBLIC__/css/login.css" />
+<style type="text/css">
+.choose_type{
+    margin-bottom: 20px;
+    text-align: center;
+}
+#choose_item{
+    width: 100%;
+}
+</style>
+    <div class="container">
+
+      <form class="form-signin myform" method="post"  action="server/index.php?s=/api/item/add">
+        <!-- <h3 class="form-signin-heading">新建项目</h3> -->
+        <div class="choose_type">
+            <label class="radio inline">
+              <input type="radio" name="item_type" id="item_type1" value="1" checked >
+              常规项目
+            </label>
+            <label class="radio inline">
+              <input type="radio" name="item_type" id="item_type2" value="2" >
+              单页项目
+              &nbsp;
+              <a href="https://www.showdoc.cc/page/65391" target="_blank"><i class="icon-question-sign"></i></a>
+
+            </label>
+        </div>
+
+
+        <input type="text" class="input-block-level" id="item_name" name="item_name" placeholder="{$Think.Lang.item_name}" autocomplete="off" value="{$item.item_name}" >
+        <input type="text" class="input-block-level" id="item_description" name="item_description" placeholder="{$Think.Lang.item_description}" autocomplete="off" value="{$item.item_description}">
+        <input type="text" style="display:none" class="input-block-level"  name="item_domain" placeholder="{$Think.Lang.item_domain}" autocomplete="off" value="{$item.item_domain}" >
+        <input style="display:none"><!-- for disable autocomplete on chrome -->
+        <input style="display:none"><!-- for disable autocomplete on chrome -->
+        <input type="text" onfocus="this.type='password'" id="password" class="input-block-level" name="password" placeholder="{$Think.Lang.visit_password_placeholder}" title="{$Think.Lang.visit_password_placeholder}" autocomplete="off" value="{$item.password}">
+        <label class="checkbox">
+            <input type="checkbox" id="show_copy"> 复制已存在项目
+        </label>
+        <div >
+            <select id="choose_item" name="copy_item_id">
+
+            </select>
+        </div>
+        <br>
+        <button class="btn  btn-primary" type="submit">{$Think.Lang.submit}</button>
+        <a href="javascript:history.go(-1)" class="btn">{$Think.Lang.goback}</a>
+      </form>
+
+    </div> <!-- /container -->
+
+
+ <include file="Common/footer" />
+ <script src="__PUBLIC__/js/jquery.form.min.js"></script>
+ <script type="text/javascript">
+ var password = $("#password").val();
+ if (password) {
+    $("#password").val('');
+    $("#password").attr('type','password');
+    $("#password").val(password);  
+ };
+
+$("#choose_item").hide();
+
+//如果是编辑项目,则禁用复制项目功能
+if ($("#item_id").val()) {
+    $("#show_copy").parent().hide();
+    $(".choose_type").html("");
+};
+
+$("#show_copy").change(function(){
+    if ($("#show_copy").is(':checked')) {
+        $("#choose_item").show();
+        $("#item_type1").attr("disabled","disabled");
+        $("#item_type2").attr("disabled","disabled");
+        $("#item_type1").removeAttr("checked");
+        $("#item_type2").removeAttr("checked");
+    }else{
+        $("#choose_item").hide();
+        $("#item_type1").removeAttr("disabled");
+        $("#item_type2").removeAttr("disabled");
+        $("#item_name").val("");
+        $("#item_description").val('');
+        $("#password").val('');
+    }
+    get_item_list();
+});
+
+
+function get_item_list(){
+    //获取已有项目列表
+    $.get(
+            DocConfig.server+"/api/item/itemList",
+            {},
+            function(data){
+             if (data.error_code === 0) {
+                var json = data.data ;
+                var html = '<option>请选择</option>';
+                for (var i = 0; i < json.length; i++) {
+                    html += '<option value="'+json[i].item_id+'" item_description="'+json[i].item_description+'" password="'+json[i].password+'" >'+json[i].item_name+'</option>';
+                };
+                $("#choose_item").html(html);
+
+             };
+            },
+            "json"
+        );    
+}
+
+
+//当用户选择了某个复制项目,则填充信息
+$("#choose_item").change(function(){
+    var a = $(this).find("option:selected");
+    var item_name = a.text();
+    var item_description = a.attr("item_description");
+    var password = a.attr("password");
+    $("#item_name").val(item_name+"--copy");
+    $("#item_description").val(item_description);
+    $("#password").val(password);
+
+});
+
+
+//上传表单参数
+var ajax_option = {
+  dataType:"json",
+  beforeSubmit:function(){
+
+  },
+  success:function(res){
+    if (res.error_code === 0) {
+      window.location.href = "?s=/home/item/index";
+    }else{
+      $.alert(res.error_message);
+    }
+
+    return false;
+  }
+};
+
+$('.myform').ajaxForm(ajax_option); 
+
+ </script>

+ 38 - 0
Application/Home/View/Item/delete.html

@@ -0,0 +1,38 @@
+<include file="Common/header" />
+<style type="text/css">
+.single-cat{
+  margin: 10px;
+}
+</style>
+ <div id="edit-cat" class="modal hide fade">
+  <!-- 编辑框 -->
+  <div class="cat-edit">
+      <div class="modal-header">
+      <h4>{$Think.Lang.delete_item}</h4>
+      </div>
+      <input type="hidden" id="item_id" value="{$item_id}">
+      <div class="add-cat">
+          <form class="form-horizontal">
+            <div class="control-group">
+              <label class="control-label" for="inputEmail">{$Think.Lang.verify_your_identity}</label>
+              <div class="controls">
+                <input type="password" id="password" placeholder="{$Think.Lang.creator_password}" value="">
+              </div>
+            </div>
+            <div class="control-group">
+              <div class="controls">
+                <button type="submit" class="btn" id="save-cat">{$Think.Lang.delete}</button>
+              </div>
+            </div>
+          </form>
+
+      </div>
+    </div>
+
+    <div class="modal-footer">
+      <a href="#" class="btn exist-cat">{$Think.Lang.close}</a>
+    </div>
+ </div>
+
+ <include file="Common/footer" />
+ <script src="__PUBLIC__/js/item/delete.js?v=dd"></script>

+ 57 - 0
Application/Home/View/Item/export.html

@@ -0,0 +1,57 @@
+<include file="Common/header" />
+<link rel="stylesheet" href="__PUBLIC__/css/login.css" />
+<style type="text/css">
+.choose_type{
+    margin-bottom: 30px;
+    text-align: center;
+}
+.inline{
+    display: inline;
+}
+</style>
+    <div class="container">
+
+      <form class="form-signin" method="post">
+        <input type="hidden" id="item_id" name="item_id" value="{$item_id}">
+        <div class="choose_type">
+            <label class="radio inline">
+              <input type="radio" name="item_type" id="item_type1" value="1" checked="checked">
+              导出全部
+            </label>
+            <label class="radio inline">
+              <input type="radio" name="item_type" id="item_type2" value="2" >
+              按目录导出
+            </label>
+        </div>
+
+
+        <div >
+            <label class="inline">二级目录:</label>
+            <select class="inline level_2_directory" disabled="disabled">
+                <option >  全部 </option>
+            </select>
+        </div>
+        <div >
+            <label class="inline">三级目录:</label>
+            <select class="inline level_3_directory" disabled="disabled">
+                <option>  全部 </option>
+            </select>
+        </div>
+        <!--  
+        <div >
+            <label class="inline">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;页面:</label>
+            <select class="inline page" disabled="disabled">
+                <option>  全部 </option>
+            </select>
+        </div>
+        -->
+        <br>
+        <button class="btn  btn-primary export-submit" type="submit">{$Think.Lang.submit}</button>
+        <a href="javascript:history.go(-1)" class="btn">{$Think.Lang.goback}</a>
+      </form>
+
+    </div> <!-- /container -->
+
+
+ <include file="Common/footer" />
+<script src="__PUBLIC__/js/item/export.js"></script>

+ 52 - 0
Application/Home/View/Item/index.html

@@ -0,0 +1,52 @@
+<include file="Common/header" />
+<link rel="stylesheet" href="__PUBLIC__/css/item/index.css?v=1.234" />
+    <div class="container-narrow">
+
+      <div class="masthead">
+        <div class="btn-group pull-right">
+        <a class="btn btn-link" href="https://github.com/star7th/showdoc/issues" target="_blank">{$Think.Lang.feedback}</a>
+        <a class="btn btn-link dropdown-toggle" data-toggle="dropdown" href="#">
+        {$Think.Lang.more}
+        <span class="caret"></span>
+        </a>
+        <ul class="dropdown-menu">
+        <!-- dropdown menu links -->
+          <li><a href="{:U('Home/User/setting')}">{$Think.Lang.personal_setting}</a></li>
+<!--           <li><a href="#share-home-modal"  data-toggle="modal">{$Think.Lang.share_home}</a></li>
+ -->      
+          <li><a href="{:U('Home/index/index')}">{$Think.Lang.web_home}</a></li>
+          <li><a href="{:U('Home/User/exist')}">{$Think.Lang.logout}</a></li>
+
+        </ul>
+        </div>
+
+        </ul>
+        <h3 class="muted"><img src="__PUBLIC__/logo/b_64.png" style="width:50px;height:50px;margin-bottom:15px;" alt="">ShowDoc</h3>
+      </div>
+
+      <hr>
+
+    <div class="container-thumbnails">
+      <ul class="thumbnails" id="item-list">
+
+      </ul>
+    </div>
+
+
+    </div> <!-- /container -->
+
+<!-- 分享项目框 -->
+<div class="modal hide fade" id="share-home-modal">
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h3>{$Think.Lang.share_my_home}</h3>
+  </div>
+  <div class="modal-body">
+    <p>{$Think.Lang.home_address}:<code id="share-home-link">{$share_url}</code></p>
+    <p>{$Think.Lang.home_address_description}</p>
+  </div>
+</div>
+
+
+ <include file="Common/footer" />
+ <script src="__PUBLIC__/js/item/index.js?v=12"></script>

+ 70 - 0
Application/Home/View/Item/pwd.html

@@ -0,0 +1,70 @@
+<include file="Common/header" />
+<link rel="stylesheet" href="__PUBLIC__/css/login.css" />
+    <div class="container">
+
+            <form class="form-signin myform card" method="post" action="server/index.php?s=/api/item/pwd">
+        <h3 class="form-signin-heading heading">{$Think.Lang.input_visit_password}</h3>
+        <input type="hidden" id="item_id" name="item_id" value="{$item_id}">
+        <input type="password" class="input-block-level" name="password" placeholder="{$Think.Lang.password}">
+        <input type="hidden"  name="refer_url" value="{$refer_url}">
+        <if  condition="$CloseVerify != 1">
+        <input type="text" class="input-block-level" id="input_v_code" name="v_code" placeholder="{$Think.Lang.verification_code}">
+              <div class="control-group">
+          <div class="controls">
+            <img src="" id="v_code_img">
+          </div>
+        </div>
+        </if>
+        <button class="btn btn-large btn-primary btn-block" type="submit">{$Think.Lang.submit}</button>
+     
+        <div class="form-group" style="text-align:center;margin-top:15px;">
+            <a href="{:U('Home/User/login')}">{$Think.Lang.login_or_register}</a>
+        </div>
+         </form>
+    </div> <!-- /container -->
+
+
+<include file="Common/footer" />
+<script src="__PUBLIC__/js/jquery.form.min.js"></script>
+ <script type="text/javascript">
+ $(function(){
+    $("#input_v_code").hide();
+    $("#v_code_img").hide();
+    $("#v_code_img").attr("src" , DocConfig.pubile+'/verifyCode.php');
+
+    $("#v_code_img").click(function(){
+      var v_code_img = $("#v_code_img").attr("src");
+      $("#v_code_img").attr('src' ,v_code_img+'?'+Date.parse(new Date()) );
+    }); 
+
+    //上传表单参数
+    var ajax_option = {
+      dataType:"json",
+      beforeSubmit:function(){
+
+      },
+      success:function(res){
+        if (res.error_code === 0) {
+          if (res.refer_url) {
+            var url = res.refer_url;
+          }else{
+            var url = '?s=/'+$("#item_id").val();
+          }
+          window.location.href = url;
+        }else{
+          $.alert(res.error_message);
+
+          if (res.error_code === 10206 || res.error_code === 10308 ) {
+            $("#v_code_img").click();
+            $("#v_code_img").show();
+            $("#input_v_code").show();
+          };
+          
+        }
+      }
+    };
+
+    $('.myform').ajaxForm(ajax_option); 
+ });
+</script>
+

+ 269 - 0
Application/Home/View/Item/setting.html

@@ -0,0 +1,269 @@
+<include file="Common/header" />
+
+<link rel="stylesheet" type="text/css" href="__PUBLIC__/css/tab-tpl.css?v=1">
+<style type="text/css">
+.member-desc{
+  width: 300px;
+  margin: 0 auto;
+}
+
+</style>
+<div class="tab-header"></div>
+<div class="container tab-doc-container">
+ <div class="tab-doc-title-box">
+  <span  class="dn"></span>
+  <h3 >项目设置 &nbsp;&nbsp;<small><a href="javascript:history.go(-1)">返回</a></small></h3>
+</div>
+<div class="tab-doc-body" >
+
+  <div class="tab-doc-content" >
+    <ul class="nav nav-tabs" id="myTab">
+      <li><a href="#base-info" data-toggle="tab">基础信息</a></li>
+      <li><a href="#member" data-toggle="tab">成员管理</a></li>
+      <li><a href="#adv-seting" data-toggle="tab">高级设置</a></li>
+      <li><a href="#item-api" data-toggle="tab">开放API</a></li>
+    </ul>
+
+    <div class="tab-content">
+      <div class="tab-pane" id="base-info" >
+        <form class="form-horizontal">
+         <div class="control-group">
+          <label class="control-label" for="">项目名:</label>
+          <div class="controls">
+            <input type="text" id="item_name" placeholder="">
+          </div>
+        </div>
+        <div class="control-group">
+          <label class="control-label" for="">项目描述:</label>
+          <div class="controls">
+            <input type="text" id="item_description" placeholder="">
+          </div>
+        </div>
+        <div class="control-group" style="display:none">
+          <label class="control-label" for="">个性域名:</label>
+          <div class="controls">
+            <input type="text" id="item_domain" placeholder="">
+          </div>
+        </div>
+        <div class="control-group">
+          <label class="control-label" for="inputPassword">访问密码:</label>
+          <div class="controls">
+            <input  type="text" onfocus="this.type='password'" id="password" placeholder="(可选)私有项目请设置访问密码">
+          </div>
+        </div>
+        <div class="control-group">
+          <div class="controls">
+            <button type="submit" id="item_save" class="btn">保存</button>
+          </div>
+        </div>
+      </form>
+    </div>
+
+    <div class="tab-pane" id="member">
+      <p><button  id="add-member-btn" class="btn ">新增成员</button></p>
+      <table class="table table-hover">
+        <thead>
+          <tr>
+            <th style="width:80px;">用户名</th>
+            <th style="width:80px;">添加时间</th>
+            <th style="width:80px;">权限</th>
+            <th style="width:80px;">操作</th>
+
+          </tr>
+        </thead>
+        <tbody id="member-list">
+
+        </tbody>
+      </table>
+
+    </div>
+    <div class="tab-pane" id="adv-seting">
+      <div style="width:300px;margin:0 auto;padding-top:20px;">
+        <p><button  id="attorn-btn" class="btn ">转让</button></p>
+        <p><small>你可以将项目转让给他人</small></p>
+        <hr>
+        <p><button  id="archive-item-btn" class="btn ">归档</button></p>
+        <p><small>归档后,项目将变为只读,无法再修改/新增内容</small></p>
+        <hr>
+        <p><button  id="delete-item-btn" class="btn btn-danger">删除</button></p>
+        <p><small>删除后将不可恢复</small></p>
+        <hr> 
+      </div>
+
+    </div>
+    <div class="tab-pane" id="item-api">
+        <form class="form-horizontal">
+         <div class="control-group">
+          <label class="control-label" for="">api_key:</label>
+          <div class="controls">
+            <!-- <input type="text" id="api_key" style="width:260px;" placeholder="" disabled> -->
+            <code id="api_key" ></code>
+          </div>
+        </div>
+        <div class="control-group">
+          <label class="control-label" for="">api_token:</label>
+          <div class="controls">
+            <!-- <input type="text" id="api_token" placeholder="" style="width:260px;" disabled> -->
+            <code id="api_token" ></code>
+          </div>
+        </div>
+        <div class="control-group">
+          <div class="controls">
+            <button type="submit" id="reset_api_token" class="btn">重新生成api_token</button>
+          </div>
+        </div>
+      </form>
+      <div style="width:450px;margin:0 auto;padding-top:20px;">
+        <p>showdoc开放文档编辑的API,供使用者更加方便地操作文档数据。利用开放API,你可以自动化地完成很多事</p>
+        <p>关于API详细用法,请参考我们的<a href="https://www.showdoc.cc/page/102098" target="_blank">API文档</a></p>
+        <hr> 
+      </div>
+    </div>
+  </div>
+
+</div>
+
+</div>
+
+<input type="hidden" id="item_id" value="{$item_id}">
+
+
+<!-- 转让项目的弹窗 -->
+<div id="attorn-modal" class="modal hide fade">
+  <div class="">
+    <div class="modal-header">
+      <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+      <h4>转让项目</h4>
+    </div>
+    <div class="">
+      <form class="form-horizontal">
+        <div class="control-group">
+          <label class="control-label" for="inputEmail">{$Think.Lang.username}</label>
+          <div class="controls">
+            <input type="text" id="attorn_username" placeholder="{$Think.Lang.receiver_name}" value="">
+          </div>
+        </div>
+        <div class="control-group">
+          <label class="control-label" for="inputEmail">{$Think.Lang.verify_identity}</label>
+          <div class="controls">
+            <input type="password" id="attorn_password" placeholder="{$Think.Lang.your_password}" value="">
+          </div>
+        </div>
+        <div class="control-group">
+          <div class="controls">
+            <button type="submit" class="btn" id="attorn_save">{$Think.Lang.attorn}</button>
+          </div>
+        </div>
+      </form>
+
+    </div>
+  </div>
+
+  <div class="modal-footer">
+    <a href="#" class="btn exist-attorn" data-dismiss="modal" aria-hidden="true" >{$Think.Lang.close}</a>
+  </div>
+</div>
+
+<!-- 删除项目的弹窗 -->
+<div id="delete-item-modal" class="modal hide fade">
+  <div class="">
+    <div class="modal-header">
+      <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+      <h4>删除项目</h4>
+    </div>
+    <div class="">
+      <form class="form-horizontal">
+        <div class="control-group">
+          <label class="control-label" for="inputEmail">{$Think.Lang.verify_identity}</label>
+          <div class="controls">
+            <input type="password" id="delete_item_password" placeholder="{$Think.Lang.your_password}" value="">
+          </div>
+        </div>
+        <div class="control-group">
+          <div class="controls">
+            <button type="submit" class="btn" id="delete_item_save">{$Think.Lang.delete}</button>
+          </div>
+        </div>
+      </form>
+
+    </div>
+  </div>
+
+  <div class="modal-footer">
+    <a href="#" class="btn exist-attorn" data-dismiss="modal" aria-hidden="true" >{$Think.Lang.close}</a>
+  </div>
+</div>
+
+<!-- 添加成员的弹窗 -->
+<div id="member-modal" class="modal hide fade">
+  <!-- 编辑框 -->
+  <div class="">
+    <div class="modal-header">
+    <h4>{$Think.Lang.new_member}</h4>
+    </div>
+    <div class="">
+        <form class="form-horizontal">
+          <div class="control-group">
+            <label class="control-label" for="inputEmail">{$Think.Lang.username}</label>
+            <div class="controls">
+              <input type="text" id="member_username" placeholder="{$Think.Lang.username}" value="">
+            </div>
+          </div>
+          <div class="control-group">
+            <div class="controls">
+              <label class="checkbox">
+                <input type="checkbox" id="member_group_id">{$Think.Lang.member_group_id}
+              </label>
+            </div>
+          </div>
+          <div class="control-group">
+            <div class="controls">
+              <button type="submit" class="btn" id="member_save">{$Think.Lang.save}</button>
+            </div>
+          </div>
+        </form>
+        <div class="member-desc">
+          <p>权限说明:
+            <br>默认成员可以新建/编辑项目页面,删除时将只能删除自己新建/编辑的页面。
+            <br>勾选只读属性后,该成员对所有页面都只能查看,无法新增/编辑/删除</p>
+        </div>
+        
+    </div>
+  </div>
+  <div class="modal-footer">
+    <a href="#" class="btn " data-dismiss="modal" aria-hidden="true">{$Think.Lang.close}</a>
+  </div>
+</div>
+
+<!-- 归档项目的弹窗 -->
+<div id="archive-item-modal" class="modal hide fade">
+  <div class="">
+    <div class="modal-header">
+      <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+      <h4>归档项目</h4>
+    </div>
+    <div class="">
+      <form class="form-horizontal">
+        <div class="control-group">
+          <label class="control-label" for="inputEmail">{$Think.Lang.verify_identity}</label>
+          <div class="controls">
+            <input type="password" id="archive_item_password" placeholder="{$Think.Lang.your_password}" value="">
+          </div>
+        </div>
+        <div class="control-group">
+          <div class="controls">
+            <button type="submit" class="btn" id="archive_item_save">归档</button>
+          </div>
+        </div>
+      </form>
+        <div class="member-desc">
+          <p>说明:
+            <br>归档项目,项目将无法再新增和修改内容,并且无法取消归档状态。
+            <br>如想再次修改内容,可复制本项目,在新的项目基础上修改。复制项目的方法是,在创建项目的时候,选择从已有项目里复制。</p>
+        </div>
+    </div>
+  </div>
+
+<include file="Common/footer" />
+<script src="__PUBLIC__/js/item/setting.js?v=12"></script>
+

+ 176 - 0
Application/Home/View/Item/show.html

@@ -0,0 +1,176 @@
+<include file="Common/header" />
+<link rel="stylesheet" href="__PUBLIC__/css/item/show.css?1.1d.1thdddef" />
+
+
+<div class="doc-head row" >
+  <div class="left "><h2>{$item.item_name}</h2></div>
+  <div class="right">
+    <ul class="inline pull-right">
+
+      <if condition="$ItemPermn">
+      <li>
+          <div class="btn-group ">
+            <a class="btn btn-link dropdown-toggle" data-toggle="dropdown" href="#">
+              {$Think.Lang.item}
+              <span class="caret"></span>
+            </a>
+          <ul class="dropdown-menu">
+          <!-- dropdown menu links -->
+            <li><a href="#" id="share">{$Think.Lang.share}</a></li>
+             <li><a href="{:U('Home/Item/word',array('item_id'=>$item['item_id']))}">{$Think.Lang.export}</a></li>
+
+             <if condition="$ItemCreator">
+              <li><a href="{:U('Home/Item/add',array('item_id'=>$item['item_id']))}">{$Think.Lang.update_info}</a></li>          
+              <li><a href="{:U('Home/Member/edit',array('item_id'=>$item['item_id']))}">{$Think.Lang.manage_members}</a></li>
+              <li><a href="{:U('Home/Attorn/index',array('item_id'=>$item['item_id']))}">{$Think.Lang.attorn}</a></li>
+              <li><a href="{:U('Home/Item/delete',array('item_id'=>$item['item_id']))}">{$Think.Lang.delete}</a></li>
+            </if>
+
+            <li><a href="{:U('Home/Item/index')}">{$Think.Lang.goback}</a></li>
+          </ul>
+      </li>
+      <else />
+
+      <if condition="! $login_user">
+        <li ><a href="{:U('Home/User/login')}">{$Think.Lang.login_or_register}</a></li>
+        <li ><a href="{$help_url}" target="_blank">{$Think.Lang.about_showdoc}</a></li>
+        <else />
+        <li><a href="{:U('Home/Item/index')}">{$Think.Lang.my_item}</a></li>
+      </if>
+
+        
+      </if>
+
+    </ul>
+    </div>  
+  </div>
+</div>
+
+<div class="doc-body row">
+  <!-- 左侧栏菜单 -->
+    <div class="doc-left span3 bs-docs-sidebar pull-left">
+        <form class="form-search text-center" action="{:U('Home/item/show',array('item_id'=>$item['item_id']))}" method="post">
+          <div class="input-append search-input-append">
+            <i class="icon-blank"></i>
+            <input type="text" name="keyword" class="search-query search-query-input" value="{$keyword}">
+            <input type="hidden" name="item_id" value="{$item.item_id}">
+            <button type="submit" class="btn"><i class="icon-search"></i></button>
+          </div>
+        </form>
+
+      <ul class="nav nav-list bs-docs-sidenav">
+
+        <!-- 一级目录的页面在前面 -->
+        <foreach name="pages" item="page">
+          <li ><a href="{:U('Home/Page/index',array('page_id'=>$page['page_id']))}" data-page-id="{$page.page_id}" ><i class="icon-blank"></i>{$page.page_title}</a></li>
+        </foreach>
+
+        <foreach name="catalogs" item="catalog">
+
+        
+          <li><a href="#"><i class="icon-chevron-right"></i>{$catalog.cat_name}</a>
+            <ul class="child-ul nav-list hide">
+              <!-- 二级目录的页面们 -->
+              <foreach name="catalog.pages" item="catalog_page">
+                <li><a href="{:U('Home/Page/index',array('page_id'=>$catalog_page['page_id']))}" data-page-id="{$catalog_page.page_id}" >{$catalog_page.page_title}</a></li>
+              </foreach>
+              <!-- 二级目录的子目录们(三级目录) -->
+                <foreach name="catalog.catalogs" item="catalog3">   
+                  <li class="third-child-catalog"><a href="#"><i class="icon-chevron-right"></i>{$catalog3.cat_name}</a>
+                    <ul class="child-ul nav-list hide">
+                      <!-- 二级目录的页面们 -->
+                      <foreach name="catalog3.pages" item="catalog3_page">
+                        <li><a href="{:U('Home/Page/index',array('page_id'=>$catalog3_page['page_id']))}" data-page-id="{$catalog3_page.page_id}" >{$catalog3_page.page_title}</a></li>
+                      </foreach>
+                    </ul>
+                  </li>
+
+                </foreach>
+
+            </ul>
+          </li>
+
+        </foreach>
+
+      </ul>
+      <!-- 新建栏 -->
+      <div class="doc-left-newbar">
+
+        <if condition="$ItemPermn">
+          <div><a href="{:U('Home/Page/edit',array('item_id'=>$item['item_id'],'type'=>'new'))}" id="new-like"><i class="icon-plus"></i>&nbsp;{$Think.Lang.new_page}</a></div>
+          <div><a href="{:U('Home/Catalog/edit',array('item_id'=>$item['item_id']))}" id="dir-like" ><i class="icon-folder-open"></i>{$Think.Lang.new_catalog}</a></div>
+
+        </if>
+
+      </div>
+
+      <input type="hidden" id="item_id" value="{$item.item_id}">
+      <input type="hidden" id="item_domain" value="{$item.item_domain}">
+      <input type="hidden" id="current_page_id" value="{$current_page_id}">
+      <input type="hidden" id="base_url" value="__APP__">
+
+
+    </div>
+    <div class="doc-right  span12 ">
+      <!-- 编辑栏 -->
+      <div class='page-edit-link pull-right hide'>
+        <ul class="inline">
+          <if condition="$ItemPermn">
+            <li><a href="" id="share-page" title="{$Think.Lang.share_address_to_your_friends}">{$Think.Lang.share}</a></li>
+            <li><a href="" id="copy-link" title="{$Think.Lang.copy_interface_to_new}">{$Think.Lang.copy}</a></li>
+            <li><a href="" id="edit-link" title="{$Think.Lang.edit_interface}">{$Think.Lang.edit}</a></li>
+            <li><a href="" title="{$Think.Lang.delete_interface}" onclick="return confirm('{$Think.Lang.comfirm_delete}');return false;" id="delete-link">{$Think.Lang.delete}</a></li>
+          <else />
+            <li></li>
+            <li></li>
+        </if>
+        </ul>
+      </div>
+      <!-- 页面内容 -->
+      <div class='iframe_content'>
+        <iframe id="page-content" width="100%" scrolling="yes"  height="100%" frameborder="0" style=" overflow:visible; height:100%;" name="main"  seamless ="seamless"src=""></iframe>
+      </div>
+
+    </div>
+
+<include file="Common/footer" />
+<!-- 分享项目框 -->
+<div class="modal hide fade" id="share-modal">
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h3>{$Think.Lang.share}</h3>
+  </div>
+  <div class="modal-body">
+  <div class="modal-body" style="text-align: center;">
+    <p>{$Think.Lang.item_address}:<code id="share-item-link">{$share_url}</code>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" id="copy-item-link">复制链接</a>
+  </p>
+    <p style="border-bottom: 1px solid #eee;"><img  alt="二维码" style="width:114px;height:114px;" src="?s=home/common/qrcode&size=3&url={$share_url}"> </p>
+  </div>
+
+  </div>
+</div>
+
+<!-- 分享页面框 -->
+<div class="modal hide fade" id="share-page-modal">
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h3>{$Think.Lang.share_page}</h3>
+  </div>
+  <div class="modal-body" style="text-align: center;">
+    <p>项目页面地址:<code id="share-page-link"></code>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" id="copy-page-link">复制链接</a>
+  </p>
+      <p style="border-bottom: 1px solid #eee;"><img  alt="二维码" id="qr-page-link" style="width:114px;height:114px;" src="?s=home/common/qrcode&size=3&url="> </p>
+      
+    <p >单页面地址:<code id="share-single-link"></code>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" id="copy-single-link">复制链接</a>
+    </p>
+      <p style="border-bottom: 1px solid #eee;"><img  alt="二维码" id="qr-single-link" style="width:114px;height:114px;" src="?s=home/common/qrcode&size=3&url="> </p>
+   <p><a href="https://www.showdoc.cc/page/63882" target="_blank">项目页面地址和单页面地址有什么区别?</a></p><p>
+    </p>
+  </div>
+</div>
+<script src="__PUBLIC__/js/jquery.bootstrap-growl.min.js"></script>
+<script src="__PUBLIC__/js/jquery.goup.min.js"></script>
+<script src="__PUBLIC__/js/jquery.hotkeys.js"></script>
+<script src="__PUBLIC__/jquery.zclip/jquery.zclip.js"></script>
+
+<script src="__PUBLIC__/js/item/show.js?v=1.2121"></script>

+ 187 - 0
Application/Home/View/Item/show_regular.html

@@ -0,0 +1,187 @@
+<include file="Common/header" />
+<link rel="stylesheet" href="__PUBLIC__/css/item/show.css?1.1d.1thdddefghi1" />
+
+<div class="doc-head row" >
+  <div class="left "><h4>{$item.item_name}</h4></div>
+  <div class="right">
+    <ul class="inline pull-right">
+
+      <if condition="$ItemPermn">
+      <li>
+          <div class="btn-group ">
+            <a class="btn btn-link dropdown-toggle" data-toggle="dropdown" href="#">
+              {$Think.Lang.item}
+              <span class="caret"></span>
+            </a>
+          <ul class="dropdown-menu left-dropdown-menu">
+          <!-- dropdown menu links -->
+            <li><a href="#" id="share">{$Think.Lang.share}</a></li>
+             <li><a href="{:U('Home/Item/export',array('item_id'=>$item['item_id']))}">{$Think.Lang.export}</a></li>
+
+             <if condition="$ItemCreator">
+              <li><a href="{:U('Home/Item/setting',array('item_id'=>$item['item_id']))}">项目设置</a></li>          
+            </if>
+
+            <li><a href="{:U('Home/Item/index')}">{$Think.Lang.goback}</a></li>
+          </ul>
+      </li>
+      <else />
+
+      <if condition="! $login_user">
+        <li ><a href="{:U('Home/User/login')}">{$Think.Lang.login_or_register}</a></li>
+        <li ><a href="{$help_url}" target="_blank">{$Think.Lang.about_showdoc}</a></li>
+        <else />
+        <li><a href="{:U('Home/Item/index')}">{$Think.Lang.my_item}</a></li>
+      </if>
+
+        
+      </if>
+
+    </ul>
+    </div>  
+  </div>
+</div>
+
+<div class="doc-body row">
+  <!-- 左侧栏菜单 -->
+    <div class="doc-left span3 bs-docs-sidebar pull-left">
+        <form class="form-search text-center" action="{:U('Home/item/show',array('item_id'=>$item['item_id']))}" method="post">
+          <div class="input-append search-input-append">
+            <i class="icon-blank"></i>
+            <input type="text" name="keyword" class="search-query search-query-input" value="{$keyword}">
+            <input type="hidden" name="item_id" value="{$item.item_id}">
+            <button type="submit" class="btn"><i class="icon-search"></i></button>
+          </div>
+        </form>
+
+      <!-- 新建栏 -->
+      <div class="doc-left-newbar">
+
+        <if condition="$ItemPermn && !$item['is_archived']">
+          <div><a title="{$Think.Lang.new_page}" href="{:U('Home/Page/edit',array('item_id'=>$item['item_id'],'type'=>'new'))}" id="new-like"><i class="icon-plus"></i>&nbsp;</a>
+            <a title="{$Think.Lang.new_or_edit_catalog}" href="{:U('Home/Catalog/edit',array('item_id'=>$item['item_id']))}" id="dir-like" ><i class="icon-folder-open"></i></a>
+          </div>
+        </if>
+
+      </div>
+
+      <ul class="nav nav-list bs-docs-sidenav">
+
+        <!-- 一级目录的页面在前面 -->
+        <foreach name="pages" item="page">
+          <li ><a href="{:U('Home/Page/index',array('page_id'=>$page['page_id']))}" data-page-id="{$page.page_id}" ><i class="icon-blank"></i>{$page.page_title}</a></li>
+        </foreach>
+
+        <foreach name="catalogs" item="catalog">
+
+        
+          <li><a class="show_cut_title" href="#" title="{$catalog.cat_name}"><i class="icon-chevron-right"></i>{$catalog.cat_name}</a>
+            <ul class="child-ul nav-list hide">
+              <!-- 二级目录的页面们 -->
+              <foreach name="catalog.pages" item="catalog_page">
+                <li><a href="{:U('Home/Page/index',array('page_id'=>$catalog_page['page_id']))}" data-page-id="{$catalog_page.page_id}" >{$catalog_page.page_title}</a></li>
+              </foreach>
+              <!-- 二级目录的子目录们(三级目录) -->
+                <foreach name="catalog.catalogs" item="catalog3">   
+                  <li class="third-child-catalog"><a <a class="show_cut_title" href="#" title="{$catalog3.cat_name}"><i class="icon-chevron-right"></i>{$catalog3.cat_name}</a>
+                    <ul class="child-ul nav-list hide">
+                      <!-- 二级目录的页面们 -->
+                      <foreach name="catalog3.pages" item="catalog3_page">
+                        <li><a href="{:U('Home/Page/index',array('page_id'=>$catalog3_page['page_id']))}" data-page-id="{$catalog3_page.page_id}" >{$catalog3_page.page_title}</a></li>
+                      </foreach>
+                    </ul>
+                  </li>
+
+                </foreach>
+
+            </ul>
+          </li>
+
+        </foreach>
+
+      </ul>
+
+
+      <input type="hidden" id="item_id" value="{$item.item_id}">
+      <input type="hidden" id="item_domain" value="{$item.item_domain}">
+      <input type="hidden" id="current_page_id" value="{$current_page_id}">
+      <input type="hidden" id="base_url" value="__APP__">
+
+
+    </div>
+    <div class="doc-right  span12 ">
+      <!-- 编辑栏 -->
+      <div class='page-edit-link pull-right hide'>
+        <ul class="inline">
+            <li><a class="btn btn-link" href="" id="share-page" title="{$Think.Lang.share_address_to_your_friends}">{$Think.Lang.share}</a></li>
+          <if condition="$ItemPermn && !$item['is_archived']">
+                  <li><a class="btn btn-link" href="" id="edit-link" title="{$Think.Lang.edit_interface}">{$Think.Lang.edit}</a></li>
+            <li>
+              <div class="btn-group">
+                  <a class="btn btn-link dropdown-toggle" data-toggle="dropdown" href="#">
+                    更多              <span class="caret"></span>
+                  </a>
+                <ul class="dropdown-menu left-dropdown-menu">
+                <!-- dropdown menu links -->
+                  <li><a href="" id="copy-link" title="{$Think.Lang.copy_interface_to_new}">{$Think.Lang.copy}</a></li>
+                  <li><a href="" data-page_id= "0" class="show_page_info" title="详情">详情</a></li>
+                  <li><a href="" title="{$Think.Lang.delete_interface}"  id="delete-link">{$Think.Lang.delete}</a></li>
+
+                </ul>
+              </div>
+            </li>
+          <else />
+              <li><a href="" data-page_id= "0" class="show_page_info" title="详情">详情</a></li>
+        </if>
+        </ul>
+      </div>
+      <!-- 页面内容 -->
+      <div class='iframe_content'>
+        <iframe id="page-content" width="100%" scrolling="yes"  height="100%" frameborder="0" style=" overflow:visible; height:100%;" name="main"  seamless ="seamless"src=""></iframe>
+      </div>
+
+    </div>
+
+<include file="Common/footer" />
+<!-- 分享项目框 -->
+<div class="modal hide fade" id="share-modal">
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h3>{$Think.Lang.share}</h3>
+  </div>
+  <div class="modal-body">
+  <div class="modal-body" style="text-align: center;">
+    <p>{$Think.Lang.item_address}:<code id="share-item-link">{$share_url}</code>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" id="copy-item-link">复制链接</a>
+  </p>
+    <p style="border-bottom: 1px solid #eee;"><img  alt="二维码" style="width:114px;height:114px;" src="?s=home/common/qrcode&size=3&url={$share_url}"> </p>
+  </div>
+
+  </div>
+</div>
+
+<!-- 分享页面框 -->
+<div class="modal hide fade" id="share-page-modal">
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h3>{$Think.Lang.share_page}</h3>
+  </div>
+  <div class="modal-body" style="text-align: center;">
+    <p>项目页面地址:<code id="share-page-link"></code>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" id="copy-page-link">复制链接</a>
+  </p>
+      <p style="border-bottom: 1px solid #eee;"><img  alt="二维码" id="qr-page-link" style="width:114px;height:114px;" src="?s=home/common/qrcode&size=3&url="> </p>
+      
+    <p >单页面地址:<code id="share-single-link"></code>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" id="copy-single-link">复制链接</a>
+    </p>
+      <p style="border-bottom: 1px solid #eee;"><img  alt="二维码" id="qr-single-link" style="width:114px;height:114px;" src="?s=home/common/qrcode&size=3&url="> </p>
+   <p><a href="https://www.showdoc.cc/page/63882" target="_blank">项目页面地址和单页面地址有什么区别?</a></p><p>
+    </p>
+  </div>
+</div>
+
+
+<script src="__PUBLIC__/js/jquery.bootstrap-growl.min.js"></script>
+<script src="__PUBLIC__/js/jquery.goup.min.js"></script>
+<script src="__PUBLIC__/js/jquery.hotkeys.js"></script>
+<script src="__PUBLIC__/jquery.zclip/jquery.zclip.js"></script>
+
+<script src="__PUBLIC__/js/item/show.js?v=1.212123456789012345678"></script>

+ 89 - 0
Application/Home/View/Item/show_single_page.html

@@ -0,0 +1,89 @@
+<include file="Common/header" />
+<link href="__PUBLIC__/highlight/default.min.css" rel="stylesheet"> 
+<link href="__PUBLIC__/lightbox/css/lightbox.css?v=1.1234567" rel="stylesheet"> 
+<link rel="stylesheet" href="__PUBLIC__/css/item/show_single_page.css?v=2" />
+
+<div id="header">
+
+</div>
+<div class="container doc-container">
+   <div class="doc-title-box">
+      <span id="doc-title-span" class="dn"></span>
+      <h3 id="doc-title">{$page.page_title}</h3>
+      <ul class="tool-bar inline pull-right">
+        <li><a href="#" id="share">分享</a></li> 
+        <if condition="$ItemPermn">
+
+            <if condition="!$item['is_archived']">
+                <li><a href="?s=/home/page/edit/page_id/{$page.page_id}">编辑</a></li>
+              </if>
+        <li>
+            <div class="btn-group ">
+              <a class="btn btn-link dropdown-toggle" data-toggle="dropdown" href="#">
+                {$Think.Lang.item}
+                <span class="caret"></span>
+              </a>
+            <ul class="dropdown-menu">
+            <!-- dropdown menu links -->
+               <li><a href="{:U('Home/Item/export',array('item_id'=>$item['item_id']))}">{$Think.Lang.export}</a></li>
+             <if condition="$ItemCreator">
+                <li><a href="{:U('Home/Item/setting',array('item_id'=>$item['item_id']))}">项目设置</a></li>          
+              </if>
+              <li><a href="{:U('Home/Item/index')}" >{$Think.Lang.goback}</a></li>
+            </ul>
+        </li>
+        <else />
+
+          
+        </if>
+
+      </ul>
+
+      
+
+  </div>
+  <div id="doc-body" >
+
+  <div id="page_md_content" ><textarea style="display:none;">{$page.page_content}</textarea></div>
+
+    </textarea>
+  </div>
+
+</div>
+  <div id="footer">
+    <if condition="! $login_user">
+      <div id="copyright-text">本页面使用<a href="https://www.showdoc.cc/">showdoc</a>编写
+    </if>
+    </div>
+  </div>
+
+<!-- 分享项目框 -->
+<div class="modal hide fade" id="share-modal">
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h3>{$Think.Lang.share}</h3>
+  </div>
+  <div class="modal-body">
+  <div class="modal-body" style="text-align: center;">
+    <p>{$Think.Lang.item_address}:<code id="share-item-link">{$share_url}</code>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" id="copy-item-link">复制链接</a>
+  </p>
+    <p style="border-bottom: 1px solid #eee;"><img  alt="二维码" style="width:114px;height:114px;" src="?s=home/common/qrcode&size=3&url={$share_url}"> </p>
+  </div>
+
+  </div>
+</div>
+ <include file="Common/footer" />
+ <script src="__PUBLIC__/highlight/highlight.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/marked.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/prettify.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/flowchart.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/raphael.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/underscore.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/sequence-diagram.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/jquery.flowchart.min.js"></script>
+ <script src="__PUBLIC__/editor.md/editormd.min.js"></script>
+ <script src="__PUBLIC__/js/jquery.goup.min.js"></script>
+ <script src="__PUBLIC__/lightbox/js/lightbox.js?a=abc"></script>
+<script src="__PUBLIC__/jquery.zclip/jquery.zclip.js"></script>
+<script src="__PUBLIC__/js/jquery.bootstrap-growl.min.js"></script>
+<script src="__PUBLIC__/js/item/show_single_page.js?a=ab"></script>

+ 71 - 0
Application/Home/View/Item/showbyuid.html

@@ -0,0 +1,71 @@
+<include file="Common/header" />
+<link rel="stylesheet" href="__PUBLIC__/css/item/index.css" />
+<style type="text/css">
+  .container-thumbnails{
+    margin-top: 60px;
+  }
+  .thumbnails li a{
+    color: #888;
+    font-weight: bold;
+  }
+  .thumbnails li a:hover,
+  .thumbnails li a:focus{
+    border-color:#f2f5e9;
+    -webkit-box-shadow:none;
+    box-shadow:none;
+    text-decoration: none;
+    background-color: #f2f5e9;
+  }
+</style>
+    <div class="container-narrow">
+
+      <div class="masthead">
+        <div class="btn-group pull-right">
+        <a class="btn btn-primary dropdown-toggle" data-toggle="dropdown" href="#">
+        {$Think.Lang.more}
+        <span class="caret"></span>
+        </a>
+        <ul class="dropdown-menu">
+        <!-- dropdown menu links -->
+          <if condition="$login_user">
+            <li><a href="{:U('Home/Item/Index')}">{$Think.Lang.my_item}</a></li>
+            <else />
+             <li><a href="{:U('Home/User/login')}">{$Think.Lang.login_or_register}</a></li> 
+          </if>
+          
+          
+          <li><a href="{$help_url}" target="_blank">{$Think.Lang.about_showdoc}</a></li>
+
+        </ul>
+        </div>
+
+        </ul>
+        <h3 class="muted">{$show_user.username}{$Think.Lang.all_pubilc_item}</h3>
+      </div>
+
+      <hr>
+
+    <div class="container-thumbnails">
+      <ul class="thumbnails">
+
+        <foreach name="items" item="item">
+          <li class="span3 text-center">
+            <a class="thumbnail" href="{:U('Home/Item/show',array('item_id'=>$item['item_id']))}" target="_blank" title="{$item.item_description}">
+              <p class="my-item">{$item.item_name}</p>
+            </a>
+          </li>     
+        </foreach>
+
+
+      </ul>
+    </div>
+
+
+    </div> <!-- /container -->
+
+
+ <include file="Common/footer" />
+ <script type="text/javascript">
+
+
+ </script>

+ 44 - 0
Application/Home/View/MdTemplate/api-doc.en-us.html

@@ -0,0 +1,44 @@
+
+**A brief description:** 
+
+- interface for registering
+
+**Request url:** 
+- ` http://xx.com/api/user/register `
+  
+**Method:**
+- POST 
+
+**Request params:** 
+
+|Param|Required|Type|Description|
+|:----    |:---|:----- |-----   |
+|username |yes  |string |your usernem   |
+|password |yes  |string | your password    |
+|name     |yes  |string | your name    |
+
+ **A sample of result **
+
+``` 
+  {
+    "error_code": 0,
+    "data": {
+      "uid": "1",
+      "username": "12154545",
+      "name": "Jim",
+      "groupid": 2 ,
+      "reg_time": "1436864169",
+      "last_login_time": "0",
+    }
+  }
+```
+
+ **Result params** 
+
+|Param|Type|Description|
+|:-----  |:-----|-----                           |
+|groupid |int   | none |
+
+ **Remarks** 
+
+- See the home page for more 

+ 45 - 0
Application/Home/View/MdTemplate/api-doc.zh-cn.html

@@ -0,0 +1,45 @@
+
+**简要描述:** 
+
+- 用户注册接口
+
+**请求URL:** 
+- ` http://xx.com/api/user/register `
+  
+**请求方式:**
+- POST 
+
+**参数:** 
+
+|参数名|必选|类型|说明|
+|:----    |:---|:----- |-----   |
+|username |是  |string |用户名   |
+|password |是  |string | 密码    |
+|name     |否  |string | 昵称    |
+
+ **返回示例**
+
+``` 
+  {
+    "error_code": 0,
+    "data": {
+      "uid": "1",
+      "username": "12154545",
+      "name": "吴系挂",
+      "groupid": 2 ,
+      "reg_time": "1436864169",
+      "last_login_time": "0",
+    }
+  }
+```
+
+ **返回参数说明** 
+
+|参数名|类型|说明|
+|:-----  |:-----|-----                           |
+|groupid |int   |用户组id,1:超级管理员;2:普通用户  |
+
+ **备注** 
+
+- 更多返回错误代码请看首页的错误代码描述
+

+ 12 - 0
Application/Home/View/MdTemplate/database.en-us.html

@@ -0,0 +1,12 @@
+
+-  User table , for storing the user information
+
+|Field|Type|Allow empty|Default|Comment|
+|:----    |:-------    |:--- |-- -|------      |
+|uid      |int(10)     |no   |    |             |
+|username |varchar(20) |no   |    |   your username    |
+|password |varchar(50) |no   |    |   your password      |
+|name     |varchar(15) |yes   |    |    your name     |
+|reg_time |int(11)     |yes  | 0  |   register time  |
+
+- Remarks:none

+ 13 - 0
Application/Home/View/MdTemplate/database.zh-cn.html

@@ -0,0 +1,13 @@
+
+-  用户表,储存用户信息
+
+|字段|类型|空|默认|注释|
+|:----    |:-------    |:--- |-- -|------      |
+|uid	  |int(10)     |否	|	 |	           |
+|username |varchar(20) |否	|    |	 用户名	|
+|password |varchar(50) |否   |    |	 密码		 |
+|name     |varchar(15) |是   |    |    昵称     |
+|reg_time |int(11)     |否   | 0  |   注册时间  |
+
+- 备注:无
+

+ 57 - 0
Application/Home/View/Member/edit.html

@@ -0,0 +1,57 @@
+<include file="Common/header" />
+<style type="text/css">
+.single-cat{
+  margin: 10px;
+
+}
+</style>
+ <div id="edit-cat" class="modal hide fade">
+  <!-- 编辑框 -->
+  <div class="cat-edit">
+      <div class="modal-header">
+      <h4>{$Think.Lang.new_member}</h4>
+      </div>
+      <input type="hidden" id="item_id" value="{$item_id}">
+      <div class="add-cat">
+          <form class="form-horizontal">
+            <div class="control-group">
+              <label class="control-label" for="inputEmail">{$Think.Lang.username}</label>
+              <div class="controls">
+                <input type="text" id="username" placeholder="{$Think.Lang.username}" value="">
+              </div>
+            </div>
+            <div class="control-group">
+              <div class="controls">
+                <label class="checkbox">
+                  <input type="checkbox" id="member_group_id">{$Think.Lang.member_group_id}
+                </label>
+              </div>
+            </div>
+            <div class="control-group">
+              <div class="controls">
+                <button type="submit" class="btn" id="save-cat">{$Think.Lang.save}</button>
+              </div>
+            </div>
+          </form>
+
+      </div>
+    </div>
+  <!-- 成员列表 -->
+  <div class="cat-list">
+    <div class="modal-header">
+    <h4>{$Think.Lang.member_list}&nbsp;<small>({$Think.Lang.click_to_delete})</small></h4>
+    </div>
+    <div id="show-cat">
+
+    <br>
+    <br>
+    </div>
+  </div>
+
+    <div class="modal-footer">
+      <a href="#" class="btn exist-cat">{$Think.Lang.close}</a>
+    </div>
+ </div>
+
+ <include file="Common/footer" />
+<script src="__PUBLIC__/js/member/edit.js?v=12"></script>

+ 89 - 0
Application/Home/View/Page/diff.html

@@ -0,0 +1,89 @@
+<include file="Common/header" />
+<link href="__PUBLIC__/diff/diffview.css" rel="stylesheet"> 
+
+<style type="text/css">
+body {
+	font-size: 12px;
+	font-family: Sans-Serif;
+}
+h2 {
+	margin: 0.5em 0 0.1em;
+	text-align: center;
+}
+.top {
+	text-align: center;
+}
+.textInput {
+	display: block;
+	width: 49%;
+	float: left;
+	display: none;
+}
+textarea {
+	width:100%;
+	height:300px;
+}
+label:hover {
+	text-decoration: underline;
+	cursor: pointer;
+}
+.spacer {
+	margin-left: 10px;
+}
+.viewType {
+	font-size: 16px;
+	clear: both;
+	text-align: center;
+	padding: 1em;
+}
+#diffoutput {
+    width: 835px;
+    margin: 0 auto;
+}
+</style>
+
+<!-- <h1 class="top"><a href="http://github.com/cemerick/jsdifflib">jsdifflib</a> demo</h1> -->
+
+<div class="textInput">
+	<h2>{$Think.Lang.cur_page_content}</h2>
+	<textarea id="baseText">{$cur_page_content}</textarea>
+</div>
+<div class="textInput spacer">
+	<h2>{$Think.Lang.history_page_content}</h2>
+	<textarea id="newText">{$history_page_content}</textarea>
+</div>
+
+<div id="diffoutput"> </div>
+
+ <include file="Common/footer" />
+
+ <script src="__PUBLIC__/diff/diffview.js"></script> 
+ <script src="__PUBLIC__/diff/difflib.js"></script> 
+<script type="text/javascript">
+
+$(function(){
+	diffUsingJS(0);
+});
+
+function diffUsingJS(viewType) {
+	"use strict";
+	var byId = function (id) { return document.getElementById(id); },
+		base = difflib.stringAsLines(byId("baseText").value),
+		newtxt = difflib.stringAsLines(byId("newText").value),
+		sm = new difflib.SequenceMatcher(base, newtxt),
+		opcodes = sm.get_opcodes(),
+		diffoutputdiv = byId("diffoutput")
+
+	diffoutputdiv.innerHTML = "";
+
+	diffoutputdiv.appendChild(diffview.buildView({
+		baseTextLines: base,
+		newTextLines: newtxt,
+		opcodes: opcodes,
+		baseTextName: "{$Think.Lang.cur_page_content}",
+		newTextName: "{$Think.Lang.history_page_content}",
+		viewType: viewType
+	}));
+}
+
+</script>

+ 148 - 0
Application/Home/View/Page/edit.html

@@ -0,0 +1,148 @@
+<include file="Common/header" />
+<link rel="stylesheet" href="__PUBLIC__/editor.md/css/editormd.css" />
+<link rel="stylesheet" href="__PUBLIC__/css/page/edit.css?1.1thirdef" />
+
+<div id="layout">
+    <!-- 顶部条 -->
+    <header class="row">
+        <div class="head-left  pull-left">
+            <ul class="inline">
+                <li>
+                    <input type="text" name="page_title" id="page_title" placeholder="{$Think.Lang.input_page_title}" value="{$page.page_title}" tabindex="1">
+                </li>
+                <li>
+                    {$Think.Lang.level_2_directory}:
+                    <select name="cat_id" id="cat_id" tabindex="2"></select>
+                </li>
+                <li id="li_parent_cat">
+                    {$Think.Lang.level_3_directory}:
+                    <select name="parent_cat_id" id="parent_cat_id" tabindex="3"></select>
+                </li>
+                <li>
+                    <input type="text" name="s_number" id="s_number" value="{$page.s_number}" placeholder="{$Think.Lang.s_number_explain}" title="{$Think.Lang.s_number_explain}"  tabindex="4" >
+                </li>
+                <li>
+                    <!-- 首次添加没有历史版本,不显示 -->
+                    <if condition="$page.page_id gt 0">
+                        <a href="?s=home/page/history&page_id={$page.page_id}">{$Think.Lang.history_version}</a>
+                        <else />
+                    </if>
+                </li>
+            </ul>
+        </div>
+        <div class="head-right pull-right">
+            <!-- <a href="#" class="btn btn-primary " id="save">{$Think.Lang.save}</a> -->
+            <div class="btn-group" id="save-btn-group"> 
+                <button class="btn btn-primary" id="save">{$Think.Lang.save}</button>
+                <button class="btn btn-primary dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
+                <ul class="dropdown-menu" >
+                    <li><a href="#" id="add-page-comments">{$Think.Lang.add_page_comments}</a></li>
+                    <li><a href="#" id="save-to-templ">{$Think.Lang.save_to_templ}</a></li>
+                </ul>
+            </div>
+
+            <a href="?s=home/item/show&item_id={$item_id}&page_id={$page.page_id}" class="btn cancel">{$Think.Lang.cancel}</a>
+        </div>
+    </header>
+    <br>
+    <!-- 插入模板的按钮组 -->
+    <div class="btns">
+        <button id="api-doc" tabindex="5" >{$Think.Lang.inser_apidoc_template}</button>
+        <button id="database-doc" tabindex="6" >{$Think.Lang.inser_database_doc_template}</button>
+        <button id="more-templ" tabindex="7" >{$Think.Lang.more_templ}</button>
+<!--         <button id="jsons" tabindex="8" style="margin-left: 100px;">{$Think.Lang.json_to_table}</button> -->
+        <div class="btn-group" style="margin-left: 100px;">
+          <a class="btn dropdown-toggle" id="json-tools-btn" data-toggle="dropdown" tabindex="8" href="#">
+           {$Think.Lang.json_tools}
+            <span class="caret"></span>
+          </a>
+          <ul class="dropdown-menu">
+                <li><a id="jsons" >{$Think.Lang.json_to_table}</a></li>
+                <li><a id="beautify-json" >{$Think.Lang.beautify_json}</a></li>
+          </ul>
+        </div>
+        <a href="http://runapi.showdoc.cc/" target="_blank" class="btn" tabindex="9" id="runapi">{$Think.Lang.http_test_api}</a>
+    </div>
+    <div id="editormd">
+        <textarea id="page_content" style="display:none;" tabindex="10" >{$page.page_content}</textarea>
+    </div>
+    <input type="hidden" id="item_id" value="{$item_id}">
+    <input type="hidden" id="page_id" value="{$page.page_id}">
+    <input type="hidden" id="page_comments" value="">
+    <input type="hidden" id="default_second_cat_id" value="{$default_second_cat_id}">
+    <input type="hidden" id="default_child_cat_id" value="{$default_child_cat_id}">
+</div>
+<!-- 模板存放的地方 -->
+<div id="api-doc-templ" style="display:none">
+    <include file="$api_doc_templ" />
+</div>
+<div id="database-doc-templ" style="display:none">
+    <include file="$database_doc_templ" />
+</div>
+
+<div id="json-templ" class="editormd-dialog editormd-preformatted-text-dialog" style="width: 780px; height: 540px;">
+
+    <div style="cursor: move;" class="editormd-dialog-header">
+        <strong class="editormd-dialog-title">{$Think.Lang.json_to_table}</strong>
+    </div>
+    <a class="fa fa-close editormd-dialog-close" href="javascript:closeDiv('#json-templ');"></a>
+    <div class="editormd-dialog-container">
+        <textarea id="jsons_add" class="jsons" placeholder="{$Think.Lang.json_to_table_description}"></textarea>
+        
+        <div class="editormd-dialog-footer">
+            <button class="editormd-btn editormd-enter-btn">{$Think.Lang.confirm}</button>
+            <button class="editormd-btn editormd-cancel-btn" onclick="closeDiv('#json-templ')">{$Think.Lang.cancel}</button>
+        </div>
+    </div>
+    <div class="editormd-dialog-mask editormd-dialog-mask-bg"></div><div class="editormd-dialog-mask editormd-dialog-mask-con"></div>
+</div>
+
+<div id="beautify-json-dialog" class="editormd-dialog editormd-preformatted-text-dialog" style="width: 780px; height: 540px;">
+
+    <div style="cursor: move;" class="editormd-dialog-header">
+        <strong class="editormd-dialog-title">{$Think.Lang.beautify_json}</strong>
+    </div>
+    <a class="fa fa-close editormd-dialog-close" href="javascript:closeDiv('#beautify-json-dialog');"></a>
+    <div class="editormd-dialog-container">
+        <textarea id="beautify-jsons-content" class="jsons" placeholder="{$Think.Lang.beautify_json_description}"></textarea>
+        
+        <div class="editormd-dialog-footer">
+            <button class="editormd-btn editormd-enter-btn">{$Think.Lang.confirm}</button>
+            <button class="editormd-btn editormd-cancel-btn" onclick="closeDiv('#beautify-json-dialog')">{$Think.Lang.cancel}</button>
+        </div>
+    </div>
+    <div class="editormd-dialog-mask editormd-dialog-mask-bg"></div><div class="editormd-dialog-mask editormd-dialog-mask-con"></div>
+</div>
+
+ <div id="more-templ-modal" class="modal hide fade">
+  <div class="modal-header">
+    <h4>{$Think.Lang.saved_templ_list}</h4>
+  </div>
+  <table class="table table-hover" id="templ-table">
+
+
+  </table>
+
+    <div class="modal-footer">
+        <button class="btn" data-dismiss="modal" aria-hidden="true">{$Think.Lang.close}</button>
+    </div>
+ </div>
+
+<include file="Common/footer" />
+<script src="__PUBLIC__/js/xss.min.js"></script>
+<script src="__PUBLIC__/js/jquery.bootstrap-growl.min.js"></script>
+<script src="__PUBLIC__/js/jquery.hotkeys.js"></script>
+<script src="__PUBLIC__/editor.md/editormd.js"></script>
+<script src="__PUBLIC__/editor.md/plugins/image-dialog/image-dialog.js"></script>
+<script src="__PUBLIC__/editor.md/plugins/link-dialog/link-dialog.js"></script>
+<script src="__PUBLIC__/editor.md/plugins/preformatted-text-dialog/preformatted-text-dialog.js"></script>
+<script src="__PUBLIC__/editor.md/plugins/code-block-dialog/code-block-dialog.js"></script>
+<script src="__PUBLIC__/editor.md/plugins/html-entities-dialog/html-entities-dialog.js"></script>
+<script src="__PUBLIC__/editor.md/plugins/goto-line-dialog/goto-line-dialog.js"></script>
+<script src="__PUBLIC__/editor.md/plugins/table-dialog/table-dialog.js"></script>
+<script src="__PUBLIC__/editor.md/plugins/reference-link-dialog/reference-link-dialog.js"></script>
+
+<script src="__PUBLIC__/js/page/edit.js?v=1.1.2thirdonmopqrstutv1234"></script>
+<if condition="LANG_SET=='en-us'">
+    <script src="__PUBLIC__/editor.md/languages/en.js"></script>
+</if>

+ 47 - 0
Application/Home/View/Page/history.html

@@ -0,0 +1,47 @@
+<include file="Common/header" />
+<style type="text/css">
+.single-cat{
+  margin: 10px;
+
+}
+#edit-cat{
+  width: 750px;
+}
+</style>
+ <div id="edit-cat" class="modal hide fade">
+  <div class="modal-header">
+    <h4>{$Think.Lang.history_version}</h4>
+  </div>
+  <table class="table table-hover">
+    <TR>
+      <td>{$Think.Lang.update_time}</td>
+      <td>{$Think.Lang.update_by_who}</td>
+      <td>{$Think.Lang.page_comments}</td>
+      <td>{$Think.Lang.operation}</td>
+    </TR>
+    <if condition="$PageHistory">
+      <foreach name="PageHistory" item="value">
+      <TR>
+        <td>{$value.addtime}</td>
+        <td>{$value.author_username}</td>
+        <td>{$value.page_comments}</td>
+        <td> <a href="?s=home/page/diff&page_id={$page_id}&page_history_id={$value.page_history_id}" target="_blank">{$Think.Lang.overview}</a> | <a href="?s=home/page/edit&page_id={$page_id}&page_history_id={$value.page_history_id}">{$Think.Lang.recover_to_this_version}</a></td>
+      </TR>
+
+      </foreach>
+    </if>
+  </table>
+
+    <div class="modal-footer">
+      <a href="?s=home/page/edit&page_id={$page_id}" class="btn exist-cat">{$Think.Lang.close}</a>
+      <a href="?s=home/page/edit&page_id={$page_id}" class="btn btn-primary exist-cat">{$Think.Lang.finish}</a>
+    </div>
+ </div>
+<input type="hidden" id="page_id" value="{$page_id}">
+ <include file="Common/footer" />
+ <script type="text/javascript">
+ $(function(){
+   $('#edit-cat').modal();
+ })
+
+ </script>

+ 21 - 0
Application/Home/View/Page/index.html

@@ -0,0 +1,21 @@
+<include file="Common/header" />
+<link href="__PUBLIC__/highlight/default.min.css" rel="stylesheet"> 
+<link href="__PUBLIC__/css/page/index.css?v=1.123456" rel="stylesheet">
+<h3 id="page_title"></h3>
+<!-- 这里开始是内容 -->
+<div id="page_md_content" ><textarea style="display:none;"></textarea></div>
+<input type="hidden" id="page_id" value="{$page_id}"> 
+<div id="page_html_content" style="display:none;"></div>
+
+ <include file="Common/footer" />
+ <script src="__PUBLIC__/js/xss.min.js"></script>
+ <script src="__PUBLIC__/highlight/highlight.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/marked.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/prettify.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/flowchart.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/raphael.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/underscore.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/sequence-diagram.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/jquery.flowchart.min.js"></script>
+ <script src="__PUBLIC__/editor.md/editormd.js"></script>
+ <script src="__PUBLIC__/js/page/index.js?a=abcedefgh12"></script>

+ 152 - 0
Application/Home/View/Page/single.html

@@ -0,0 +1,152 @@
+<include file="Common/header" />
+<link href="__PUBLIC__/highlight/default.min.css" rel="stylesheet"> 
+<link href="__PUBLIC__/lightbox/css/lightbox.css?v=1.1234567" rel="stylesheet"> 
+
+<style type="text/css">
+body{
+    background: #F1F0F1;
+    height: auto;
+    overflow: auto;
+    margin: 0 auto;
+}
+
+#page_md_content{
+	
+    padding: 11px 0 90px 0;
+    overflow: hidden;
+    font-size: 11pt;
+    line-height: 1.7;
+    color: #333;
+}
+#doc-body{
+	background-color: #fff;
+}
+
+.doc-container {
+    position: static;
+    -webkit-box-shadow: 0px 1px 6px #ccc;
+    -moz-box-shadow: 0px 1px 6px #ccc;
+    -ms-box-shadow: 0px 1px 6px #ccc;
+    -o-box-shadow: 0px 1px 6px #ccc;
+    box-shadow: 0px 1px 6px #ccc;
+    background-color: #fff;
+    border-bottom: 1px solid #d9d9d9;
+    margin-bottom: 20px;
+    width: 800px;
+    min-height: 500px;
+}
+
+#header{
+	height: 80px;
+}
+
+#doc-body{
+	width: 600px;
+  margin: 0 auto;
+}
+
+.doc-title-box{
+    height: auto;
+    margin: 30px 100px 10px 100px;
+    width: auto;
+    border-bottom: 1px solid #ebebeb;
+    padding-bottom: 10px;
+}
+#footer{
+	  margin: 0 auto;
+    width: 180px;
+    font-size: 8px;
+    color: #959595;
+}
+	
+pre ol{
+  list-style: none;
+}
+	
+.markdown-body pre {
+  background-color: #f7f7f9;
+  border: 1px solid #e1e1e8;
+}
+.hljs{
+  background-color: #f7f7f9;
+}
+</style>
+
+<div id="header"></div>
+<div class="container doc-container">
+   <div class="doc-title-box">
+    	<span id="doc-title-span" class="dn"></span>
+    	<h3 id="doc-title"></h3>
+  </div>
+  <div id="doc-body" >
+
+	<div id="page_md_content" ><textarea style="display:none;"></textarea></div>
+
+  	</textarea>
+  </div>
+
+</div>
+  <div id="footer">
+    <if condition="! $login_user">
+      <div id="copyright-text">本页面使用<a href="https://www.showdoc.cc/">showdoc</a>编写
+    </if>
+  </div>
+
+<input type="hidden" id="page_id" value="{$page_id}"> 
+ <include file="Common/footer" />
+ <script src="__PUBLIC__/js/xss.min.js"></script>
+ <script src="__PUBLIC__/highlight/highlight.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/marked.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/prettify.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/flowchart.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/raphael.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/underscore.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/sequence-diagram.min.js"></script>
+ <script src="__PUBLIC__/editor.md/lib/jquery.flowchart.min.js"></script>
+ <script src="__PUBLIC__/editor.md/editormd.js"></script>
+ <script src="__PUBLIC__/js/jquery.goup.min.js"></script>
+ <script src="__PUBLIC__/lightbox/js/lightbox.js?a=abc"></script>
+
+<script src="__PUBLIC__/js/page/index.js?a=ab1"></script>
+<script type="text/javascript">
+$(function(){
+    //增加返回顶部按钮
+    $.goup({
+          trigger: 100,
+          bottomOffset: 150,
+          locationOffset: 100,
+          title: lang["back_to_top"] ,
+          titleAsText: true,
+          containerColor:"#08c",
+      });
+
+    if( isMobile() || $(window).width() < 1000){
+          AdaptToMobile();
+      }
+
+    $(window).resize(function(){
+      if( isMobile()){
+          AdaptToMobile();
+      }
+
+      else if($(window).width() < 1000){
+          AdaptToMobile();
+      }else{
+        window.location.reload();
+      }
+    });
+
+});
+
+
+  function AdaptToMobile(){
+    $(".doc-container").css("width","90%");
+    $("#doc-body").css("width","90%");
+    $("#header").css("height","20px");
+    $(".doc-title-box").css("margin","20px 20px 0px 20px");
+    $("#footer").css("font-size","11pt");
+
+  }
+
+
+</script>

+ 67 - 0
Application/Home/View/User/login.html

@@ -0,0 +1,67 @@
+<include file="Common/header" />
+<link rel="stylesheet" href="__PUBLIC__/css/login.css" />
+
+    <div class="container">
+
+      <form class="form-signin myform card" method="post" action="server/index.php?s=/api/user/login">
+        <h3 class="form-signin-heading heading">{$Think.Lang.login}</h3>
+        <input type="text" class="input-block-level"  name="username" placeholder="{$Think.Lang.username}">
+        <input type="password" class="input-block-level" name="password" placeholder="{$Think.Lang.password}">
+        <if  condition="$CloseVerify != 1">
+        <input type="text" class="input-block-level" id="input_v_code" autocomplete="off" name="v_code" placeholder="{$Think.Lang.verification_code}">
+        <div class="control-group">
+          <div class="controls">
+            <img src="#" id="v_code_img">
+          </div>
+        </div>
+        </if>
+
+        <button class="btn btn-large btn-primary btn-block" type="submit">{$Think.Lang.login}</button>
+        <div class="form-group" style="text-align:center;margin-top:15px;">
+            <a href="?s=/home/user/register">{$Think.Lang.no_account}</a>
+        </div>
+      </form>
+
+    </div> <!-- /container -->
+
+
+<include file="Common/footer" />
+<script src="__PUBLIC__/js/jquery.form.min.js"></script>
+ <script type="text/javascript">
+ $(function(){
+    $("#input_v_code").hide();
+    $("#v_code_img").hide();
+    $("#v_code_img").attr("src" , DocConfig.pubile+'/verifyCode.php');
+
+    $("#v_code_img").click(function(){
+      var v_code_img = $("#v_code_img").attr("src");
+      $("#v_code_img").attr('src' ,v_code_img+'?'+Date.parse(new Date()) );
+    }); 
+
+    //上传表单参数
+    var ajax_option = {
+      dataType:"json",
+      beforeSubmit:function(){
+
+      },
+      success:function(res){
+        if (res.error_code === 0) {
+          window.location.href = "?s=/home/item/index";
+        }else{
+          $.alert(res.error_message);
+
+          if (res.error_code === 10206 || res.error_code === 10210 ) {
+            $("#v_code_img").click();
+            $("#v_code_img").show();
+            $("#input_v_code").show();
+          };
+          
+        }
+      }
+    };
+
+    $('.myform').ajaxForm(ajax_option); 
+
+
+ });
+ </script>

+ 58 - 0
Application/Home/View/User/register.html

@@ -0,0 +1,58 @@
+<include file="Common/header" />
+<link rel="stylesheet" href="__PUBLIC__/css/login.css" />
+
+    <div class="container">
+
+      <form class="form-signin myform card" method="post" action="server/index.php?s=api/user/register">
+        <h3 class="form-signin-heading heading">{$Think.Lang.register_new_account}</h3>
+        <input type="text" class="input-block-level" name="username" placeholder="{$Think.Lang.username_description}">
+        <input type="password" class="input-block-level" name="password"  placeholder="{$Think.Lang.password}">
+        <input type="password" class="input-block-level" name="confirm_password"  placeholder="{$Think.Lang.password_again}">
+        <if  condition="$CloseVerify != 1">
+        <input type="text" class="input-block-level" autocomplete="off" name="v_code"  placeholder="{$Think.Lang.verification_code}">
+        <div class="control-group">
+          <div class="controls">
+            <img src="#" id="v_code_img">
+          </div>
+        </div>
+        </if>
+        <button class="btn btn-large btn-primary btn-block" type="submit">{$Think.Lang.register}</button>
+        <div class="form-group" style="text-align:center;margin-top:15px;">
+            <a href="?s=/home/user/login">{$Think.Lang.had_a_account}</a>
+        </div>
+      </form>
+
+    </div> <!-- /container -->
+
+
+<include file="Common/footer" />
+<script src="__PUBLIC__/js/jquery.form.min.js"></script>
+ <script type="text/javascript">
+ $(function(){
+    $("#v_code_img").attr("src" , DocConfig.pubile+'/verifyCode.php');
+    $("#v_code_img").click(function(){
+      var v_code_img = $("#v_code_img").attr("src");
+      $("#v_code_img").attr('src' ,v_code_img+'?'+Date.parse(new Date()) );
+    }); 
+
+    //上传表单参数
+    var ajax_option = {
+      dataType:"json",
+      beforeSubmit:function(){
+
+      },
+      success:function(res){
+        if (res.error_code === 0) {
+          window.location.href = "?s=/home/item/index";
+        }else{
+          $.alert(res.error_message);
+          $("#v_code_img").click();
+        }
+      }
+    };
+
+    $('.myform').ajaxForm(ajax_option); 
+
+ });
+
+</script>

+ 19 - 0
Application/Home/View/User/setting.html

@@ -0,0 +1,19 @@
+<include file="Common/header" />
+<link rel="stylesheet" href="__PUBLIC__/css/login.css" />
+
+    <div class="container">
+
+      <form class="form-signin" method="post">
+        <h3 class="form-signin-heading">{$Think.Lang.update_personal_info}</h3>
+        <input type="text" class="input-block-level" value="{$user.username}" disabled >
+        <input type="password" class="input-block-level" name="new_password"  placeholder="{$Think.Lang.new_password_description}">
+        <input type="password" class="input-block-level" name="password"  placeholder="{$Think.Lang.old_password_description}">
+        <button class="btn  btn-primary" type="submit">{$Think.Lang.submit}</button>
+        <a href="javascript:history.go(-1)" class="btn">{$Think.Lang.goback}</a>
+      </form>
+
+    </div> <!-- /container -->
+
+
+ <include file="Common/footer" />
+

+ 1 - 0
Application/Home/View/index.html

@@ -0,0 +1 @@
+ 

+ 1 - 0
Application/Home/index.html

@@ -0,0 +1 @@
+ 

+ 1 - 0
Application/README.md

@@ -0,0 +1 @@
+项目目录

+ 1 - 0
Application/Runtime/index.html

@@ -0,0 +1 @@
+ 

+ 1 - 0
Application/index.html

@@ -0,0 +1 @@
+ 

+ 16 - 0
Dockerfile

@@ -0,0 +1,16 @@
+FROM php:5.6-apache
+COPY ./ /var/www/html/
+
+RUN  \
+		sed -i  's#http[:]//deb[^/ ]\+#http://ftp.cn.debian.org#g' /etc/apt/sources.list  && \
+		apt-get update && apt-get install -y \
+        libfreetype6-dev \
+        libjpeg62-turbo-dev \
+        libmcrypt-dev \
+        libpng12-dev \
+    && docker-php-ext-install -j$(nproc) gd mcrypt
+
+
+RUN chmod -R 777 /var/www/html/
+
+CMD ["apache2-foreground"]

+ 1 - 0
Public/README.md

@@ -0,0 +1 @@
+资源文件目录

+ 1 - 0
Public/Uploads/index.html

@@ -0,0 +1 @@
+ 

File diff suppressed because it is too large
+ 1109 - 0
Public/bootstrap/css/bootstrap-responsive.css


File diff suppressed because it is too large
+ 9 - 0
Public/bootstrap/css/bootstrap-responsive.min.css


File diff suppressed because it is too large
+ 6167 - 0
Public/bootstrap/css/bootstrap.css


File diff suppressed because it is too large
+ 9 - 0
Public/bootstrap/css/bootstrap.min.css


BIN
Public/bootstrap/img/glyphicons-halflings-white.png


BIN
Public/bootstrap/img/glyphicons-halflings.png


File diff suppressed because it is too large
+ 2280 - 0
Public/bootstrap/js/bootstrap.js


File diff suppressed because it is too large
+ 11 - 0
Public/bootstrap/js/bootstrap.min.js


+ 38 - 0
Public/css/index.css

@@ -0,0 +1,38 @@
+body {
+  padding-top: 20px;
+  padding-bottom: 40px;
+}
+
+/* Custom container */
+.container-narrow {
+  margin: 0 auto;
+  max-width: 700px;
+}
+.container-narrow > hr {
+  margin: 30px 0;
+}
+
+/* Main marketing message and sign up button */
+.jumbotron {
+  margin: 60px 0;
+  text-align: center;
+}
+.jumbotron h1 {
+  font-size: 72px;
+  line-height: 1;
+}
+.jumbotron .btn {
+  font-size: 21px;
+  padding: 14px 24px;
+}
+
+/* Supporting marketing content */
+.marketing {
+  margin: 60px 0;
+}
+.marketing p + h4 {
+  margin-top: 28px;
+}
+.markdown-body pre {
+  background-color: #f0f0f0;
+}

+ 51 - 0
Public/css/item/index.css

@@ -0,0 +1,51 @@
+body {
+  padding-top: 20px;
+  padding-bottom: 40px;
+}
+
+/* Custom container */
+.container-narrow {
+  margin: 0 auto;
+  max-width: 700px;
+}
+.container-narrow > hr {
+  margin: 30px 0;
+}
+.my-item{
+  margin: 40px 10px;
+}
+
+.container-thumbnails{
+margin-top: 60px;
+}
+.thumbnails li a{
+	color: #777;
+	font-weight: bold;
+	height: 100px;
+}
+.thumbnails li a:hover,
+.thumbnails li a:focus{
+	border-color:#f2f5e9;
+	-webkit-box-shadow:none;
+	box-shadow:none;
+	text-decoration: none;
+	background-color: #f2f5e9;
+}
+
+.masthead h3{
+  color: #333;
+}
+
+.item-setting{
+  float:right;
+  margin-right:15px;
+  margin-top:5px;
+  display: none;
+}
+
+.item-top{
+  float:right;
+  margin-right:5px;
+  margin-top:5px;
+  display: none;
+}

+ 171 - 0
Public/css/item/show.css

@@ -0,0 +1,171 @@
+  body,html,.doc-body{
+    height: 100%;
+  }
+  .doc-head{
+    padding-top: 5px;
+    padding-bottom: 5px;
+    padding-left: 10px;
+    border-bottom: 1px solid #eee;
+    position: fixed;
+    width: 100%;
+    background-color: #FFFFFF;
+    z-index: 999;
+    height: 40px;
+  }
+
+  .doc-head .left{
+    padding-left: 30px;
+    float: left;
+  }
+
+  .doc-head .right{
+    padding-top: 10px;
+    padding-right: 40px;
+  }
+  .doc-left{
+    width: 240px;
+    margin-top: 51px;
+    height: calc(100% - 60px);
+    border-right-color: rgb(221, 221, 221);
+    border-right-width: 1px;
+    border-right-style: solid;
+    overflow-y: auto;
+    display: block;
+    /*background: rgb(245, 245, 245);*/
+    position: fixed;
+  }
+  
+  .doc-left .form-search{
+    padding-top: 15px;
+  }
+
+  .doc-left ul li{
+    font-size: 16px;
+    line-height: 30px;
+  }
+  .doc-left ul li a{
+    color: #000;
+  }
+  .doc-left ul li a:hover ,.doc-left ul li a:focus{
+    color: #fff;
+    text-shadow: 0 -1px 0 rgba(0,0,0,0.2);
+    background-color: #08c;
+  }
+  .doc-right{
+    margin-top: 81px;
+    margin-left: 260px;
+  }
+  .child-ul{
+      list-style: none;
+      padding-left: 10px;
+  }
+  .child-ul li a {
+    padding: 3px 15px;
+    margin-right: -15px;
+    margin-left: -15px;
+    text-shadow: 0 1px 0 rgba(255,255,255,0.5);
+    display: block;
+    text-decoration: none;
+    font-size: 14px;
+    line-height: 25px;
+  }
+
+  .icon-blank{
+    padding-right: 4px;
+  }
+
+  .doc-left-newbar{
+    /*float: right;*/
+    margin-left: 180px;
+    margin-top: 10px;
+  }
+
+  .page-edit-link{
+    padding-top: 10px;
+  }
+  .iframe_content{
+    padding-left: 20px;
+    padding-right: 20px;
+    width: 80%;
+    max-width: 700px;
+    margin: 0 auto;
+  }
+
+  .search-query-input{
+    width: 140px;
+  }
+.third-child-catalog{
+  margin-left: -16px;
+}
+
+@media screen and (min-width:500px){
+  .doc-right{ width: 400px;} 
+}
+
+@media screen and (min-width:600px){
+  .doc-right{ width: 500px;} 
+}
+
+@media screen and (min-width:700px){
+  .doc-right{ width: 600px;} 
+}
+
+@media screen and (min-width:800px){
+  .doc-right{ width: 700px;} 
+}
+
+@media screen and (min-width:900px){
+  .doc-right{ width: 800px;} 
+}
+
+@media screen and (min-width:1000px){
+  .doc-right{ width: 700px;} 
+}
+
+@media screen and (min-width:1100px){
+  .doc-right{ width: 800px;} 
+}
+
+@media screen and (min-width:1200px){
+  .doc-right{ width: 900px;} 
+}
+@media screen and (min-width:1300px){
+  .doc-right{ width: 1000px;} 
+}
+@media screen and (min-width:1400px){
+  .doc-right{ width: 1100px;} 
+}
+@media screen and (min-width:1500px){
+  .doc-right{ width: 1200px;} 
+}
+@media screen and (min-width:1600px){
+  .doc-right{ width: 1300px;} 
+}
+@media screen and (min-width:1700px){
+  .doc-right{ width: 1400px;} 
+}
+@media screen and (min-width:1800px){
+  .doc-right{ width: 1500px;} 
+}
+@media screen and (min-width:1900px){
+  .doc-right{ width: 1600px;} 
+}
+
+.page-edit-link .btn-link{
+  padding-right: 4px;
+  padding-left: 4px;
+  margin-right: 0px;
+  margin-left: 0px;
+}
+
+.show_cut_title{
+  white-space:nowrap;
+  text-overflow:ellipsis; 
+  -o-text-overflow:ellipsis; 
+  overflow:hidden
+}
+
+.left-dropdown-menu{
+  left: auto;
+   right: 0;
+}

+ 83 - 0
Public/css/item/show_single_page.css

@@ -0,0 +1,83 @@
+body{
+    background: #F1F0F1;
+    height: auto;
+    overflow: auto;
+    margin: 0 auto;
+}
+
+#page_content{
+  
+    padding: 11px 0 90px 0;
+    overflow: hidden;
+    font-size: 11pt;
+    line-height: 1.7;
+    color: #333;
+}
+#doc-body{
+  background-color: #fff;
+}
+
+.doc-container {
+    position: static;
+    -webkit-box-shadow: 0px 1px 6px #ccc;
+    -moz-box-shadow: 0px 1px 6px #ccc;
+    -ms-box-shadow: 0px 1px 6px #ccc;
+    -o-box-shadow: 0px 1px 6px #ccc;
+    box-shadow: 0px 1px 6px #ccc;
+    background-color: #fff;
+    border-bottom: 1px solid #d9d9d9;
+    margin-bottom: 20px;
+    width: 800px;
+    min-height: 500px;
+
+}
+
+#header{
+  height: 80px;
+}
+
+#doc-body{
+  width: 600px;
+  margin: 0 auto;
+}
+
+.doc-title-box{
+    height: auto;
+    margin: 30px 100px 10px 100px;
+    width: auto;
+    border-bottom: 1px solid #ebebeb;
+    padding-bottom: 10px;
+}
+#footer{
+    margin: 0 auto;
+    width: 180px;
+    font-size: 8px;
+    color: #959595;
+}
+
+#doc-title{
+  display: inline-block;
+}
+
+.tool-bar{
+  font-size: 14px;
+  padding-top: 15px;
+}
+
+.tool-bar .btn-link{
+  padding: 0px;
+}
+.linenums li {
+    list-style-type: none;
+    line-height: 20px;
+}
+
+.markdown-body pre {
+    background-color: #fcfcfc;
+    border: 1px solid #e1e1e8;
+}
+
+.hljs{
+  padding:0.2em;
+  background-color: #fcfcfc;
+}

+ 182 - 0
Public/css/jquery.fullPage.css

@@ -0,0 +1,182 @@
+/**
+ * fullPage 2.4.6
+ * https://github.com/alvarotrigo/fullPage.js
+ * MIT licensed
+ *
+ * Copyright (C) 2013 alvarotrigo.com - A project by Alvaro Trigo
+ */
+html, body {
+    margin: 0;
+    padding: 0;
+    overflow:hidden;
+
+    /*Avoid flicker on slides transitions for mobile phones #336 */
+    -webkit-tap-highlight-color: rgba(0,0,0,0);
+}
+#superContainer {
+    height: 100%;
+    position: relative;
+
+    /* Touch detection for Windows 8 */
+    -ms-touch-action: none;
+
+    /* IE 11 on Windows Phone 8.1*/
+    touch-action: none;
+}
+.fp-section {
+    position: relative;
+    -webkit-box-sizing: border-box; /* Safari<=5 Android<=3 */
+    -moz-box-sizing: border-box; /* <=28 */
+    box-sizing: border-box;
+}
+.fp-slide {
+    float: left;
+}
+.fp-slide, .fp-slidesContainer {
+    height: 100%;
+    display: block;
+}
+.fp-slides {
+    z-index:1;
+    height: 100%;
+    overflow: hidden;
+    position: relative;
+    -webkit-transition: all 0.3s ease-out; /* Safari<=6 Android<=4.3 */
+    transition: all 0.3s ease-out;
+}
+.fp-section.fp-table, .fp-slide.fp-table {
+    display: table;
+    table-layout:fixed;
+    width: 100%;
+}
+.fp-tableCell {
+    display: table-cell;
+    vertical-align: middle;
+    width: 100%;
+    height: 100%;
+}
+.fp-slidesContainer {
+    float: left;
+    position: relative;
+}
+.fp-controlArrow {
+    position: absolute;
+    z-index: 4;
+    top: 50%;
+    cursor: pointer;
+    width: 0;
+    height: 0;
+    border-style: solid;
+    margin-top: -38px;
+}
+.fp-controlArrow.fp-prev {
+    left: 15px;
+    width: 0;
+    border-width: 38.5px 34px 38.5px 0;
+    border-color: transparent #fff transparent transparent;
+}
+.fp-controlArrow.fp-next {
+    right: 15px;
+    border-width: 38.5px 0 38.5px 34px;
+    border-color: transparent transparent transparent #fff;
+}
+.fp-scrollable {
+    overflow: scroll;
+
+}
+.fp-notransition {
+    -webkit-transition: none !important;
+    transition: none !important;
+}
+#fp-nav {
+    position: fixed;
+    z-index: 100;
+    margin-top: -32px;
+    top: 50%;
+    opacity: 1;
+}
+#fp-nav.right {
+    right: 17px;
+}
+#fp-nav.left {
+    left: 17px;
+}
+.fp-slidesNav{
+    position: absolute;
+    z-index: 4;
+    left: 50%;
+    opacity: 1;
+}
+.fp-slidesNav.bottom {
+    bottom: 17px;
+}
+.fp-slidesNav.top {
+    top: 17px;
+}
+#fp-nav ul,
+.fp-slidesNav ul {
+  margin: 0;
+  padding: 0;
+}
+#fp-nav ul li,
+.fp-slidesNav ul li {
+    display: block;
+    width: 14px;
+    height: 13px;
+    margin: 7px;
+    position:relative;
+}
+.fp-slidesNav ul li {
+    display: inline-block;
+}
+#fp-nav ul li a,
+.fp-slidesNav ul li a {
+    display: block;
+    position: relative;
+    z-index: 1;
+    width: 100%;
+    height: 100%;
+    cursor: pointer;
+    text-decoration: none;
+}
+#fp-nav ul li a.active span,
+.fp-slidesNav ul li a.active span {
+    background: #333;
+}
+#fp-nav ul li a span,
+.fp-slidesNav ul li a span {
+    top: 2px;
+    left: 2px;
+    width: 8px;
+    height: 8px;
+    border: 1px solid #000;
+    background: rgba(0, 0, 0, 0);
+    border-radius: 50%;
+    position: absolute;
+    z-index: 1;
+}
+#fp-nav ul li .fp-tooltip {
+    position: absolute;
+    top: -2px;
+    color: #fff;
+    font-size: 14px;
+    font-family: arial, helvetica, sans-serif;
+    white-space: nowrap;
+    max-width: 220px;
+    overflow: hidden;
+    display: block;
+    opacity: 0;
+    width: 0;
+}
+#fp-nav ul li:hover .fp-tooltip {
+    -webkit-transition: opacity 0.2s ease-in;
+    transition: opacity 0.2s ease-in;
+    width: auto;
+    opacity: 1;
+}
+#fp-nav ul li .fp-tooltip.right {
+    right: 20px;
+}
+#fp-nav ul li .fp-tooltip.left {
+    left: 20px;
+}

+ 52 - 0
Public/css/login.css

@@ -0,0 +1,52 @@
+body {
+  padding-top: 40px;
+  padding-bottom: 40px;
+  background-color: #f5f5f5;
+}
+
+.form-signin {
+  max-width: 300px;
+  padding: 19px 29px 29px;
+  margin: 0 auto 20px;
+  background-color: #fff;
+  border: 1px solid #e5e5e5;
+  -webkit-border-radius: 5px;
+     -moz-border-radius: 5px;
+          border-radius: 5px;
+  -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.05);
+     -moz-box-shadow: 0 1px 2px rgba(0,0,0,.05);
+          box-shadow: 0 1px 2px rgba(0,0,0,.05);
+}
+.form-signin .form-signin-heading,
+.form-signin .checkbox {
+  margin-bottom: 10px;
+}
+.form-signin input[type="text"],
+.form-signin input[type="password"] {
+  font-size: 16px;
+  height: auto;
+  margin-bottom: 15px;
+  padding: 7px 9px;
+}
+
+.container{
+  margin-top: 5%;
+}
+
+.card{
+    width: 330px;
+    position  : absolute;
+    top       : 50%;
+    left      : 50%;
+    transform : translate(-50%,-50%);
+    padding-top: 30px;
+    padding-left: 45px;
+    padding-right: 45px;
+    padding-bottom: 30px;
+    background-color: #fff;
+    box-sizing: border-box;
+}
+
+.heading{
+    text-align: center;
+    padding-bottom: 20px

+ 491 - 0
Public/css/page/edit.css

@@ -0,0 +1,491 @@
+* {
+
+
+
+    padding: 0;
+
+
+
+    margin: 0;
+
+
+
+}
+
+
+
+
+
+
+
+*, *:before, *:after {
+
+
+
+    -webkit-box-sizing: border-box;
+
+
+
+    -moz-box-sizing: border-box;
+
+
+
+    box-sizing: border-box;
+
+
+
+}
+
+
+
+		body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{
+
+
+
+    margin: 0;
+
+
+
+    padding: 0;
+
+
+
+}
+
+
+
+
+
+
+
+article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary {
+
+
+
+    display: block;
+
+
+
+}
+
+
+
+
+
+
+
+audio, canvas, video {
+
+
+
+    display: inline-block;
+
+
+
+}
+
+
+
+
+
+
+
+img {
+
+
+
+    border: none;
+
+
+
+    vertical-align: middle;
+
+
+
+}
+
+
+
+
+
+
+
+ul, ol {
+
+
+
+    /*list-style: none;*/
+
+
+
+}
+
+
+
+
+
+
+
+.clear {
+
+
+
+    *zoom: 1;           /* for IE 6/7 */
+
+
+
+}
+
+
+
+
+
+
+
+.clear:before, .clear:after {
+
+
+
+    height: 0; 
+
+
+
+    content: "";
+
+
+
+    font-size: 0;
+
+
+
+    display: table;
+
+
+
+    line-height: 0;     /* for Opera */
+
+
+
+    visibility: hidden;
+
+
+
+}
+
+
+
+
+
+
+
+.clear:after {
+
+
+
+    clear: both;
+
+
+
+}
+
+
+
+
+
+
+
+body {
+
+
+
+    font-size: 14px;
+
+
+
+    color: #666;
+
+
+
+    font-family: "Microsoft YaHei", "微软雅黑", Helvetica, Tahoma, STXihei, "华文细黑", STHeiti, "Helvetica Neue", Helvetica, Tahoma, "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, "宋体", Heiti, "黑体", sans-serif; 
+
+
+
+    background: #fff;
+
+
+
+    text-align: center;
+
+
+
+}
+
+
+
+
+
+
+
+#layout {
+
+
+
+    text-align: left;
+
+
+
+}
+
+
+
+
+
+
+
+#layout > header, .btns {
+
+
+
+    padding: 15px 0;
+
+
+
+    width: 90%;
+
+
+
+    margin: 0 auto;
+
+
+
+}
+
+
+
+
+
+
+
+.btns {
+
+
+
+    padding-top: 0;
+
+
+
+}
+
+
+
+
+
+
+
+.btns button {
+
+
+
+    padding: 2px 8px;
+
+
+
+}
+
+
+
+
+
+
+
+#layout > header > h1 {
+
+
+
+    font-size: 20px;
+
+
+
+    margin-bottom: 10px;
+
+
+
+}
+
+
+
+
+
+
+
+.btns button, .btn {
+
+
+
+    padding: 8px 10px;
+
+
+
+    background: #fff;
+
+
+
+    border: 1px solid #ddd;
+
+
+
+    -webkit-border-radius: 3px;
+
+
+
+    border-radius: 3px;
+
+
+
+    cursor: pointer;
+
+
+
+    -webkit-transition: background 300ms ease-out;
+
+
+
+    transition: background 300ms ease-out;
+
+
+
+}
+
+
+
+
+
+
+
+.btns button:hover, .btn:hover {
+
+
+
+    background: #f6f6f6;
+
+
+
+}
+
+
+
+
+
+
+
+#json-templ,#beautify-json-dialog{ position:fixed; float:left; top:100px; left:300px; border:2px solid #ccc; display:none; z-index:999999;}
+
+
+
+
+
+
+
+.markdown-body.editormd-preview-container table tr td{ max-width:300px;}
+
+
+
+
+
+
+
+.btn-primary {
+
+
+
+    background-color: #006dcc;
+
+
+
+}
+
+
+
+
+
+
+
+.btn-primary:hover {
+
+
+
+    background-color: #04c;
+
+
+
+}
+
+
+
+
+
+
+
+#page_title,
+
+
+
+#cat_id,
+
+
+
+#order {
+
+
+
+    height: 30px;
+
+
+
+}
+
+
+
+
+
+
+
+#cat_id ,#parent_cat_id {
+
+
+
+    width: 120px;
+
+
+
+}
+
+
+
+
+
+
+
+#s_number {
+
+
+
+    width: 120px;
+
+
+
+    margin-right: 20px;
+
+
+
+    height: 28px;
+
+
+
+}
+
+ol.linenums li {
+    list-style-type: none !important;
+}
+
+

+ 46 - 0
Public/css/page/index.css

@@ -0,0 +1,46 @@
+
+h3{
+	font-size: 1.5em;
+}
+
+body{
+	overflow-x:hidden;overflow-y:hidden;
+	font-size: 1rem;
+	line-height: 1.7em;
+}
+
+p{
+	margin: 0 0 20px;
+}
+
+li{
+	line-height: 30px;
+}
+
+.linenums li{
+	list-style-type:none;
+	line-height: 20px;
+}
+
+#page_md_content{
+	padding-top:10px;
+	word-break: break-all;
+}
+
+.hljs{
+	padding:0.2em;
+	background-color: #fcfcfc;
+}
+
+
+#page_title{
+    text-align: left;
+    border-bottom: 1px solid #d9d9d9;
+    padding-top: 30px;
+    padding-bottom: 20px
+}
+
+.markdown-body pre {
+	background-color: #fcfcfc;
+	border: 1px solid #e1e1e8;
+}

+ 35 - 0
Public/css/showdoc.css

@@ -0,0 +1,35 @@
+
+@charset "utf-8";
+  body {
+    font:14px/1.5 "Microsoft Yahei","微软雅黑",Tahoma,Arial,Helvetica,STHeiti;
+}
+
+.btn-primary{
+    background-color: #08c !important;
+    background-image: linear-gradient(to bottom,#08c,#08c);
+}
+.btn-primary:active{
+  background-color: #07c !important;
+}
+.btn-primary:hover{
+  background-color: #07c !important;
+  background-image: linear-gradient(to bottom,#07c,#07c);
+}
+
+/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
+::-webkit-scrollbar
+{
+    width: 7px;
+    height: 10px;
+    background-color: rgba(0, 0, 0, 0.1);
+}
+/*定义滑块 内阴影+圆角*/
+::-webkit-scrollbar-thumb
+{
+    background-color: rgba(0, 0, 0, 0.3);
+    -webkit-border-radius:6px;
+    -moz-border-radius: 6px;
+    -ms-border-radius: 6px;
+    -o-border-radius: 6px;
+    border-radius: 6px;
+}

+ 46 - 0
Public/css/tab-tpl.css

@@ -0,0 +1,46 @@
+body{
+    background: #F1F0F1;
+    height: auto;
+    overflow: auto;
+    margin: 0 auto;
+}
+
+.tab-doc-content{
+  
+    padding: 11px 0 90px 0;
+    overflow: hidden;
+    font-size: 11pt;
+    line-height: 1.7;
+    color: #333;
+}
+.tab-doc-body{
+  background-color: #fff;
+  width: 600px;
+  margin: 0 auto;
+}
+
+.tab-doc-container {
+    position: static;
+    -webkit-box-shadow: 0px 1px 6px #ccc;
+    -moz-box-shadow: 0px 1px 6px #ccc;
+    -ms-box-shadow: 0px 1px 6px #ccc;
+    -o-box-shadow: 0px 1px 6px #ccc;
+    box-shadow: 0px 1px 6px #ccc;
+    background-color: #fff;
+    border-bottom: 1px solid #d9d9d9;
+    margin-bottom: 20px;
+    width: 800px;
+    min-height: 500px;
+}
+
+.tab-header{
+  height: 40px;
+}
+
+.tab-doc-title-box{
+    height: auto;
+    margin: 30px 100px 10px 100px;
+    width: auto;
+    /*border-bottom: 1px solid #ebebeb;*/
+    padding-bottom: 10px;
+}

+ 411 - 0
Public/diff/difflib.js

@@ -0,0 +1,411 @@
+/***
+This is part of jsdifflib v1.0. <http://snowtide.com/jsdifflib>
+
+Copyright (c) 2007, Snowtide Informatics Systems, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+	* Redistributions of source code must retain the above copyright notice, this
+		list of conditions and the following disclaimer.
+	* Redistributions in binary form must reproduce the above copyright notice,
+		this list of conditions and the following disclaimer in the documentation
+		and/or other materials provided with the distribution.
+	* Neither the name of the Snowtide Informatics Systems nor the names of its
+		contributors may be used to endorse or promote products derived from this
+		software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+***/
+/* Author: Chas Emerick <cemerick@snowtide.com> */
+__whitespace = {" ":true, "\t":true, "\n":true, "\f":true, "\r":true};
+
+difflib = {
+	defaultJunkFunction: function (c) {
+		return __whitespace.hasOwnProperty(c);
+	},
+	
+	stripLinebreaks: function (str) { return str.replace(/^[\n\r]*|[\n\r]*$/g, ""); },
+	
+	stringAsLines: function (str) {
+		var lfpos = str.indexOf("\n");
+		var crpos = str.indexOf("\r");
+		var linebreak = ((lfpos > -1 && crpos > -1) || crpos < 0) ? "\n" : "\r";
+		
+		var lines = str.split(linebreak);
+		for (var i = 0; i < lines.length; i++) {
+			lines[i] = difflib.stripLinebreaks(lines[i]);
+		}
+		
+		return lines;
+	},
+	
+	// iteration-based reduce implementation
+	__reduce: function (func, list, initial) {
+		if (initial != null) {
+			var value = initial;
+			var idx = 0;
+		} else if (list) {
+			var value = list[0];
+			var idx = 1;
+		} else {
+			return null;
+		}
+		
+		for (; idx < list.length; idx++) {
+			value = func(value, list[idx]);
+		}
+		
+		return value;
+	},
+	
+	// comparison function for sorting lists of numeric tuples
+	__ntuplecomp: function (a, b) {
+		var mlen = Math.max(a.length, b.length);
+		for (var i = 0; i < mlen; i++) {
+			if (a[i] < b[i]) return -1;
+			if (a[i] > b[i]) return 1;
+		}
+		
+		return a.length == b.length ? 0 : (a.length < b.length ? -1 : 1);
+	},
+	
+	__calculate_ratio: function (matches, length) {
+		return length ? 2.0 * matches / length : 1.0;
+	},
+	
+	// returns a function that returns true if a key passed to the returned function
+	// is in the dict (js object) provided to this function; replaces being able to
+	// carry around dict.has_key in python...
+	__isindict: function (dict) {
+		return function (key) { return dict.hasOwnProperty(key); };
+	},
+	
+	// replacement for python's dict.get function -- need easy default values
+	__dictget: function (dict, key, defaultValue) {
+		return dict.hasOwnProperty(key) ? dict[key] : defaultValue;
+	},	
+	
+	SequenceMatcher: function (a, b, isjunk) {
+		this.set_seqs = function (a, b) {
+			this.set_seq1(a);
+			this.set_seq2(b);
+		}
+		
+		this.set_seq1 = function (a) {
+			if (a == this.a) return;
+			this.a = a;
+			this.matching_blocks = this.opcodes = null;
+		}
+		
+		this.set_seq2 = function (b) {
+			if (b == this.b) return;
+			this.b = b;
+			this.matching_blocks = this.opcodes = this.fullbcount = null;
+			this.__chain_b();
+		}
+		
+		this.__chain_b = function () {
+			var b = this.b;
+			var n = b.length;
+			var b2j = this.b2j = {};
+			var populardict = {};
+			for (var i = 0; i < b.length; i++) {
+				var elt = b[i];
+				if (b2j.hasOwnProperty(elt)) {
+					var indices = b2j[elt];
+					if (n >= 200 && indices.length * 100 > n) {
+						populardict[elt] = 1;
+						delete b2j[elt];
+					} else {
+						indices.push(i);
+					}
+				} else {
+					b2j[elt] = [i];
+				}
+			}
+	
+			for (var elt in populardict) {
+				if (populardict.hasOwnProperty(elt)) {
+					delete b2j[elt];
+				}
+			}
+			
+			var isjunk = this.isjunk;
+			var junkdict = {};
+			if (isjunk) {
+				for (var elt in populardict) {
+					if (populardict.hasOwnProperty(elt) && isjunk(elt)) {
+						junkdict[elt] = 1;
+						delete populardict[elt];
+					}
+				}
+				for (var elt in b2j) {
+					if (b2j.hasOwnProperty(elt) && isjunk(elt)) {
+						junkdict[elt] = 1;
+						delete b2j[elt];
+					}
+				}
+			}
+	
+			this.isbjunk = difflib.__isindict(junkdict);
+			this.isbpopular = difflib.__isindict(populardict);
+		}
+		
+		this.find_longest_match = function (alo, ahi, blo, bhi) {
+			var a = this.a;
+			var b = this.b;
+			var b2j = this.b2j;
+			var isbjunk = this.isbjunk;
+			var besti = alo;
+			var bestj = blo;
+			var bestsize = 0;
+			var j = null;
+	
+			var j2len = {};
+			var nothing = [];
+			for (var i = alo; i < ahi; i++) {
+				var newj2len = {};
+				var jdict = difflib.__dictget(b2j, a[i], nothing);
+				for (var jkey in jdict) {
+					if (jdict.hasOwnProperty(jkey)) {
+						j = jdict[jkey];
+						if (j < blo) continue;
+						if (j >= bhi) break;
+						newj2len[j] = k = difflib.__dictget(j2len, j - 1, 0) + 1;
+						if (k > bestsize) {
+							besti = i - k + 1;
+							bestj = j - k + 1;
+							bestsize = k;
+						}
+					}
+				}
+				j2len = newj2len;
+			}
+	
+			while (besti > alo && bestj > blo && !isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) {
+				besti--;
+				bestj--;
+				bestsize++;
+			}
+				
+			while (besti + bestsize < ahi && bestj + bestsize < bhi &&
+					!isbjunk(b[bestj + bestsize]) &&
+					a[besti + bestsize] == b[bestj + bestsize]) {
+				bestsize++;
+			}
+	
+			while (besti > alo && bestj > blo && isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) {
+				besti--;
+				bestj--;
+				bestsize++;
+			}
+			
+			while (besti + bestsize < ahi && bestj + bestsize < bhi && isbjunk(b[bestj + bestsize]) &&
+					a[besti + bestsize] == b[bestj + bestsize]) {
+				bestsize++;
+			}
+	
+			return [besti, bestj, bestsize];
+		}
+		
+		this.get_matching_blocks = function () {
+			if (this.matching_blocks != null) return this.matching_blocks;
+			var la = this.a.length;
+			var lb = this.b.length;
+	
+			var queue = [[0, la, 0, lb]];
+			var matching_blocks = [];
+			var alo, ahi, blo, bhi, qi, i, j, k, x;
+			while (queue.length) {
+				qi = queue.pop();
+				alo = qi[0];
+				ahi = qi[1];
+				blo = qi[2];
+				bhi = qi[3];
+				x = this.find_longest_match(alo, ahi, blo, bhi);
+				i = x[0];
+				j = x[1];
+				k = x[2];
+	
+				if (k) {
+					matching_blocks.push(x);
+					if (alo < i && blo < j)
+						queue.push([alo, i, blo, j]);
+					if (i+k < ahi && j+k < bhi)
+						queue.push([i + k, ahi, j + k, bhi]);
+				}
+			}
+			
+			matching_blocks.sort(difflib.__ntuplecomp);
+	
+			var i1 = j1 = k1 = block = 0;
+			var non_adjacent = [];
+			for (var idx in matching_blocks) {
+				if (matching_blocks.hasOwnProperty(idx)) {
+					block = matching_blocks[idx];
+					i2 = block[0];
+					j2 = block[1];
+					k2 = block[2];
+					if (i1 + k1 == i2 && j1 + k1 == j2) {
+						k1 += k2;
+					} else {
+						if (k1) non_adjacent.push([i1, j1, k1]);
+						i1 = i2;
+						j1 = j2;
+						k1 = k2;
+					}
+				}
+			}
+			
+			if (k1) non_adjacent.push([i1, j1, k1]);
+	
+			non_adjacent.push([la, lb, 0]);
+			this.matching_blocks = non_adjacent;
+			return this.matching_blocks;
+		}
+		
+		this.get_opcodes = function () {
+			if (this.opcodes != null) return this.opcodes;
+			var i = 0;
+			var j = 0;
+			var answer = [];
+			this.opcodes = answer;
+			var block, ai, bj, size, tag;
+			var blocks = this.get_matching_blocks();
+			for (var idx in blocks) {
+				if (blocks.hasOwnProperty(idx)) {
+					block = blocks[idx];
+					ai = block[0];
+					bj = block[1];
+					size = block[2];
+					tag = '';
+					if (i < ai && j < bj) {
+						tag = 'replace';
+					} else if (i < ai) {
+						tag = 'delete';
+					} else if (j < bj) {
+						tag = 'insert';
+					}
+					if (tag) answer.push([tag, i, ai, j, bj]);
+					i = ai + size;
+					j = bj + size;
+					
+					if (size) answer.push(['equal', ai, i, bj, j]);
+				}
+			}
+			
+			return answer;
+		}
+		
+		// this is a generator function in the python lib, which of course is not supported in javascript
+		// the reimplementation builds up the grouped opcodes into a list in their entirety and returns that.
+		this.get_grouped_opcodes = function (n) {
+			if (!n) n = 3;
+			var codes = this.get_opcodes();
+			if (!codes) codes = [["equal", 0, 1, 0, 1]];
+			var code, tag, i1, i2, j1, j2;
+			if (codes[0][0] == 'equal') {
+				code = codes[0];
+				tag = code[0];
+				i1 = code[1];
+				i2 = code[2];
+				j1 = code[3];
+				j2 = code[4];
+				codes[0] = [tag, Math.max(i1, i2 - n), i2, Math.max(j1, j2 - n), j2];
+			}
+			if (codes[codes.length - 1][0] == 'equal') {
+				code = codes[codes.length - 1];
+				tag = code[0];
+				i1 = code[1];
+				i2 = code[2];
+				j1 = code[3];
+				j2 = code[4];
+				codes[codes.length - 1] = [tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)];
+			}
+	
+			var nn = n + n;
+			var group = [];
+			var groups = [];
+			for (var idx in codes) {
+				if (codes.hasOwnProperty(idx)) {
+					code = codes[idx];
+					tag = code[0];
+					i1 = code[1];
+					i2 = code[2];
+					j1 = code[3];
+					j2 = code[4];
+					if (tag == 'equal' && i2 - i1 > nn) {
+						group.push([tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]);
+						groups.push(group);
+						group = [];
+						i1 = Math.max(i1, i2-n);
+						j1 = Math.max(j1, j2-n);
+					}
+					
+					group.push([tag, i1, i2, j1, j2]);
+				}
+			}
+			
+			if (group && !(group.length == 1 && group[0][0] == 'equal')) groups.push(group)
+			
+			return groups;
+		}
+		
+		this.ratio = function () {
+			matches = difflib.__reduce(
+							function (sum, triple) { return sum + triple[triple.length - 1]; },
+							this.get_matching_blocks(), 0);
+			return difflib.__calculate_ratio(matches, this.a.length + this.b.length);
+		}
+		
+		this.quick_ratio = function () {
+			var fullbcount, elt;
+			if (this.fullbcount == null) {
+				this.fullbcount = fullbcount = {};
+				for (var i = 0; i < this.b.length; i++) {
+					elt = this.b[i];
+					fullbcount[elt] = difflib.__dictget(fullbcount, elt, 0) + 1;
+				}
+			}
+			fullbcount = this.fullbcount;
+	
+			var avail = {};
+			var availhas = difflib.__isindict(avail);
+			var matches = numb = 0;
+			for (var i = 0; i < this.a.length; i++) {
+				elt = this.a[i];
+				if (availhas(elt)) {
+					numb = avail[elt];
+				} else {
+					numb = difflib.__dictget(fullbcount, elt, 0);
+				}
+				avail[elt] = numb - 1;
+				if (numb > 0) matches++;
+			}
+			
+			return difflib.__calculate_ratio(matches, this.a.length + this.b.length);
+		}
+		
+		this.real_quick_ratio = function () {
+			var la = this.a.length;
+			var lb = this.b.length;
+			return _calculate_ratio(Math.min(la, lb), la + lb);
+		}
+		
+		this.isjunk = isjunk ? isjunk : difflib.defaultJunkFunction;
+		this.a = this.b = null;
+		this.set_seqs(a, b);
+	}
+};
+

+ 83 - 0
Public/diff/diffview.css

@@ -0,0 +1,83 @@
+/*
+This is part of jsdifflib v1.0. <http://github.com/cemerick/jsdifflib>
+
+Copyright 2007 - 2011 Chas Emerick <cemerick@snowtide.com>. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice, this list of
+      conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright notice, this list
+      of conditions and the following disclaimer in the documentation and/or other materials
+      provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY Chas Emerick ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Chas Emerick OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those of the
+authors and should not be interpreted as representing official policies, either expressed
+or implied, of Chas Emerick.
+*/
+table.diff {
+	border-collapse:collapse;
+	border:1px solid darkgray;
+	white-space:pre-wrap
+}
+table.diff tbody { 
+	font-family:Courier, monospace
+}
+table.diff tbody th {
+	font-family:verdana,arial,'Bitstream Vera Sans',helvetica,sans-serif;
+	background:#EED;
+	font-size:11px;
+	font-weight:normal;
+	border:1px solid #BBC;
+	color:#886;
+	padding:.3em .5em .1em 2em;
+	text-align:right;
+	vertical-align:top
+}
+table.diff thead {
+	border-bottom:1px solid #BBC;
+	background:#EFEFEF;
+	font-family:Verdana
+}
+table.diff thead th.texttitle {
+	text-align:left
+}
+table.diff tbody td {
+	padding:0px .4em;
+	padding-top:.4em;
+	vertical-align:top;
+}
+table.diff .empty {
+	background-color:#DDD;
+}
+table.diff .replace {
+	background-color:#FD8
+}
+table.diff .delete {
+	background-color:#E99;
+}
+table.diff .skip {
+	background-color:#EFEFEF;
+	border:1px solid #AAA;
+	border-right:1px solid #BBC;
+}
+table.diff .insert {
+	background-color:#9E9
+}
+table.diff th.author {
+	text-align:right;
+	border-top:1px solid #BBC;
+	background:#EFEFEF
+}

+ 198 - 0
Public/diff/diffview.js

@@ -0,0 +1,198 @@
+/*
+This is part of jsdifflib v1.0. <http://github.com/cemerick/jsdifflib>
+
+Copyright 2007 - 2011 Chas Emerick <cemerick@snowtide.com>. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice, this list of
+      conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright notice, this list
+      of conditions and the following disclaimer in the documentation and/or other materials
+      provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY Chas Emerick ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Chas Emerick OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those of the
+authors and should not be interpreted as representing official policies, either expressed
+or implied, of Chas Emerick.
+*/
+diffview = {
+	/**
+	 * Builds and returns a visual diff view.  The single parameter, `params', should contain
+	 * the following values:
+	 *
+	 * - baseTextLines: the array of strings that was used as the base text input to SequenceMatcher
+	 * - newTextLines: the array of strings that was used as the new text input to SequenceMatcher
+	 * - opcodes: the array of arrays returned by SequenceMatcher.get_opcodes()
+	 * - baseTextName: the title to be displayed above the base text listing in the diff view; defaults
+	 *	   to "Base Text"
+	 * - newTextName: the title to be displayed above the new text listing in the diff view; defaults
+	 *	   to "New Text"
+	 * - contextSize: the number of lines of context to show around differences; by default, all lines
+	 *	   are shown
+	 * - viewType: if 0, a side-by-side diff view is generated (default); if 1, an inline diff view is
+	 *	   generated
+	 */
+	buildView: function (params) {
+		var baseTextLines = params.baseTextLines;
+		var newTextLines = params.newTextLines;
+		var opcodes = params.opcodes;
+		var baseTextName = params.baseTextName ? params.baseTextName : "Base Text";
+		var newTextName = params.newTextName ? params.newTextName : "New Text";
+		var contextSize = params.contextSize;
+		var inline = (params.viewType == 0 || params.viewType == 1) ? params.viewType : 0;
+
+		if (baseTextLines == null)
+			throw "Cannot build diff view; baseTextLines is not defined.";
+		if (newTextLines == null)
+			throw "Cannot build diff view; newTextLines is not defined.";
+		if (!opcodes)
+			throw "Canno build diff view; opcodes is not defined.";
+		
+		function celt (name, clazz) {
+			var e = document.createElement(name);
+			e.className = clazz;
+			return e;
+		}
+		
+		function telt (name, text) {
+			var e = document.createElement(name);
+			e.appendChild(document.createTextNode(text));
+			return e;
+		}
+		
+		function ctelt (name, clazz, text) {
+			var e = document.createElement(name);
+			e.className = clazz;
+			e.appendChild(document.createTextNode(text));
+			return e;
+		}
+	
+		var tdata = document.createElement("thead");
+		var node = document.createElement("tr");
+		tdata.appendChild(node);
+		if (inline) {
+			node.appendChild(document.createElement("th"));
+			node.appendChild(document.createElement("th"));
+			node.appendChild(ctelt("th", "texttitle", baseTextName + " vs. " + newTextName));
+		} else {
+			node.appendChild(document.createElement("th"));
+			node.appendChild(ctelt("th", "texttitle", baseTextName));
+			node.appendChild(document.createElement("th"));
+			node.appendChild(ctelt("th", "texttitle", newTextName));
+		}
+		tdata = [tdata];
+		
+		var rows = [];
+		var node2;
+		
+		/**
+		 * Adds two cells to the given row; if the given row corresponds to a real
+		 * line number (based on the line index tidx and the endpoint of the 
+		 * range in question tend), then the cells will contain the line number
+		 * and the line of text from textLines at position tidx (with the class of
+		 * the second cell set to the name of the change represented), and tidx + 1 will
+		 * be returned.	 Otherwise, tidx is returned, and two empty cells are added
+		 * to the given row.
+		 */
+		function addCells (row, tidx, tend, textLines, change) {
+			if (tidx < tend) {
+				row.appendChild(telt("th", (tidx + 1).toString()));
+				row.appendChild(ctelt("td", change, textLines[tidx].replace(/\t/g, "\u00a0\u00a0\u00a0\u00a0")));
+				return tidx + 1;
+			} else {
+				row.appendChild(document.createElement("th"));
+				row.appendChild(celt("td", "empty"));
+				return tidx;
+			}
+		}
+		
+		function addCellsInline (row, tidx, tidx2, textLines, change) {
+			row.appendChild(telt("th", tidx == null ? "" : (tidx + 1).toString()));
+			row.appendChild(telt("th", tidx2 == null ? "" : (tidx2 + 1).toString()));
+			row.appendChild(ctelt("td", change, textLines[tidx != null ? tidx : tidx2].replace(/\t/g, "\u00a0\u00a0\u00a0\u00a0")));
+		}
+		
+		for (var idx = 0; idx < opcodes.length; idx++) {
+			code = opcodes[idx];
+			change = code[0];
+			var b = code[1];
+			var be = code[2];
+			var n = code[3];
+			var ne = code[4];
+			var rowcnt = Math.max(be - b, ne - n);
+			var toprows = [];
+			var botrows = [];
+			for (var i = 0; i < rowcnt; i++) {
+				// jump ahead if we've alredy provided leading context or if this is the first range
+				if (contextSize && opcodes.length > 1 && ((idx > 0 && i == contextSize) || (idx == 0 && i == 0)) && change=="equal") {
+					var jump = rowcnt - ((idx == 0 ? 1 : 2) * contextSize);
+					if (jump > 1) {
+						toprows.push(node = document.createElement("tr"));
+						
+						b += jump;
+						n += jump;
+						i += jump - 1;
+						node.appendChild(telt("th", "..."));
+						if (!inline) node.appendChild(ctelt("td", "skip", ""));
+						node.appendChild(telt("th", "..."));
+						node.appendChild(ctelt("td", "skip", ""));
+						
+						// skip last lines if they're all equal
+						if (idx + 1 == opcodes.length) {
+							break;
+						} else {
+							continue;
+						}
+					}
+				}
+				
+				toprows.push(node = document.createElement("tr"));
+				if (inline) {
+					if (change == "insert") {
+						addCellsInline(node, null, n++, newTextLines, change);
+					} else if (change == "replace") {
+						botrows.push(node2 = document.createElement("tr"));
+						if (b < be) addCellsInline(node, b++, null, baseTextLines, "delete");
+						if (n < ne) addCellsInline(node2, null, n++, newTextLines, "insert");
+					} else if (change == "delete") {
+						addCellsInline(node, b++, null, baseTextLines, change);
+					} else {
+						// equal
+						addCellsInline(node, b++, n++, baseTextLines, change);
+					}
+				} else {
+					b = addCells(node, b, be, baseTextLines, change);
+					n = addCells(node, n, ne, newTextLines, change);
+				}
+			}
+
+			for (var i = 0; i < toprows.length; i++) rows.push(toprows[i]);
+			for (var i = 0; i < botrows.length; i++) rows.push(botrows[i]);
+		}
+		
+		rows.push(node = ctelt("th", "author", "diff view generated by "));
+		node.setAttribute("colspan", inline ? 3 : 4);
+		node.appendChild(node2 = telt("a", "jsdifflib"));
+		node2.setAttribute("href", "http://github.com/cemerick/jsdifflib");
+		
+		tdata.push(node = document.createElement("tbody"));
+		for (var idx in rows) rows.hasOwnProperty(idx) && node.appendChild(rows[idx]);
+		
+		node = celt("table", "diff" + (inline ? " inlinediff" : ""));
+		for (var idx in tdata) tdata.hasOwnProperty(idx) && node.appendChild(tdata[idx]);
+		return node;
+	}
+};
+

+ 342 - 0
Public/editor.md/Gulpfile.js

@@ -0,0 +1,342 @@
+"use strict";
+
+var os           = require("os");
+var gulp         = require("gulp");
+var gutil        = require("gulp-util");
+var sass         = require("gulp-ruby-sass");
+var jshint       = require("gulp-jshint");
+var uglify       = require("gulp-uglifyjs");
+var rename       = require("gulp-rename");
+var concat       = require("gulp-concat");
+var notify       = require("gulp-notify");
+var header       = require("gulp-header");
+var minifycss    = require("gulp-minify-css");
+//var jsdoc        = require("gulp-jsdoc");
+//var jsdoc2md     = require("gulp-jsdoc-to-markdown");
+var pkg          = require("./package.json");
+var dateFormat   = require("dateformatter").format;
+var replace      = require("gulp-replace");
+
+pkg.name         = "Editor.md";
+pkg.today        = dateFormat;
+
+var headerComment = ["/*", 
+					" * <%= pkg.name %>",
+                    " *",
+					" * @file        <%= fileName(file) %> ",
+					" * @version     v<%= pkg.version %> ",
+					" * @description <%= pkg.description %>",
+					" * @license     MIT License",
+					" * @author      <%= pkg.author %>",
+					" * {@link       <%= pkg.homepage %>}",
+					" * @updateTime  <%= pkg.today('Y-m-d') %>",
+					" */", 
+					"\r\n"].join("\r\n");
+
+var headerMiniComment = "/*! <%= pkg.name %> v<%= pkg.version %> | <%= fileName(file) %> | <%= pkg.description %> | MIT License | By: <%= pkg.author %> | <%= pkg.homepage %> | <%=pkg.today('Y-m-d') %> */\r\n";
+
+var scssTask = function(fileName, path) {
+    
+    path = path || "scss/";
+    
+    var distPath = "css";
+    
+    return sass(path + fileName + ".scss", { style: "expanded", sourcemap: false, noCache : true })
+        .pipe(gulp.dest(distPath))
+        .pipe(header(headerComment, {pkg : pkg, fileName : function(file) { 
+            var name = file.path.split(file.base);
+            return name[1].replace("\\", "");
+        }}))
+       .pipe(gulp.dest(distPath)) 
+       .pipe(rename({ suffix: ".min" }))
+       .pipe(gulp.dest(distPath))
+       .pipe(minifycss())
+       .pipe(gulp.dest(distPath)) 
+        .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) { 
+            var name = file.path.split(file.base);
+            return name[1].replace("\\", "");
+        }}))
+       .pipe(gulp.dest(distPath)) 
+       .pipe(notify({ message: fileName + ".scss task completed!" }));
+};
+
+gulp.task("scss", function() { 
+	return scssTask("editormd");
+}); 
+
+gulp.task("scss2", function() { 
+	return scssTask("editormd.preview");
+}); 
+
+gulp.task("scss3", function() {
+	return scssTask("editormd.logo");
+}); 
+
+gulp.task("js", function() { 
+  return gulp.src("./src/editormd.js")
+            .pipe(jshint("./.jshintrc"))
+            .pipe(jshint.reporter("default"))
+            .pipe(header(headerComment, {pkg : pkg, fileName : function(file) { 
+                var name = file.path.split(file.base);
+                return name[1].replace(/[\\\/]?/, "");
+            }}))
+            .pipe(gulp.dest("./"))
+            .pipe(rename({ suffix: ".min" }))
+            .pipe(uglify())  // {outSourceMap: true, sourceRoot: './'}
+            .pipe(gulp.dest("./"))	
+            .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) {
+                var name = file.path.split(file.base + ( (os.platform() === "win32") ? "\\" : "/") );
+                return name[1].replace(/[\\\/]?/, "");
+            }}))
+            .pipe(gulp.dest("./"))
+            .pipe(notify({ message: "editormd.js task complete" }));
+}); 
+
+gulp.task("amd", function() {
+    var replaceText1 = [
+        'var cmModePath  = "codemirror/mode/";',
+        '            var cmAddonPath = "codemirror/addon/";', 
+        '',
+        '            var codeMirrorModules = [',
+        '                "jquery", "marked", "prettify",',
+        '                "katex", "raphael", "underscore", "flowchart",  "jqueryflowchart",  "sequenceDiagram",',
+        '',
+        '                "codemirror/lib/codemirror",',
+        '                cmModePath + "css/css",',
+        '                cmModePath + "sass/sass",', 
+        '                cmModePath + "shell/shell",', 
+        '                cmModePath + "sql/sql",',
+        '                cmModePath + "clike/clike",',
+        '                cmModePath + "php/php",',
+        '                cmModePath + "xml/xml",',
+        '                cmModePath + "markdown/markdown",', 
+        '                cmModePath + "javascript/javascript",',
+        '                cmModePath + "htmlmixed/htmlmixed",',
+        '                cmModePath + "gfm/gfm",',
+        '                cmModePath + "http/http",',
+        '                cmModePath + "go/go",', 
+        '                cmModePath + "dart/dart",', 
+        '                cmModePath + "coffeescript/coffeescript",',
+        '                cmModePath + "nginx/nginx",',
+        '                cmModePath + "python/python",', 
+        '                cmModePath + "perl/perl",',
+        '                cmModePath + "lua/lua",', 
+        '                cmModePath + "r/r", ',
+        '                cmModePath + "ruby/ruby", ',
+        '                cmModePath + "rst/rst",',
+        '                cmModePath + "smartymixed/smartymixed",', 
+        '                cmModePath + "vb/vb",',
+        '                cmModePath + "vbscript/vbscript",', 
+        '                cmModePath + "velocity/velocity",',
+        '                cmModePath + "xquery/xquery",',
+        '                cmModePath + "yaml/yaml",',
+        '                cmModePath + "erlang/erlang",', 
+        '                cmModePath + "jade/jade",',
+        '',
+        '                cmAddonPath + "edit/trailingspace", ',
+        '                cmAddonPath + "dialog/dialog", ',
+        '                cmAddonPath + "search/searchcursor", ',
+        '                cmAddonPath + "search/search", ',
+        '                cmAddonPath + "scroll/annotatescrollbar", ', 
+        '                cmAddonPath + "search/matchesonscrollbar", ',
+        '                cmAddonPath + "display/placeholder", ',
+        '                cmAddonPath + "edit/closetag", ',
+        '                cmAddonPath + "fold/foldcode",',
+        '                cmAddonPath + "fold/foldgutter",',
+        '                cmAddonPath + "fold/indent-fold",',
+        '                cmAddonPath + "fold/brace-fold",',
+        '                cmAddonPath + "fold/xml-fold", ',
+        '                cmAddonPath + "fold/markdown-fold",',
+        '                cmAddonPath + "fold/comment-fold", ',
+        '                cmAddonPath + "mode/overlay", ',
+        '                cmAddonPath + "selection/active-line", ',
+        '                cmAddonPath + "edit/closebrackets", ',
+        '                cmAddonPath + "display/fullscreen",',
+        '                cmAddonPath + "search/match-highlighter"',
+        '            ];',
+        '',
+        '            define(codeMirrorModules, factory);'
+    ].join("\r\n");
+    
+    var replaceText2 = [
+        "if (typeof define == \"function\" && define.amd) {",
+        "       $          = arguments[0];",
+        "       marked     = arguments[1];",
+        "       prettify   = arguments[2];",
+        "       katex      = arguments[3];",
+        "       Raphael    = arguments[4];",
+        "       _          = arguments[5];",
+        "       flowchart  = arguments[6];",
+        "       CodeMirror = arguments[9];",
+        "   }"
+    ].join("\r\n");
+    
+    gulp.src("src/editormd.js")
+        .pipe(rename({ suffix: ".amd" }))
+        .pipe(gulp.dest('./'))
+        .pipe(header(headerComment, {pkg : pkg, fileName : function(file) { 
+            var name = file.path.split(file.base);
+            return name[1].replace(/[\\\/]?/, "");
+        }}))
+        .pipe(gulp.dest("./"))
+        .pipe(replace("/* Require.js define replace */", replaceText1))
+        .pipe(gulp.dest('./'))
+        .pipe(replace("/* Require.js assignment replace */", replaceText2))
+        .pipe(gulp.dest('./'))
+        .pipe(rename({ suffix: ".min" }))
+        .pipe(uglify()) //{outSourceMap: true, sourceRoot: './'}
+        .pipe(gulp.dest("./"))
+        .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) {
+            var name = file.path.split(file.base + ( (os.platform() === "win32") ? "\\" : "/") );
+            return name[1].replace(/[\\\/]?/, "");
+        }}))
+        .pipe(gulp.dest("./"))
+        .pipe(notify({ message: "amd version task complete"}));
+}); 
+
+
+var codeMirror = {
+    path : {
+        src : {
+            mode : "lib/codemirror/mode",
+            addon : "lib/codemirror/addon"
+        },
+        dist : "lib/codemirror"
+    },
+    modes : [
+        "css",
+        "sass",
+        "shell",
+        "sql",
+        "clike",
+        "php",
+        "xml",
+        "markdown",
+        "javascript",
+        "htmlmixed",
+        "gfm",
+        "http",
+        "go",
+        "dart",
+        "coffeescript",
+        "nginx",
+        "python",
+        "perl",
+        "lua",
+        "r", 
+        "ruby", 
+        "rst",
+        "smartymixed",
+        "vb",
+        "vbscript",
+        "velocity",
+        "xquery",
+        "yaml",
+        "erlang",
+        "jade",
+    ],
+
+    addons : [
+        "edit/trailingspace", 
+        "dialog/dialog", 
+        "search/searchcursor", 
+        "search/search",
+        "scroll/annotatescrollbar", 
+        "search/matchesonscrollbar", 
+        "display/placeholder", 
+        "edit/closetag", 
+        "fold/foldcode",
+        "fold/foldgutter",
+        "fold/indent-fold",
+        "fold/brace-fold",
+        "fold/xml-fold", 
+        "fold/markdown-fold",
+        "fold/comment-fold", 
+        "mode/overlay", 
+        "selection/active-line", 
+        "edit/closebrackets", 
+        "display/fullscreen", 
+        "search/match-highlighter"
+    ]
+};
+
+gulp.task("cm-mode", function() { 
+    
+    var modes = [
+        codeMirror.path.src.mode + "/meta.js"
+    ];
+    
+    for(var i in codeMirror.modes) {
+        var mode = codeMirror.modes[i];
+        modes.push(codeMirror.path.src.mode + "/" + mode + "/" + mode + ".js");
+    }
+    
+    return gulp.src(modes)
+                .pipe(concat("modes.min.js"))
+                .pipe(gulp.dest(codeMirror.path.dist))
+                .pipe(uglify()) // {outSourceMap: true, sourceRoot: codeMirror.path.dist}
+                .pipe(gulp.dest(codeMirror.path.dist))	
+                .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) {
+                    var name = file.path.split(file.base + "\\"); 
+                    return (name[1]?name[1]:name[0]).replace(/\\/g, "");
+                }}))
+                .pipe(gulp.dest(codeMirror.path.dist))
+                .pipe(notify({ message: "codemirror-mode task complete!" }));
+}); 
+
+gulp.task("cm-addon", function() { 
+    
+    var addons = [];
+    
+    for(var i in codeMirror.addons) {
+        var addon = codeMirror.addons[i];
+        addons.push(codeMirror.path.src.addon + "/" + addon + ".js");
+    }
+    
+    return gulp.src(addons)
+                .pipe(concat("addons.min.js"))
+                .pipe(gulp.dest(codeMirror.path.dist))
+                .pipe(uglify()) //{outSourceMap: true, sourceRoot: codeMirror.path.dist}
+                .pipe(gulp.dest(codeMirror.path.dist))	
+                .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) {
+                    var name = file.path.split(file.base + "\\");
+                    return (name[1]?name[1]:name[0]).replace(/\\/g, "");
+                }}))
+                .pipe(gulp.dest(codeMirror.path.dist))
+                .pipe(notify({ message: "codemirror-addon.js task complete" }));
+}); 
+/*
+gulp.task("jsdoc", function(){
+    return gulp.src(["./src/editormd.js", "README.md"])
+               .pipe(jsdoc.parser())
+               .pipe(jsdoc.generator("./docs/html"));
+});
+
+gulp.task("jsdoc2md", function() {
+    return gulp.src("src/js/editormd.js")
+            .pipe(jsdoc2md())
+            .on("error", function(err){
+                gutil.log(gutil.colors.red("jsdoc2md failed"), err.message);
+            })
+            .pipe(rename(function(path) {
+                path.extname = ".md";
+            }))
+            .pipe(gulp.dest("docs/markdown"));
+});
+*/
+gulp.task("watch", function() {
+	gulp.watch("scss/editormd.scss", ["scss"]);
+	gulp.watch("scss/editormd.preview.scss", ["scss", "scss2"]);
+	gulp.watch("scss/editormd.logo.scss", ["scss", "scss3"]);
+	gulp.watch("src/editormd.js", ["js", "amd"]);
+});
+
+gulp.task("default", function() {
+    gulp.run("scss");
+    gulp.run("scss2");
+    gulp.run("scss3");
+    gulp.run("js");
+    gulp.run("amd");
+    gulp.run("cm-addon");
+    gulp.run("cm-mode");
+});

+ 22 - 0
Public/editor.md/LICENSE

@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 pandao
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+

+ 119 - 0
Public/editor.md/README.md

@@ -0,0 +1,119 @@
+# Editor.md
+
+![](https://pandao.github.io/editor.md/images/logos/editormd-logo-180x180.png)
+
+![](https://img.shields.io/github/stars/pandao/editor.md.svg)
+![](https://img.shields.io/github/forks/pandao/editor.md.svg)
+![](https://img.shields.io/github/tag/pandao/editor.md.svg)
+![](https://img.shields.io/github/release/pandao/editor.md.svg)
+![](https://img.shields.io/github/issues/pandao/editor.md.svg)
+![](https://img.shields.io/bower/v/editor.md.svg)
+
+**Editor.md** : The open source embeddable online markdown editor (component), based on CodeMirror & jQuery & Marked.
+
+### Features
+
+- Support Standard Markdown / CommonMark and GFM (GitHub Flavored Markdown);
+- Full-featured: Real-time Preview, Image (cross-domain) upload, Preformatted text/Code blocks/Tables insert, Code fold, Search replace, Read only, Themes, Multi-languages, L18n, HTML entities, Code syntax highlighting...;
+- Markdown Extras : Support [ToC (Table of Contents)](https://pandao.github.io/editor.md/examples/toc.html), [Emoji](https://pandao.github.io/editor.md/examples/emoji.html), [Task lists](https://pandao.github.io/editor.md/examples/task-lists.html), [@Links](https://pandao.github.io/editor.md/examples/@links.html)...;
+- Compatible with all major browsers (IE8+), compatible Zepto.js and iPad;
+- Support [decode & fliter of the HTML tags & attributes](https://pandao.github.io/editor.md/examples/html-tags-decode.html);
+- Support [TeX (LaTeX expressions, Based on KaTeX)](https://pandao.github.io/editor.md/examples/katex.html), [Flowchart](https://pandao.github.io/editor.md/examples/flowchart.html) and [Sequence Diagram](https://pandao.github.io/editor.md/examples/sequence-diagram.html) of Markdown extended syntax;
+- Support AMD/CMD (Require.js & Sea.js) Module Loader, and Custom/define editor plugins;
+
+[README & Examples (English)](https://pandao.github.io/editor.md/en.html)
+  
+
+--------
+
+**Editor.md** 是一款开源的、可嵌入的 Markdown 在线编辑器(组件),基于 CodeMirror、jQuery 和 Marked 构建。
+
+![editormd-screenshot](https://pandao.github.io/editor.md/examples/images/editormd-screenshot.png "editormd-screenshot")
+
+#### 主要特性
+
+- 支持通用 Markdown / CommonMark 和 GFM (GitHub Flavored Markdown) 风格的语法,也可[变身为代码编辑器](https://pandao.github.io/editor.md/examples/change-mode.html);
+- 支持实时预览、图片(跨域)上传、预格式文本/代码/表格插入、代码折叠、跳转到行、搜索替换、只读模式、自定义样式主题和多语言语法高亮等功能;
+- 支持 [ToC(Table of Contents)](https://pandao.github.io/editor.md/examples/toc.html)、[Emoji表情](https://pandao.github.io/editor.md/examples/emoji.html)、[Task lists](https://pandao.github.io/editor.md/examples/task-lists.html)、[@链接](https://pandao.github.io/editor.md/examples/@links.html)等 Markdown 扩展语法;
+- 支持 TeX 科学公式(基于 [KaTeX](https://pandao.github.io/editor.md/examples/katex.html))、流程图 [Flowchart](https://pandao.github.io/editor.md/examples/flowchart.html) 和 [时序图 Sequence Diagram](https://pandao.github.io/editor.md/examples/sequence-diagram.html);
+- 支持[识别和解析 HTML 标签,并且支持自定义过滤标签及属性解析](https://pandao.github.io/editor.md/examples/html-tags-decode.html),具有可靠的安全性和几乎无限的扩展性;
+- 支持 AMD / CMD 模块化加载(支持 [Require.js](https://pandao.github.io/editor.md/examples/use-requirejs.html) & [Sea.js](https://pandao.github.io/editor.md/examples/use-seajs.html)),并且支持[自定义扩展插件](https://pandao.github.io/editor.md/examples/define-plugin.html);
+- 兼容主流的浏览器(IE8+)和 [Zepto.js](https://pandao.github.io/editor.md/examples/use-zepto.html),且支持 iPad 等平板设备;
+
+#### Examples
+
+[https://pandao.github.io/editor.md/examples/index.html](https://pandao.github.io/editor.md/examples/index.html)
+
+#### Download & install
+
+[Github download](https://github.com/pandao/editor.md/archive/master.zip)
+
+Bower install :
+
+```shell
+bower install editor.md
+```
+
+#### Usages
+
+HTML:
+
+```html
+<link rel="stylesheet" href="editormd.min.css" />
+<div id="editormd">
+    <textarea style="display:none;">### Hello Editor.md !</textarea>
+</div>
+```
+
+> Tip: Editor.md can auto append `<textarea>` tag;
+
+javascript:
+
+```html
+<script src="jquery.min.js"></script>
+<script src="editormd.min.js"></script>
+<script type="text/javascript">
+    $(function() {
+        var editor = editormd("editormd", {
+            path : "../lib/" // Autoload modules mode, codemirror, marked... dependents libs path
+        });
+
+        /*
+        // or
+        var editor = editormd({
+            id   : "editormd",
+            path : "../lib/"
+        });
+        */
+    });
+</script>
+```
+
+Using modular script loader :
+
+- [Using Require.js](https://github.com/pandao/editor.md/tree/master/examples/use-requirejs.html)
+- [Using Sea.js](https://github.com/pandao/editor.md/tree/master/examples/use-seajs.html)
+
+#### Dependents
+
+- [CodeMirror](http://codemirror.net/ "CodeMirror")
+- [marked](https://github.com/chjj/marked "marked")
+- [jQuery](http://jquery.com/ "jQuery")
+- [FontAwesome](http://fontawesome.io/ "FontAwesome")
+- [github-markdown.css](https://github.com/sindresorhus/github-markdown-css "github-markdown.css")
+- [KaTeX](http://khan.github.io/KaTeX/ "KaTeX")
+- [prettify.js](http://code.google.com/p/google-code-prettify/ "prettify.js")
+- [Rephael.js](http://raphaeljs.com/ "Rephael.js")
+- [flowchart.js](http://adrai.github.io/flowchart.js/ "flowchart.js")
+- [sequence-diagram.js](http://bramp.github.io/js-sequence-diagrams/ "sequence-diagram.js")
+- [Prefixes.scss](https://github.com/pandao/prefixes.scss "Prefixes.scss")
+
+#### Changes
+
+[Change logs](https://github.com/pandao/editor.md/blob/master/CHANGE.md)
+
+#### License
+
+The MIT License.
+
+Copyright (c) 2015 Pandao

File diff suppressed because it is too large
+ 4450 - 0
Public/editor.md/css/editormd.css


+ 98 - 0
Public/editor.md/css/editormd.logo.css

@@ -0,0 +1,98 @@
+/*
+ * Editor.md
+ *
+ * @file        editormd.logo.css 
+ * @version     v1.5.0 
+ * @description Open source online markdown editor.
+ * @license     MIT License
+ * @author      Pandao
+ * {@link       https://github.com/pandao/editor.md}
+ * @updateTime  2015-06-09
+ */
+
+/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */
+@font-face {
+  font-family: 'editormd-logo';
+  src: url("../fonts/editormd-logo.eot?-5y8q6h");
+  src: url(".../fonts/editormd-logo.eot?#iefix-5y8q6h") format("embedded-opentype"), url("../fonts/editormd-logo.woff?-5y8q6h") format("woff"), url("../fonts/editormd-logo.ttf?-5y8q6h") format("truetype"), url("../fonts/editormd-logo.svg?-5y8q6h#icomoon") format("svg");
+  font-weight: normal;
+  font-style: normal;
+}
+.editormd-logo,
+.editormd-logo-1x,
+.editormd-logo-2x,
+.editormd-logo-3x,
+.editormd-logo-4x,
+.editormd-logo-5x,
+.editormd-logo-6x,
+.editormd-logo-7x,
+.editormd-logo-8x {
+  font-family: 'editormd-logo';
+  speak: none;
+  font-style: normal;
+  font-weight: normal;
+  font-variant: normal;
+  text-transform: none;
+  font-size: inherit;
+  line-height: 1;
+  display: inline-block;
+  text-rendering: auto;
+  vertical-align: inherit;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+.editormd-logo:before,
+.editormd-logo-1x:before,
+.editormd-logo-2x:before,
+.editormd-logo-3x:before,
+.editormd-logo-4x:before,
+.editormd-logo-5x:before,
+.editormd-logo-6x:before,
+.editormd-logo-7x:before,
+.editormd-logo-8x:before {
+  content: "\e1987";
+  /* 
+  HTML Entity &#xe1987; 
+  example: <span class="editormd-logo">&#xe1987;</span>
+  */
+}
+
+.editormd-logo-1x {
+  font-size: 1em;
+}
+
+.editormd-logo-lg {
+  font-size: 1.2em;
+}
+
+.editormd-logo-2x {
+  font-size: 2em;
+}
+
+.editormd-logo-3x {
+  font-size: 3em;
+}
+
+.editormd-logo-4x {
+  font-size: 4em;
+}
+
+.editormd-logo-5x {
+  font-size: 5em;
+}
+
+.editormd-logo-6x {
+  font-size: 6em;
+}
+
+.editormd-logo-7x {
+  font-size: 7em;
+}
+
+.editormd-logo-8x {
+  font-size: 8em;
+}
+
+.editormd-logo-color {
+  color: #2196F3;
+}

File diff suppressed because it is too large
+ 2 - 0
Public/editor.md/css/editormd.logo.min.css


File diff suppressed because it is too large
+ 5 - 0
Public/editor.md/css/editormd.min.css


File diff suppressed because it is too large
+ 3554 - 0
Public/editor.md/css/editormd.preview.css


File diff suppressed because it is too large
+ 5 - 0
Public/editor.md/css/editormd.preview.min.css


File diff suppressed because it is too large
+ 4667 - 0
Public/editor.md/editormd.amd.js


File diff suppressed because it is too large
+ 4 - 0
Public/editor.md/editormd.amd.min.js


File diff suppressed because it is too large
+ 4621 - 0
Public/editor.md/editormd.js


+ 0 - 0
Public/editor.md/editormd.min.js


Some files were not shown because too many files changed in this diff