diff --git a/CHANGELOG-zh-cn.md b/CHANGELOG-zh-cn.md
new file mode 100644
index 00000000..c09ca401
--- /dev/null
+++ b/CHANGELOG-zh-cn.md
@@ -0,0 +1,134 @@
+## ZeroNet 0.5.1 (2016-11-18)
+### 新增
+- 多语言界面
+- 新插件:为站点 HTML 与 JS 文件提供的翻译助手
+- 每个站点独立的 favicon
+
+### 修复
+- 并行可选文件下载
+
+## ZeroNet 0.5.0 (2016-11-08)
+### 新增
+- 新插件:允许在 ZeroHello 列出/删除/固定/管理文件
+- 新的 API 命令来关注用户的可选文件,与可选文件的请求统计
+- 新的可选文件总大小限制
+- 新插件:保存节点到数据库并在重启时保持它们,使得更快的可选文件搜索以及在没有 Tracker 的情况下工作
+- 重写 UPnP 端口打开器 + 退出时关闭端口(感谢 sirMackk!)
+- 通过懒惰 PeerHashfield 创建来减少内存占用
+- 在 /Stats 页面加载 JSON 文件统计与数据库信息
+
+### 更改
+- 独立的锁定文件来获得更好的 Windows 兼容性
+- 当执行 start.py 时,即使 ZeroNet 已经运行也打开浏览器
+- 在重载时保持插件顺序来允许插件扩展另一个插件
+- 只在完整加载 sites.json 时保存来避免数据丢失
+- 将更多的 Tracker 更改为更可靠的 Tracker
+- 更少的 findhashid CPU 使用率
+- 合并下载大量可选文件
+- 更多对于可选文件的其他优化
+- 如果一个站点有 1000 个节点,更积极地清理
+- 为验证错误使用警告而不是错误
+- 首先推送更新到更新的客户端
+- 损坏文件重置改进
+
+### 修复
+- 修复启动时出现的站点删除错误
+- 延迟 WebSocket 消息直到连接上
+- 修复如果文件包含额外数据时的数据库导入
+- 修复大站点下载
+- 修复 diff 发送 bug (跟踪它好长时间了)
+- 修复当 JSON 文件包含 [] 字符时随机出现的发布错误
+- 修复 siteDelete 与 siteCreate bug
+- 修复文件写入确认对话框
+
+
+## ZeroNet 0.4.1 (2016-09-05)
+### 新增
+- 更快启动与更少内存使用的内核改变
+- 尝试连接丢失时重新连接 Tor
+- 侧边栏滑入
+- 尝试避免不完整的数据文件被覆盖
+- 更快地打开数据库
+- 在侧边栏显示用户文件大小
+- 依赖 --connection_limit 的并发 worker 数量
+
+
+### 更改
+- 在空闲 5 分钟后关闭数据库
+- 更好的站点大小计算
+- 允许在域名中使用“-”符号
+- 总是尝试为站点保持连接
+- 移除已合并站点的合并权限
+- 只扫描最后 3 天的新闻源来加快数据库请求
+- 更新 ZeroBundle-win 到 Python 2.7.12
+
+
+### 修复
+- 修复重要的安全问题:允许任意用户无需有效的来自 ID 提供者的证书发布新内容,感谢 Kaffie 指出
+- 修复在没有选择提供证书提供者时的侧边栏错误
+- 在数据库重建时跳过无效文件
+- 修复随机弹出的 WebSocket 连接错误
+- 修复新的 siteCreate 命令
+- 修复站点大小计算
+- 修复计算机唤醒后的端口打开检查
+- 修复 --size_limit 的命令行解析
+
+
+## ZeroNet 0.4.0 (2016-08-11)
+### 新增
+- 合并站点插件
+- Live source code reloading: Faster core development by allowing me to make changes in ZeroNet source code without restarting it.
+- 为合并站点设计的新 JSON 表
+- 从侧边栏重建数据库
+- 允许直接在 JSON 表中存储自定义数据:更简单与快速的 SQL 查询
+- 用户文件存档:允许站点拥有者存档不活跃的用户内容到单个文件(减少初始同步的时间/CPU/内存使用率)
+- 在文件删除时同时触发数据库 onUpdated/update
+- 从 ZeroFrame API 请求权限
+- 允许使用 fileWrite API 命令在 content.json 存储额外数据
+- 更快的可选文件下载
+- 使用替代源 (Gogs, Gitlab) 来下载更新
+- Track provided sites/connection and prefer to keep the ones with more sites to reduce connection number
+
+### 更改
+- 保持每个站点至少 5 个连接
+- 将目标站点连接从 10 更改到 15
+- ZeroHello 搜索功能稳定性/速度改进
+- 提升机械硬盘下的客户端性能
+
+### 修复
+- 修复 IE11 wrapper nonce 错误
+- 修复在移动设备上的侧边栏
+- 修复站点大小计算
+- 修复 IE10 兼容性
+- Windows XP ZeroBundle 兼容性(感谢中国人民)
+
+
+## ZeroNet 0.3.7 (2016-05-27)
+### 更改
+- 通过只传输补丁来减少带宽使用
+- 其他 CPU /内存优化
+
+
+## ZeroNet 0.3.6 (2016-05-27)
+### 新增
+- 新的 ZeroHello
+- Newsfeed 函数
+
+### 修复
+- 安全性修复
+
+
+## ZeroNet 0.3.5 (2016-02-02)
+### 新增
+- 带有 .onion 隐藏服务的完整 Tor 支持
+- 使用 ZeroNet 协议的 Bootstrap
+
+### 修复
+- 修复 Gevent 1.0.2 兼容性
+
+
+## ZeroNet 0.3.4 (2015-12-28)
+### 新增
+- AES, ECIES API 函数支持
+- PushState 与 ReplaceState URL 通过 API 的操作支持
+- 多用户 localstorage
diff --git a/README-zh-cn.md b/README-zh-cn.md
index 7bb1d307..0abff7a8 100644
--- a/README-zh-cn.md
+++ b/README-zh-cn.md
@@ -85,6 +85,12 @@
* 执行 `python zeronet.py` 来启动
* 在你的浏览器中打开 http://127.0.0.1:43110/
+### [FreeBSD](https://www.freebsd.org/)
+
+* `pkg install zeronet` 或者 `cd /usr/ports/security/zeronet/ && make install clean`
+* `sysrc zeronet_enable="YES"`
+* `service zeronet start`
+* 在你的浏览器中打开 http://127.0.0.1:43110/
### [Vagrant](https://www.vagrantup.com/)
diff --git a/plugins/Mute/languages/zh-tw.json b/plugins/Mute/languages/zh-tw.json
index b8590e38..3bdb5fc0 100644
--- a/plugins/Mute/languages/zh-tw.json
+++ b/plugins/Mute/languages/zh-tw.json
@@ -3,4 +3,4 @@
"Mute": "屏蔽",
"Unmute %s?": "對 %s 解除屏蔽?",
"Unmute": "解除屏蔽"
-}
\ No newline at end of file
+}
diff --git a/plugins/Mute/languages/zh.json b/plugins/Mute/languages/zh.json
index 5c48a7d8..beea7e77 100644
--- a/plugins/Mute/languages/zh.json
+++ b/plugins/Mute/languages/zh.json
@@ -3,4 +3,4 @@
"Mute": "屏蔽",
"Unmute %s?": "对 %s 解除屏蔽?",
"Unmute": "解除屏蔽"
-}
\ No newline at end of file
+}
diff --git a/plugins/Sidebar/media/Sidebar.coffee b/plugins/Sidebar/media/Sidebar.coffee
index db0bfb5e..69abab69 100644
--- a/plugins/Sidebar/media/Sidebar.coffee
+++ b/plugins/Sidebar/media/Sidebar.coffee
@@ -42,7 +42,7 @@ class Sidebar extends Class
e.preventDefault()
# Disable previous listeners
- @fixbutton.off "click touchstop touchcancel"
+ @fixbutton.off "click touchend touchcancel"
@fixbutton.off "mousemove touchmove"
# Make sure its not a click
@@ -54,7 +54,7 @@ class Sidebar extends Class
@fixbutton_addx = @fixbutton.offset().left-mousex
@startDrag()
- @fixbutton.parent().on "click touchstop touchcancel", (e) =>
+ @fixbutton.parent().on "click touchend touchcancel", (e) =>
@stopDrag()
@resized()
$(window).on "resize", @resized
@@ -96,7 +96,7 @@ class Sidebar extends Class
@fixbutton.parents().on "mousemove touchmove" ,@waitMove
# Stop dragging listener
- @fixbutton.parents().on "mouseup touchstop touchend touchcancel", (e) =>
+ @fixbutton.parents().on "mouseup touchend touchend touchcancel", (e) =>
e.preventDefault()
@stopDrag()
@@ -253,13 +253,13 @@ class Sidebar extends Class
@scrollable()
# Re-calculate height when site admin opened or closed
- @tag.find("#checkbox-owned").off("click").on "click", =>
+ @tag.find("#checkbox-owned").off("click touchend").on "click touchend", =>
setTimeout (=>
@scrollable()
), 300
# Site limit button
- @tag.find("#button-sitelimit").off("click").on "click", =>
+ @tag.find("#button-sitelimit").off("click touchend").on "click touchend", =>
wrapper.ws.cmd "siteSetLimit", $("#input-sitelimit").val(), (res) =>
if res == "ok"
wrapper.notifications.add "done-sitelimit", "done", "Site storage limit modified!", 5000
@@ -267,14 +267,14 @@ class Sidebar extends Class
return false
# Database reload
- @tag.find("#button-dbreload").off("click").on "click", =>
+ @tag.find("#button-dbreload").off("click touchend").on "click touchend", =>
wrapper.ws.cmd "dbReload", [], =>
wrapper.notifications.add "done-dbreload", "done", "Database schema reloaded!", 5000
@updateHtmlTag()
return false
# Database rebuild
- @tag.find("#button-dbrebuild").off("click").on "click", =>
+ @tag.find("#button-dbrebuild").off("click touchend").on "click touchend", =>
wrapper.notifications.add "done-dbrebuild", "info", "Database rebuilding...."
wrapper.ws.cmd "dbRebuild", [], =>
wrapper.notifications.add "done-dbrebuild", "done", "Database rebuilt!", 5000
@@ -282,7 +282,7 @@ class Sidebar extends Class
return false
# Update site
- @tag.find("#button-update").off("click").on "click", =>
+ @tag.find("#button-update").off("click touchend").on "click touchend", =>
@tag.find("#button-update").addClass("loading")
wrapper.ws.cmd "siteUpdate", wrapper.site_info.address, =>
wrapper.notifications.add "done-updated", "done", "Site updated!", 5000
@@ -290,19 +290,19 @@ class Sidebar extends Class
return false
# Pause site
- @tag.find("#button-pause").off("click").on "click", =>
+ @tag.find("#button-pause").off("click touchend").on "click touchend", =>
@tag.find("#button-pause").addClass("hidden")
wrapper.ws.cmd "sitePause", wrapper.site_info.address
return false
# Resume site
- @tag.find("#button-resume").off("click").on "click", =>
+ @tag.find("#button-resume").off("click touchend").on "click touchend", =>
@tag.find("#button-resume").addClass("hidden")
wrapper.ws.cmd "siteResume", wrapper.site_info.address
return false
# Delete site
- @tag.find("#button-delete").off("click").on "click", =>
+ @tag.find("#button-delete").off("click touchend").on "click touchend", =>
wrapper.displayConfirm "Are you sure?", "Delete this site", =>
@tag.find("#button-delete").addClass("loading")
wrapper.ws.cmd "siteDelete", wrapper.site_info.address, ->
@@ -310,24 +310,24 @@ class Sidebar extends Class
return false
# Owned checkbox
- @tag.find("#checkbox-owned").off("click").on "click", =>
+ @tag.find("#checkbox-owned").off("click touchend").on "click touchend", =>
wrapper.ws.cmd "siteSetOwned", [@tag.find("#checkbox-owned").is(":checked")]
# Owned checkbox
- @tag.find("#checkbox-autodownloadoptional").off("click").on "click", =>
+ @tag.find("#checkbox-autodownloadoptional").off("click touchend").on "click touchend", =>
wrapper.ws.cmd "siteSetAutodownloadoptional", [@tag.find("#checkbox-autodownloadoptional").is(":checked")]
# Change identity button
- @tag.find("#button-identity").off("click").on "click", =>
+ @tag.find("#button-identity").off("click touchend").on "click touchend", =>
wrapper.ws.cmd "certSelect"
return false
# Owned checkbox
- @tag.find("#checkbox-owned").off("click").on "click", =>
+ @tag.find("#checkbox-owned").off("click touchend").on "click touchend", =>
wrapper.ws.cmd "siteSetOwned", [@tag.find("#checkbox-owned").is(":checked")]
# Save settings
- @tag.find("#button-settings").off("click").on "click", =>
+ @tag.find("#button-settings").off("click touchend").on "click touchend", =>
wrapper.ws.cmd "fileGet", "content.json", (res) =>
data = JSON.parse(res)
data["title"] = $("#settings-title").val()
@@ -342,7 +342,7 @@ class Sidebar extends Class
return false
# Sign content.json
- @tag.find("#button-sign").off("click").on "click", =>
+ @tag.find("#button-sign").off("click touchend").on "click touchend", =>
inner_path = @tag.find("#input-contents").val()
if wrapper.site_info.privatekey
@@ -360,7 +360,7 @@ class Sidebar extends Class
return false
# Publish content.json
- @tag.find("#button-publish").off("click").on "click", =>
+ @tag.find("#button-publish").off("click touchend").on "click touchend", =>
inner_path = @tag.find("#input-contents").val()
@tag.find("#button-publish").addClass "loading"
wrapper.ws.cmd "sitePublish", {"inner_path": inner_path, "sign": false}, =>
diff --git a/plugins/Sidebar/media/all.js b/plugins/Sidebar/media/all.js
index bf05eb49..bed431c2 100644
--- a/plugins/Sidebar/media/all.js
+++ b/plugins/Sidebar/media/all.js
@@ -241,7 +241,7 @@ window.initScrollable = function () {
return;
}
e.preventDefault();
- _this.fixbutton.off("click touchstop touchcancel");
+ _this.fixbutton.off("click touchend touchcancel");
_this.fixbutton.off("mousemove touchmove");
_this.dragStarted = +(new Date);
return _this.fixbutton.one("mousemove touchmove", function(e) {
@@ -255,7 +255,7 @@ window.initScrollable = function () {
});
};
})(this));
- this.fixbutton.parent().on("click touchstop touchcancel", (function(_this) {
+ this.fixbutton.parent().on("click touchend touchcancel", (function(_this) {
return function(e) {
return _this.stopDrag();
};
@@ -297,7 +297,7 @@ window.initScrollable = function () {
})(this));
this.fixbutton.parents().on("mousemove touchmove", this.animDrag);
this.fixbutton.parents().on("mousemove touchmove", this.waitMove);
- return this.fixbutton.parents().on("mouseup touchstop touchend touchcancel", (function(_this) {
+ return this.fixbutton.parents().on("mouseup touchend touchend touchcancel", (function(_this) {
return function(e) {
e.preventDefault();
return _this.stopDrag();
@@ -473,14 +473,14 @@ window.initScrollable = function () {
Sidebar.prototype.onOpened = function() {
this.log("Opened");
this.scrollable();
- this.tag.find("#checkbox-owned").off("click").on("click", (function(_this) {
+ this.tag.find("#checkbox-owned").off("click touchend").on("click touchend", (function(_this) {
return function() {
return setTimeout((function() {
return _this.scrollable();
}), 300);
};
})(this));
- this.tag.find("#button-sitelimit").off("click").on("click", (function(_this) {
+ this.tag.find("#button-sitelimit").off("click touchend").on("click touchend", (function(_this) {
return function() {
wrapper.ws.cmd("siteSetLimit", $("#input-sitelimit").val(), function(res) {
if (res === "ok") {
@@ -491,7 +491,7 @@ window.initScrollable = function () {
return false;
};
})(this));
- this.tag.find("#button-dbreload").off("click").on("click", (function(_this) {
+ this.tag.find("#button-dbreload").off("click touchend").on("click touchend", (function(_this) {
return function() {
wrapper.ws.cmd("dbReload", [], function() {
wrapper.notifications.add("done-dbreload", "done", "Database schema reloaded!", 5000);
@@ -500,7 +500,7 @@ window.initScrollable = function () {
return false;
};
})(this));
- this.tag.find("#button-dbrebuild").off("click").on("click", (function(_this) {
+ this.tag.find("#button-dbrebuild").off("click touchend").on("click touchend", (function(_this) {
return function() {
wrapper.notifications.add("done-dbrebuild", "info", "Database rebuilding....");
wrapper.ws.cmd("dbRebuild", [], function() {
@@ -510,7 +510,7 @@ window.initScrollable = function () {
return false;
};
})(this));
- this.tag.find("#button-update").off("click").on("click", (function(_this) {
+ this.tag.find("#button-update").off("click touchend").on("click touchend", (function(_this) {
return function() {
_this.tag.find("#button-update").addClass("loading");
wrapper.ws.cmd("siteUpdate", wrapper.site_info.address, function() {
@@ -520,21 +520,21 @@ window.initScrollable = function () {
return false;
};
})(this));
- this.tag.find("#button-pause").off("click").on("click", (function(_this) {
+ this.tag.find("#button-pause").off("click touchend").on("click touchend", (function(_this) {
return function() {
_this.tag.find("#button-pause").addClass("hidden");
wrapper.ws.cmd("sitePause", wrapper.site_info.address);
return false;
};
})(this));
- this.tag.find("#button-resume").off("click").on("click", (function(_this) {
+ this.tag.find("#button-resume").off("click touchend").on("click touchend", (function(_this) {
return function() {
_this.tag.find("#button-resume").addClass("hidden");
wrapper.ws.cmd("siteResume", wrapper.site_info.address);
return false;
};
})(this));
- this.tag.find("#button-delete").off("click").on("click", (function(_this) {
+ this.tag.find("#button-delete").off("click touchend").on("click touchend", (function(_this) {
return function() {
wrapper.displayConfirm("Are you sure?", "Delete this site", function() {
_this.tag.find("#button-delete").addClass("loading");
@@ -545,28 +545,28 @@ window.initScrollable = function () {
return false;
};
})(this));
- this.tag.find("#checkbox-owned").off("click").on("click", (function(_this) {
+ this.tag.find("#checkbox-owned").off("click touchend").on("click touchend", (function(_this) {
return function() {
return wrapper.ws.cmd("siteSetOwned", [_this.tag.find("#checkbox-owned").is(":checked")]);
};
})(this));
- this.tag.find("#checkbox-autodownloadoptional").off("click").on("click", (function(_this) {
+ this.tag.find("#checkbox-autodownloadoptional").off("click touchend").on("click touchend", (function(_this) {
return function() {
return wrapper.ws.cmd("siteSetAutodownloadoptional", [_this.tag.find("#checkbox-autodownloadoptional").is(":checked")]);
};
})(this));
- this.tag.find("#button-identity").off("click").on("click", (function(_this) {
+ this.tag.find("#button-identity").off("click touchend").on("click touchend", (function(_this) {
return function() {
wrapper.ws.cmd("certSelect");
return false;
};
})(this));
- this.tag.find("#checkbox-owned").off("click").on("click", (function(_this) {
+ this.tag.find("#checkbox-owned").off("click touchend").on("click touchend", (function(_this) {
return function() {
return wrapper.ws.cmd("siteSetOwned", [_this.tag.find("#checkbox-owned").is(":checked")]);
};
})(this));
- this.tag.find("#button-settings").off("click").on("click", (function(_this) {
+ this.tag.find("#button-settings").off("click touchend").on("click touchend", (function(_this) {
return function() {
wrapper.ws.cmd("fileGet", "content.json", function(res) {
var data, json_raw;
@@ -586,7 +586,7 @@ window.initScrollable = function () {
return false;
};
})(this));
- this.tag.find("#button-sign").off("click").on("click", (function(_this) {
+ this.tag.find("#button-sign").off("click touchend").on("click touchend", (function(_this) {
return function() {
var inner_path;
inner_path = _this.tag.find("#input-contents").val();
@@ -614,7 +614,7 @@ window.initScrollable = function () {
return false;
};
})(this));
- this.tag.find("#button-publish").off("click").on("click", (function(_this) {
+ this.tag.find("#button-publish").off("click touchend").on("click touchend", (function(_this) {
return function() {
var inner_path;
inner_path = _this.tag.find("#input-contents").val();