mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-11-03 20:45:58 +01:00 
			
		
		
		
	Merge branch 'master' into patch-pitaj
This commit is contained in:
		@@ -97,7 +97,8 @@
 | 
			
		||||
    "validator": "^6.1.0",
 | 
			
		||||
    "winston": "^2.1.0",
 | 
			
		||||
    "xml": "^1.0.1",
 | 
			
		||||
    "xregexp": "~3.1.0"
 | 
			
		||||
    "xregexp": "~3.1.0",
 | 
			
		||||
    "zxcvbn": "^4.4.2"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "coveralls": "^2.11.14",
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
	"headers.allow-from": "Set ALLOW-FROM to Place NodeBB in an iFrame",
 | 
			
		||||
	"headers.powered-by": "Customise the \"Powered By\" header sent by NodeBB",
 | 
			
		||||
	"headers.acao": "Access-Control-Allow-Origin",
 | 
			
		||||
	"headers.acao-help": "To deny access to all sites, leave empty or set to <code>null</code>",
 | 
			
		||||
	"headers.acao-help": "To deny access to all sites, leave empty",
 | 
			
		||||
	"headers.acam": "Access-Control-Allow-Methods",
 | 
			
		||||
	"headers.acah": "Access-Control-Allow-Headers",
 | 
			
		||||
	"traffic-management": "Traffic Management",
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,7 @@
 | 
			
		||||
	"min-username-length": "Minimum Username Length",
 | 
			
		||||
	"max-username-length": "Maximum Username Length",
 | 
			
		||||
	"min-password-length": "Minimum Password Length",
 | 
			
		||||
	"min-password-strength": "Minimum Password Strength",
 | 
			
		||||
	"max-about-me-length": "Maximum About Me Length",
 | 
			
		||||
	"terms-of-use": "Forum Terms of Use <small>(Leave blank to disable)</small>",
 | 
			
		||||
	"user-search": "User Search",
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@
 | 
			
		||||
	"username_taken_workaround": "The username you requested was already taken, so we have altered it slightly. You are now known as <strong>%1</strong>",
 | 
			
		||||
	"password_same_as_username": "Your password is the same as your username, please select another password.",
 | 
			
		||||
	"password_same_as_email": "Your password is the same as your email, please select another password.",
 | 
			
		||||
	"weak_password": "Weak password.",
 | 
			
		||||
 | 
			
		||||
	"upload_picture": "Upload picture",
 | 
			
		||||
	"upload_a_picture": "Upload a picture",
 | 
			
		||||
 
 | 
			
		||||
@@ -10,17 +10,17 @@
 | 
			
		||||
    "return_to": "Geri dön.",
 | 
			
		||||
    "new_notification": "Yeni bildirim",
 | 
			
		||||
    "you_have_unread_notifications": "Okunmamış bildirimleriniz var.",
 | 
			
		||||
    "all": "All",
 | 
			
		||||
    "topics": "Topics",
 | 
			
		||||
    "replies": "Replies",
 | 
			
		||||
    "chat": "Chats",
 | 
			
		||||
    "follows": "Follows",
 | 
			
		||||
    "all": "Hepsi",
 | 
			
		||||
    "topics": "Başlıklar",
 | 
			
		||||
    "replies": "Yanıtlar",
 | 
			
		||||
    "chat": "Sohbetler",
 | 
			
		||||
    "follows": "Takip ediyor",
 | 
			
		||||
    "upvote": "Upvotes",
 | 
			
		||||
    "new-flags": "New Flags",
 | 
			
		||||
    "new-flags": "Yeni Bayrak",
 | 
			
		||||
    "my-flags": "Flags assigned to me",
 | 
			
		||||
    "bans": "Bans",
 | 
			
		||||
    "bans": "Yasaklamalar",
 | 
			
		||||
    "new_message_from": "<strong>%1</strong> size bir mesaj gönderdi",
 | 
			
		||||
    "upvoted_your_post_in": "<strong>%1</strong> iletinizi beğendi. <strong>%2</strong>",
 | 
			
		||||
    "upvoted_your_post_in": "<strong>%1</strong> iletinizi beğendi. <strong>%2</strong>.",
 | 
			
		||||
    "upvoted_your_post_in_dual": "<strong>%1</strong> ve <strong>%2</strong> <strong>%3</strong> içindeki gönderini beğendi.",
 | 
			
		||||
    "upvoted_your_post_in_multiple": "<strong>%1</strong> ve %2 iki kişi daha <strong>%3</strong> içindeki gönderini beğendi.",
 | 
			
		||||
    "moved_your_post": "<strong>%1</strong> senin iletin <strong>%2</strong> taşındı",
 | 
			
		||||
 
 | 
			
		||||
@@ -131,5 +131,5 @@
 | 
			
		||||
    "info.email-history": "Email Geçmişi",
 | 
			
		||||
    "info.moderation-note": "Moderasyon Notu",
 | 
			
		||||
    "info.moderation-note.success": "Moderasyon notu kaydedildi",
 | 
			
		||||
    "info.moderation-note.add": "Add note"
 | 
			
		||||
    "info.moderation-note.add": "Not ekle"
 | 
			
		||||
}
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
	"container.alert": "警报",
 | 
			
		||||
 | 
			
		||||
	"alert.confirm-delete": "确认删除此窗口部件?",
 | 
			
		||||
	"alert.updated": "窗口部件升级",
 | 
			
		||||
	"alert.update-success": "已成功升级窗口部件"
 | 
			
		||||
	"alert.updated": "窗口部件更新",
 | 
			
		||||
	"alert.update-success": "已成功更新窗口部件"
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -35,12 +35,12 @@
 | 
			
		||||
	"privileges.section-user": "用户",
 | 
			
		||||
	"privileges.search-user": "添加用户",
 | 
			
		||||
	"privileges.no-users": "此板块中没有用户特定的权限。",
 | 
			
		||||
	"privileges.section-group": "用户组",
 | 
			
		||||
	"privileges.group-private": "这个用户组是私密的",
 | 
			
		||||
	"privileges.search-group": "添加用户组",
 | 
			
		||||
	"privileges.section-group": "群组",
 | 
			
		||||
	"privileges.group-private": "这个群组是私密的",
 | 
			
		||||
	"privileges.search-group": "添加群组",
 | 
			
		||||
	"privileges.copy-to-children": "复制到子版块",
 | 
			
		||||
	"privileges.copy-from-category": "从板块复制",
 | 
			
		||||
	"privileges.inherit": "如果 <code>registered-users</code> 组被授予特定权限,所有其他组都会收到<strong>隐式权限</strong>,即使它们未被明确定义/检查。 将显示此隐式权限,因为所有用户都是 <code>registered-users</code> 用户组的一部分,因此无需显式授予其他组的权限。",
 | 
			
		||||
	"privileges.inherit": "如果 <code>registered-users</code> 组被授予特定权限,所有其他组都会收到<strong>隐式权限</strong>,即使它们未被明确定义/检查。 将显示此隐式权限,因为所有用户都是 <code>registered-users</code> 群组的一部分,因此无需显式授予其他组的权限。",
 | 
			
		||||
 | 
			
		||||
	"analytics.back": "返回板块列表",
 | 
			
		||||
	"analytics.title": "“%1”板块的统计",
 | 
			
		||||
@@ -53,7 +53,7 @@
 | 
			
		||||
	"alert.create-success": "板块创建成功!",
 | 
			
		||||
	"alert.none-active": "您没有有效的板块。",
 | 
			
		||||
	"alert.create": "创建一个板块",
 | 
			
		||||
	"alert.confirm-moderate": "<strong>您确定要将审核权限授予此用户组吗?</strong>此用户组是公开的,任何用户都可以随意加入。",
 | 
			
		||||
	"alert.confirm-moderate": "<strong>您确定要将审核权限授予此群组吗?</strong>此群组是公开的,任何用户都可以随意加入。",
 | 
			
		||||
	"alert.confirm-purge": "<p class =“lead”>您确定要清除此板块“%1”吗?</p> <h5> <strong class =“text-danger”>警告!</strong> 板块将被清除!</h5> <p class =“help-block”>清除板块将删除所有主题和帖子,并从数据库中删除板块。 如果您想<em>暂时</em>移除板块,请使用停用板块。</p>",
 | 
			
		||||
	"alert.purge-success": "板块已删除!",
 | 
			
		||||
	"alert.copy-success": "设置已复制!",
 | 
			
		||||
@@ -63,6 +63,6 @@
 | 
			
		||||
	"alert.upload-image": "上传板块图片",
 | 
			
		||||
	"alert.find-user": "查找用户",
 | 
			
		||||
	"alert.user-search": "在这里查找用户…",
 | 
			
		||||
	"alert.find-group": "查找用户组",
 | 
			
		||||
	"alert.group-search": "在此处搜索用户组..."
 | 
			
		||||
	"alert.find-group": "查找群组",
 | 
			
		||||
	"alert.group-search": "在此处搜索群组..."
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
{
 | 
			
		||||
	"daily": "每日举报数",
 | 
			
		||||
	"daily": "日举报",
 | 
			
		||||
	"by-user": "用户举报",
 | 
			
		||||
	"by-user-search": "根据用户名搜索被举报帖子",
 | 
			
		||||
	"category": "版块",
 | 
			
		||||
	"sort-by": "排序",
 | 
			
		||||
	"sort-by.most-flags": "举报最多",
 | 
			
		||||
	"sort-by.most-recent": "最近",
 | 
			
		||||
	"sort-by.most-flags": "次数最多",
 | 
			
		||||
	"sort-by.most-recent": "提交时间",
 | 
			
		||||
	"search": "搜索",
 | 
			
		||||
	"dismiss-all": "全部忽略",
 | 
			
		||||
	"none-flagged": "没有被举报的帖子!",
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
	"read-more": "阅读更多",
 | 
			
		||||
	"flagged-x-times": "该贴已被举报 %1 次:",
 | 
			
		||||
	"dismiss": "忽略该举报",
 | 
			
		||||
	"delete-post": "删除该贴",
 | 
			
		||||
	"delete-post": "删除此贴",
 | 
			
		||||
 | 
			
		||||
	"alerts.confirm-delete-post": "确认删除该贴?"
 | 
			
		||||
	"alerts.confirm-delete-post": "确定删除此贴吗?"
 | 
			
		||||
}
 | 
			
		||||
@@ -1,31 +1,31 @@
 | 
			
		||||
{
 | 
			
		||||
	"name": "用户组名",
 | 
			
		||||
	"description": "用户组描述",
 | 
			
		||||
	"system": "系统用户组",
 | 
			
		||||
	"name": "群组名",
 | 
			
		||||
	"description": "群组描述",
 | 
			
		||||
	"system": "系统群组",
 | 
			
		||||
	"edit": "编辑",
 | 
			
		||||
	"search-placeholder": "搜索",
 | 
			
		||||
	"create": "创建用户组",
 | 
			
		||||
	"description-placeholder": "一个关于你的用户组的简短描述",
 | 
			
		||||
	"create": "创建群组",
 | 
			
		||||
	"description-placeholder": "一个关于你的群组的简短描述",
 | 
			
		||||
	"create-button": "创建",
 | 
			
		||||
 | 
			
		||||
	"alerts.create-failure": "<strong>哦不!</strong><p>创建您的用户组时出现问题。 请稍后再试!</p>",
 | 
			
		||||
	"alerts.confirm-delete": "确认要删除这个用户组么?",
 | 
			
		||||
	"alerts.create-failure": "<strong>哦不!</strong><p>创建您的群组时出现问题。 请稍后再试!</p>",
 | 
			
		||||
	"alerts.confirm-delete": "确认要删除这个群组么?",
 | 
			
		||||
 | 
			
		||||
	"edit.name": "名字",
 | 
			
		||||
	"edit.description": "描述",
 | 
			
		||||
	"edit.user-title": "成员标题",
 | 
			
		||||
	"edit.icon": "用户组标志",
 | 
			
		||||
	"edit.icon": "群组标志",
 | 
			
		||||
	"edit.label-color": "群组标签颜色",
 | 
			
		||||
	"edit.show-badge": "显示徽章",
 | 
			
		||||
	"edit.private-details": "启用此选项后,加入用户组的请求将需要组长审批。",
 | 
			
		||||
	"edit.private-override": "警告:系统禁用了私有用户组,优先于该选项。",
 | 
			
		||||
	"edit.private-details": "启用此选项后,加入群组的请求将需要群组所有者审批。",
 | 
			
		||||
	"edit.private-override": "警告:系统已禁用了私有群组,优先级高于该选项。",
 | 
			
		||||
	"edit.disable-requests": "禁止加入请求",
 | 
			
		||||
	"edit.hidden": "隐藏",
 | 
			
		||||
	"edit.hidden-details": "启用此选项后,此用户组将不在用户组列表展现,并且用户只能被手动邀请加入",
 | 
			
		||||
	"edit.add-user": "向此小组添加成员",
 | 
			
		||||
	"edit.hidden-details": "启用此选项后,此群组将不在群组列表展现,并且用户只能被手动邀请加入",
 | 
			
		||||
	"edit.add-user": "向此群组添加成员",
 | 
			
		||||
	"edit.add-user-search": "搜索用户",
 | 
			
		||||
	"edit.members": "成员列表",
 | 
			
		||||
	"control-panel": "小组控制面板",
 | 
			
		||||
	"control-panel": "群组控制面板",
 | 
			
		||||
	"revert": "重置",
 | 
			
		||||
 | 
			
		||||
	"edit.no-users-found": "没有找到用户",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
	"queue": "队列",
 | 
			
		||||
	"description": "注册队列里面没有用户。<br>要开启这项功能,请去<a href=\"%1\">设置 → 用户 → 用户注册</a> 并设置<strong>注册类型</strong>为“管理员批准”。",
 | 
			
		||||
	"queue": "申请",
 | 
			
		||||
	"description": "注册申请队列里面还没有用户申请。<br>要开启这项功能,请去<a href=\"%1\">设置 → 用户 → 用户注册</a> 并设置<strong>注册类型</strong>为“管理员批准”。",
 | 
			
		||||
 | 
			
		||||
	"list.name": "姓名",
 | 
			
		||||
	"list.email": "邮件",
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
	"manage/tags": "话题",
 | 
			
		||||
	"manage/users": "用户",
 | 
			
		||||
	"manage/registration": "注册申请",
 | 
			
		||||
	"manage/groups": "用户组",
 | 
			
		||||
	"manage/groups": "群组",
 | 
			
		||||
	"manage/ip-blacklist": "IP 黑名单",
 | 
			
		||||
 | 
			
		||||
	"section-settings": "设置",
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
	"settings/reputation": "声望",
 | 
			
		||||
	"settings/email": "邮件",
 | 
			
		||||
	"settings/user": "用户",
 | 
			
		||||
	"settings/group": "用户组",
 | 
			
		||||
	"settings/group": "群组",
 | 
			
		||||
	"settings/guest": "游客",
 | 
			
		||||
	"settings/uploads": "上传",
 | 
			
		||||
	"settings/post": "发帖",
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
	"headers.acam": "Access-Control-Allow-Methods",
 | 
			
		||||
	"headers.acah": "Access-Control-Allow-Headers",
 | 
			
		||||
	"traffic-management": "流量管理",
 | 
			
		||||
	"traffic.help": "NodeBB 拥有在高流量情况下自动拒绝请求的模块。 您可以在这里调整这些设置,虽然默认值就很棒。",
 | 
			
		||||
	"traffic.help": "NodeBB 拥有在高流量情况下自动拒绝请求的模块。尽管默认值就很棒,但您可以在这里调整这些设置。",
 | 
			
		||||
	"traffic.enable": "启用流量管理",
 | 
			
		||||
	"traffic.event-lag": "事件循环滞后阈值(毫秒)",
 | 
			
		||||
	"traffic.event-lag-help": "降低此值会减少页面加载的等待时间,但也会向更多用户显示“过载”消息。(需要重新启动)",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
	"general": "通用",
 | 
			
		||||
	"private-groups": "私有用户组",
 | 
			
		||||
	"private-groups.help": "启用此选项后,加入用户组需要组长审批<em>(默认启用)</em>。",
 | 
			
		||||
	"private-groups.warning": "<strong>注意!</strong>如果这个选项未启用并且你有私有用户组,那么你的用户组将变为公共的。",
 | 
			
		||||
	"allow-creation": "允许创建用户组",
 | 
			
		||||
	"allow-creation-help": "如果启用,用户就可以创建用户组<em>(默认:不启用)</em>",
 | 
			
		||||
	"max-name-length": "用户组名字的最大长度",
 | 
			
		||||
	"cover-image": "用户组封面图片",
 | 
			
		||||
	"private-groups": "私有群组",
 | 
			
		||||
	"private-groups.help": "启用此选项后,加入用户组需要群组所有者审批<em>(默认启用)</em>。",
 | 
			
		||||
	"private-groups.warning": "<strong>注意!</strong>如果这个选项未启用并且你有私有群组,那么你的群组将变为公共的。",
 | 
			
		||||
	"allow-creation": "允许创建群组",
 | 
			
		||||
	"allow-creation-help": "如果启用,用户就可以创建群组<em>(默认:不启用)</em>",
 | 
			
		||||
	"max-name-length": "群组名字的最大长度",
 | 
			
		||||
	"cover-image": "群组封面图片",
 | 
			
		||||
	"default-cover": "默认封面图片",
 | 
			
		||||
	"default-cover-help": "为没有上传封面图片的群组添加以逗号分隔的默认封面图片"
 | 
			
		||||
}
 | 
			
		||||
@@ -21,7 +21,7 @@
 | 
			
		||||
    "email-not-confirmed": "您的电子邮箱尚未确认,请点击这里确认您的电子邮箱。",
 | 
			
		||||
    "email-not-confirmed-chat": "您的电子邮箱尚未确认,无法聊天,请点击这里确认您的电子邮箱。",
 | 
			
		||||
    "email-not-confirmed-email-sent": "您的邮箱地址还没有被确认,请检查邮箱中的确认邮件。",
 | 
			
		||||
    "no-email-to-confirm": "本社区需要电子邮箱确认,请点击这里输入电子邮箱地址",
 | 
			
		||||
    "no-email-to-confirm": "本论坛需要电子邮箱确认,请点击这里输入电子邮箱地址",
 | 
			
		||||
    "email-confirm-failed": "我们无法确认您的电子邮箱,请重试",
 | 
			
		||||
    "confirm-email-already-sent": "确认邮件已发出,如需重新发送请等待 %1 分钟后再试。",
 | 
			
		||||
    "sendmail-not-found": "无法找到 sendmail 可执行程序,请确保 sendmail 已经安装并可被运行 NodeBB 的用户执行",
 | 
			
		||||
@@ -36,7 +36,7 @@
 | 
			
		||||
    "no-category": "版块不存在",
 | 
			
		||||
    "no-topic": "主题不存在",
 | 
			
		||||
    "no-post": "帖子不存在",
 | 
			
		||||
    "no-group": "用户组不存在",
 | 
			
		||||
    "no-group": "群组不存在",
 | 
			
		||||
    "no-user": "用户不存在",
 | 
			
		||||
    "no-teaser": "主题预览不存在",
 | 
			
		||||
    "no-privileges": "您没有权限执行此操作。",
 | 
			
		||||
@@ -80,13 +80,13 @@
 | 
			
		||||
    "invalid-image-type": "无效的图像类型。允许的类型有:%1",
 | 
			
		||||
    "invalid-image-extension": "无效的图像扩展",
 | 
			
		||||
    "invalid-file-type": "无效文件格式,允许的格式有:%1",
 | 
			
		||||
    "group-name-too-short": "用户组名太短",
 | 
			
		||||
    "group-name-too-long": "用户组名太长",
 | 
			
		||||
    "group-already-exists": "用户组已存在",
 | 
			
		||||
    "group-name-change-not-allowed": "不允许更改用户组名称",
 | 
			
		||||
    "group-already-member": "已经是此用户组的成员",
 | 
			
		||||
    "group-not-member": "不是此用户组的成员",
 | 
			
		||||
    "group-needs-owner": "用户组需要指定至少一名组长",
 | 
			
		||||
    "group-name-too-short": "群组名太短",
 | 
			
		||||
    "group-name-too-long": "群组名太长",
 | 
			
		||||
    "group-already-exists": "群组已存在",
 | 
			
		||||
    "group-name-change-not-allowed": "不允许更改群组名称",
 | 
			
		||||
    "group-already-member": "已经是此群组的成员",
 | 
			
		||||
    "group-not-member": "不是此群组的成员",
 | 
			
		||||
    "group-needs-owner": "群组需要指定至少一名群组所有者",
 | 
			
		||||
    "group-already-invited": "您已邀请该用户",
 | 
			
		||||
    "group-already-requested": "已提交您的请求",
 | 
			
		||||
    "post-already-deleted": "此帖已被删除",
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@
 | 
			
		||||
    "header.tags": "话题",
 | 
			
		||||
    "header.popular": "热门",
 | 
			
		||||
    "header.users": "会员",
 | 
			
		||||
    "header.groups": "用户组",
 | 
			
		||||
    "header.groups": "群组",
 | 
			
		||||
    "header.chats": "聊天",
 | 
			
		||||
    "header.notifications": "通知",
 | 
			
		||||
    "header.search": "搜索",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
    "groups": "用户组",
 | 
			
		||||
    "view_group": "查看用户组",
 | 
			
		||||
    "owner": "组长",
 | 
			
		||||
    "new_group": "创建用户组",
 | 
			
		||||
    "no_groups_found": "尚无用户组信息",
 | 
			
		||||
    "groups": "群组",
 | 
			
		||||
    "view_group": "查看群组",
 | 
			
		||||
    "owner": "群组所有者",
 | 
			
		||||
    "new_group": "创建群组",
 | 
			
		||||
    "no_groups_found": "尚无群组信息",
 | 
			
		||||
    "pending.accept": "接受",
 | 
			
		||||
    "pending.reject": "拒绝",
 | 
			
		||||
    "pending.accept_all": "全部同意",
 | 
			
		||||
@@ -11,25 +11,25 @@
 | 
			
		||||
    "pending.none": "暂时没有待加入的成员",
 | 
			
		||||
    "invited.none": "暂时没有接受邀请的成员",
 | 
			
		||||
    "invited.uninvite": "取消邀请",
 | 
			
		||||
    "invited.search": "选择用户加入用户组",
 | 
			
		||||
    "invited.search": "选择用户加入群组",
 | 
			
		||||
    "invited.notification_title": "您已被邀请加入 <strong>%1</strong>",
 | 
			
		||||
    "request.notification_title": "来自 <strong>%1</strong> 的用户组成员请求",
 | 
			
		||||
    "request.notification_title": "来自 <strong>%1</strong> 的群组成员请求",
 | 
			
		||||
    "request.notification_text": "<strong>%1</strong> 已被邀请加入 <strong>%2</strong>",
 | 
			
		||||
    "cover-save": "保存",
 | 
			
		||||
    "cover-saving": "正在保存",
 | 
			
		||||
    "details.title": "用户组信息",
 | 
			
		||||
    "details.title": "群组信息",
 | 
			
		||||
    "details.members": "成员列表",
 | 
			
		||||
    "details.pending": "待加入成员",
 | 
			
		||||
    "details.invited": "已邀请成员",
 | 
			
		||||
    "details.has_no_posts": "此用户组的会员尚未发表任何帖子。",
 | 
			
		||||
    "details.has_no_posts": "此群组的会员尚未发表任何帖子。",
 | 
			
		||||
    "details.latest_posts": "最新帖子",
 | 
			
		||||
    "details.private": "私有",
 | 
			
		||||
    "details.disableJoinRequests": "禁止申请加入用户组",
 | 
			
		||||
    "details.grant": "授予/取消管理权",
 | 
			
		||||
    "details.kick": "踢出用户组",
 | 
			
		||||
    "details.kick_confirm": "您确定要将此成员从用户组中移除吗?",
 | 
			
		||||
    "details.owner_options": "用户组管理",
 | 
			
		||||
    "details.group_name": "用户组名",
 | 
			
		||||
    "details.kick_confirm": "您确定要将此成员从群组中移除吗?",
 | 
			
		||||
    "details.owner_options": "群组管理",
 | 
			
		||||
    "details.group_name": "群组名",
 | 
			
		||||
    "details.member_count": "用户组成员数",
 | 
			
		||||
    "details.creation_date": "创建时间",
 | 
			
		||||
    "details.description": "描述",
 | 
			
		||||
@@ -38,21 +38,21 @@
 | 
			
		||||
    "details.change_colour": "更改颜色",
 | 
			
		||||
    "details.badge_text": "徽章文本",
 | 
			
		||||
    "details.userTitleEnabled": "显示组内称号",
 | 
			
		||||
    "details.private_help": "启用此选项后,加入用户组需要组长审批。",
 | 
			
		||||
    "details.private_help": "启用此选项后,加入群组需要组长审批。",
 | 
			
		||||
    "details.hidden": "隐藏",
 | 
			
		||||
    "details.hidden_help": "启用此选项后,用户组将不在用户组列表中展现,成员只能通过邀请加入。",
 | 
			
		||||
    "details.delete_group": "删除用户组",
 | 
			
		||||
    "details.private_system_help": "系统禁用了私有用户组,这个选项不起任何作用",
 | 
			
		||||
    "event.updated": "用户组信息已更新",
 | 
			
		||||
    "event.deleted": "用户组 \"%1\" 已被删除",
 | 
			
		||||
    "details.hidden_help": "启用此选项后,群组将不在群组列表中展现,成员只能通过邀请加入。",
 | 
			
		||||
    "details.delete_group": "删除群组",
 | 
			
		||||
    "details.private_system_help": "系统禁用了私有群组,这个选项不起任何作用",
 | 
			
		||||
    "event.updated": "群组信息已更新",
 | 
			
		||||
    "event.deleted": "群组 \"%1\" 已被删除",
 | 
			
		||||
    "membership.accept-invitation": "接受邀请",
 | 
			
		||||
    "membership.invitation-pending": "邀请中",
 | 
			
		||||
    "membership.join-group": "加入用户组",
 | 
			
		||||
    "membership.leave-group": "退出用户组",
 | 
			
		||||
    "membership.join-group": "加入群组",
 | 
			
		||||
    "membership.leave-group": "退出群组",
 | 
			
		||||
    "membership.reject": "拒绝",
 | 
			
		||||
    "new-group.group_name": "组名: ",
 | 
			
		||||
    "upload-group-cover": "上传组封面",
 | 
			
		||||
    "bulk-invite-instructions": "输入您要邀请加入此用户组的用户名,多个用户以逗号分隔",
 | 
			
		||||
    "new-group.group_name": "群组名: ",
 | 
			
		||||
    "upload-group-cover": "上传群组封面",
 | 
			
		||||
    "bulk-invite-instructions": "输入您要邀请加入此群组的用户名,多个用户以逗号分隔",
 | 
			
		||||
    "bulk-invite": "批量邀请",
 | 
			
		||||
    "remove_group_cover_confirm": "确定要移除封面图片吗?"
 | 
			
		||||
}
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
    "upvoted_your_post_in_dual": "<strong>%1</strong> 和 <strong>%2</strong> 在 <strong>%3</strong> 赞了您的帖子。",
 | 
			
		||||
    "upvoted_your_post_in_multiple": "<strong>%1</strong> 和 %2 个其他人在 <strong>%3</strong> 赞了您的帖子。",
 | 
			
		||||
    "moved_your_post": "您的帖子已被 <strong>%1</strong> 移动到了 <strong>%2</strong>",
 | 
			
		||||
    "moved_your_topic": "<strong>%1</strong> 移动到了 <strong>%2</strong>",
 | 
			
		||||
    "moved_your_topic": "<strong>%1</strong> 移动了 <strong>%2</strong>",
 | 
			
		||||
    "user_flagged_post_in": "<strong>%1</strong> 在 <strong>%2</strong> 标记了一个帖子",
 | 
			
		||||
    "user_flagged_post_in_dual": "<strong>%1</strong> 和 <strong>%2</strong> 在 <strong>%3</strong> 举报了一个帖子",
 | 
			
		||||
    "user_flagged_post_in_multiple": "<strong>%1</strong> 和 %2 个其他人在 <strong>%3</strong> 举报了一个帖子",
 | 
			
		||||
 
 | 
			
		||||
@@ -22,9 +22,9 @@
 | 
			
		||||
    "registration-complete": "注册完成",
 | 
			
		||||
    "login": "登录帐号",
 | 
			
		||||
    "reset": "重置帐户密码",
 | 
			
		||||
    "categories": "板块",
 | 
			
		||||
    "groups": "用户组",
 | 
			
		||||
    "group": "%1 的用户组",
 | 
			
		||||
    "categories": "版块",
 | 
			
		||||
    "groups": "群组",
 | 
			
		||||
    "group": "%1 的群组",
 | 
			
		||||
    "chats": "聊天",
 | 
			
		||||
    "chat": "与 %1 聊天",
 | 
			
		||||
    "flags": "举报",
 | 
			
		||||
@@ -38,7 +38,7 @@
 | 
			
		||||
    "account/followers": "关注 %1 的人",
 | 
			
		||||
    "account/posts": "%1 发布的帖子",
 | 
			
		||||
    "account/topics": "%1 创建的主题",
 | 
			
		||||
    "account/groups": "%1 的用户组",
 | 
			
		||||
    "account/groups": "%1 的群组",
 | 
			
		||||
    "account/bookmarks": "%1 收藏的帖子",
 | 
			
		||||
    "account/settings": "用户设置",
 | 
			
		||||
    "account/watched": "主题已被 %1 关注",
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@
 | 
			
		||||
    "number-of-views": "查看数",
 | 
			
		||||
    "topic-start-date": "主题开始日期",
 | 
			
		||||
    "username": "用户名",
 | 
			
		||||
    "category": "板块",
 | 
			
		||||
    "category": "版块",
 | 
			
		||||
    "descending": "倒序",
 | 
			
		||||
    "ascending": "顺序",
 | 
			
		||||
    "save-preferences": "保存设置",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "no_tag_topics": "此话题还没有主题帖。",
 | 
			
		||||
    "tags": "标签",
 | 
			
		||||
    "tags": "话题",
 | 
			
		||||
    "enter_tags_here": "在这里输入话题,每个话题 %1 到 %2 个字符。",
 | 
			
		||||
    "enter_tags_here_short": "输入话题...",
 | 
			
		||||
    "no_tags": "尚无话题。"
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
    "topic": "主题",
 | 
			
		||||
    "topic_id": "主题 ID",
 | 
			
		||||
    "topic_id_placeholder": "输入主题 ID",
 | 
			
		||||
    "no_topics_found": "没有找到话题!",
 | 
			
		||||
    "no_topics_found": "没有找到主题!",
 | 
			
		||||
    "no_posts_found": "没有找到帖子!",
 | 
			
		||||
    "post_is_deleted": "此回复已被删除!",
 | 
			
		||||
    "topic_is_deleted": "此主题已被删除!",
 | 
			
		||||
@@ -38,7 +38,7 @@
 | 
			
		||||
    "login_to_subscribe": "请注册或登录后,再订阅此主题。",
 | 
			
		||||
    "markAsUnreadForAll.success": "将全部主题标为未读。",
 | 
			
		||||
    "mark_unread": "标记为未读",
 | 
			
		||||
    "mark_unread.success": "未读话题",
 | 
			
		||||
    "mark_unread.success": "主题已被标记为未读。",
 | 
			
		||||
    "watch": "关注",
 | 
			
		||||
    "unwatch": "取消关注",
 | 
			
		||||
    "watch.title": "当此主题有新回复时,通知我",
 | 
			
		||||
 
 | 
			
		||||
@@ -108,8 +108,8 @@
 | 
			
		||||
    "scroll_to_my_post": "在提交回复之后显示新回复",
 | 
			
		||||
    "follow_topics_you_reply_to": "关注你回复过的主题",
 | 
			
		||||
    "follow_topics_you_create": "关注你创建的主题",
 | 
			
		||||
    "grouptitle": "用户组标题",
 | 
			
		||||
    "no-group-title": "不展示用户组称号",
 | 
			
		||||
    "grouptitle": "群组标题",
 | 
			
		||||
    "no-group-title": "不展示群组称号",
 | 
			
		||||
    "select-skin": "选择皮肤",
 | 
			
		||||
    "select-homepage": "选择首页",
 | 
			
		||||
    "homepage": "首页",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
define('forum/account/edit/password', ['forum/account/header', 'translator'], function (header, translator) {
 | 
			
		||||
define('forum/account/edit/password', ['forum/account/header', 'translator', 'zxcvbn'], function (header, translator, zxcvbn) {
 | 
			
		||||
	var AccountEditPassword = {};
 | 
			
		||||
 | 
			
		||||
	AccountEditPassword.init = function () {
 | 
			
		||||
@@ -20,6 +20,7 @@ define('forum/account/edit/password', ['forum/account/header', 'translator'], fu
 | 
			
		||||
		var passwordsmatch = false;
 | 
			
		||||
 | 
			
		||||
		function onPasswordChanged() {
 | 
			
		||||
			var passwordStrength = zxcvbn(password.val());
 | 
			
		||||
			passwordvalid = false;
 | 
			
		||||
			if (password.val().length < ajaxify.data.minimumPasswordLength) {
 | 
			
		||||
				showError(password_notify, '[[user:change_password_error_length]]');
 | 
			
		||||
@@ -29,6 +30,8 @@ define('forum/account/edit/password', ['forum/account/header', 'translator'], fu
 | 
			
		||||
				showError(password_notify, '[[user:password_same_as_username]]');
 | 
			
		||||
			} else if (password.val() === ajaxify.data.email) {
 | 
			
		||||
				showError(password_notify, '[[user:password_same_as_email]]');
 | 
			
		||||
			} else if (passwordStrength.score < ajaxify.data.minimumPasswordStrength) {
 | 
			
		||||
				showError(password_notify, '[[user:weak_password]]');
 | 
			
		||||
			} else {
 | 
			
		||||
				showSuccess(password_notify);
 | 
			
		||||
				passwordvalid = true;
 | 
			
		||||
 
 | 
			
		||||
@@ -98,7 +98,11 @@ define('forum/chats', [
 | 
			
		||||
			}
 | 
			
		||||
			loading = true;
 | 
			
		||||
			var start = parseInt($('.chat-content').children('[data-index]').first().attr('data-index'), 10) + 1;
 | 
			
		||||
			socket.emit('modules.chats.getMessages', { roomId: roomId, uid: uid, start: start }, function (err, data) {
 | 
			
		||||
			socket.emit('modules.chats.getMessages', {
 | 
			
		||||
				roomId: roomId,
 | 
			
		||||
				uid: uid,
 | 
			
		||||
				start: start,
 | 
			
		||||
			}, function (err, data) {
 | 
			
		||||
				if (err) {
 | 
			
		||||
					return app.alertError(err.message);
 | 
			
		||||
				}
 | 
			
		||||
@@ -122,7 +126,7 @@ define('forum/chats', [
 | 
			
		||||
	Chats.addEditDeleteHandler = function (element, roomId) {
 | 
			
		||||
		element.on('click', '[data-action="edit"]', function () {
 | 
			
		||||
			var messageId = $(this).parents('[data-mid]').attr('data-mid');
 | 
			
		||||
			var inputEl = components.get('chat/input');
 | 
			
		||||
			var inputEl = $('[data-roomid="' + roomId + '"] [component="chat/input"]');
 | 
			
		||||
			messages.prepEdit(inputEl, messageId, roomId);
 | 
			
		||||
		}).on('click', '[data-action="delete"]', function () {
 | 
			
		||||
			var messageId = $(this).parents('[data-mid]').attr('data-mid');
 | 
			
		||||
@@ -170,7 +174,10 @@ define('forum/chats', [
 | 
			
		||||
			if (oldName === newName) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			socket.emit('modules.chats.renameRoom', { roomId: roomId, newName: newName }, function (err) {
 | 
			
		||||
			socket.emit('modules.chats.renameRoom', {
 | 
			
		||||
				roomId: roomId,
 | 
			
		||||
				newName: newName,
 | 
			
		||||
			}, function (err) {
 | 
			
		||||
				if (err) {
 | 
			
		||||
					return app.alertError(err.message);
 | 
			
		||||
				}
 | 
			
		||||
@@ -235,10 +242,15 @@ define('forum/chats', [
 | 
			
		||||
			if (event.item === app.user.username) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			socket.emit('modules.chats.addUserToRoom', { roomId: data.roomId, username: event.item }, function (err) {
 | 
			
		||||
			socket.emit('modules.chats.addUserToRoom', {
 | 
			
		||||
				roomId: data.roomId,
 | 
			
		||||
				username: event.item,
 | 
			
		||||
			}, function (err) {
 | 
			
		||||
				if (err) {
 | 
			
		||||
					app.alertError(err.message);
 | 
			
		||||
					tagEl.tagsinput('remove', event.item, { nouser: true });
 | 
			
		||||
					tagEl.tagsinput('remove', event.item, {
 | 
			
		||||
						nouser: true,
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
@@ -262,7 +274,10 @@ define('forum/chats', [
 | 
			
		||||
			if (event.options && event.options.nouser) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			socket.emit('modules.chats.removeUserFromRoom', { roomId: data.roomId, username: event.item }, function (err) {
 | 
			
		||||
			socket.emit('modules.chats.removeUserFromRoom', {
 | 
			
		||||
				roomId: data.roomId,
 | 
			
		||||
				username: event.item,
 | 
			
		||||
			}, function (err) {
 | 
			
		||||
				if (err) {
 | 
			
		||||
					return app.alertError(err.message);
 | 
			
		||||
				}
 | 
			
		||||
@@ -319,7 +334,12 @@ define('forum/chats', [
 | 
			
		||||
				} else {
 | 
			
		||||
					var recentEl = components.get('chat/recent');
 | 
			
		||||
					templates.parse('partials/chats/recent_room', {
 | 
			
		||||
						rooms: { roomId: data.roomId, lastUser: data.message.fromUser, usernames: data.message.fromUser.username, unread: true },
 | 
			
		||||
						rooms: {
 | 
			
		||||
							roomId: data.roomId,
 | 
			
		||||
							lastUser: data.message.fromUser,
 | 
			
		||||
							usernames: data.message.fromUser.username,
 | 
			
		||||
							unread: true,
 | 
			
		||||
						},
 | 
			
		||||
					}, function (html) {
 | 
			
		||||
						translator.translate(html, function (translated) {
 | 
			
		||||
							recentEl.prepend(translated);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
define('forum/register', ['translator'], function (translator) {
 | 
			
		||||
define('forum/register', ['translator', 'zxcvbn'], function (translator, zxcvbn) {
 | 
			
		||||
	var Register = {};
 | 
			
		||||
	var validationError = false;
 | 
			
		||||
	var successIcon = '';
 | 
			
		||||
@@ -170,6 +170,7 @@ define('forum/register', ['translator'], function (translator) {
 | 
			
		||||
	function validatePassword(password, password_confirm) {
 | 
			
		||||
		var password_notify = $('#password-notify');
 | 
			
		||||
		var password_confirm_notify = $('#password-confirm-notify');
 | 
			
		||||
		var passwordStrength = zxcvbn(password);
 | 
			
		||||
 | 
			
		||||
		if (password.length < ajaxify.data.minimumPasswordLength) {
 | 
			
		||||
			showError(password_notify, '[[user:change_password_error_length]]');
 | 
			
		||||
@@ -181,6 +182,8 @@ define('forum/register', ['translator'], function (translator) {
 | 
			
		||||
			showError(password_notify, '[[user:password_same_as_username]]');
 | 
			
		||||
		} else if (password === $('#email').val()) {
 | 
			
		||||
			showError(password_notify, '[[user:password_same_as_email]]');
 | 
			
		||||
		} else if (passwordStrength.score < ajaxify.data.minimumPasswordStrength) {
 | 
			
		||||
			showError(password_notify, '[[user:weak_password]]');
 | 
			
		||||
		} else {
 | 
			
		||||
			showSuccess(password_notify, successIcon);
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,9 @@ define('chat', [
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				socket.emit('modules.chats.loadRoom', { roomId: data.roomId }, function (err, roomData) {
 | 
			
		||||
				socket.emit('modules.chats.loadRoom', {
 | 
			
		||||
					roomId: data.roomId,
 | 
			
		||||
				}, function (err, roomData) {
 | 
			
		||||
					if (err) {
 | 
			
		||||
						return app.alertError(err.message);
 | 
			
		||||
					}
 | 
			
		||||
@@ -108,7 +110,10 @@ define('chat', [
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	module.loadChatsDropdown = function (chatsListEl) {
 | 
			
		||||
		socket.emit('modules.chats.getRecentChats', { uid: app.user.uid, after: 0 }, function (err, data) {
 | 
			
		||||
		socket.emit('modules.chats.getRecentChats', {
 | 
			
		||||
			uid: app.user.uid,
 | 
			
		||||
			after: 0,
 | 
			
		||||
		}, function (err, data) {
 | 
			
		||||
			if (err) {
 | 
			
		||||
				return app.alertError(err.message);
 | 
			
		||||
			}
 | 
			
		||||
@@ -160,7 +165,7 @@ define('chat', [
 | 
			
		||||
			var dragged = false;
 | 
			
		||||
 | 
			
		||||
			chatModal.attr('id', 'chat-modal-' + data.roomId);
 | 
			
		||||
			chatModal.attr('roomId', data.roomId);
 | 
			
		||||
			chatModal.attr('data-roomid', data.roomId);
 | 
			
		||||
			chatModal.attr('intervalId', 0);
 | 
			
		||||
			chatModal.attr('UUID', uuid);
 | 
			
		||||
			chatModal.css('position', 'fixed');
 | 
			
		||||
@@ -208,7 +213,7 @@ define('chat', [
 | 
			
		||||
					components.get('chat/input').val(text);
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
				ajaxify.go('user/' + app.user.userslug + '/chats/' + chatModal.attr('roomId'));
 | 
			
		||||
				ajaxify.go('user/' + app.user.userslug + '/chats/' + chatModal.attr('data-roomid'));
 | 
			
		||||
				module.close(chatModal);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -249,14 +254,14 @@ define('chat', [
 | 
			
		||||
				messagesEl.css('height', module.calculateChatListHeight(chatModal));
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			Chats.addRenameHandler(chatModal.attr('roomId'), chatModal.find('[component="chat/room/name"]'));
 | 
			
		||||
			Chats.addRenameHandler(chatModal.attr('data-roomid'), chatModal.find('[component="chat/room/name"]'));
 | 
			
		||||
 | 
			
		||||
			Chats.addSendHandlers(chatModal.attr('roomId'), chatModal.find('#chat-message-input'), chatModal.find('#chat-message-send-btn'));
 | 
			
		||||
			Chats.addSendHandlers(chatModal.attr('data-roomid'), chatModal.find('#chat-message-input'), chatModal.find('#chat-message-send-btn'));
 | 
			
		||||
 | 
			
		||||
			Chats.createTagsInput(chatModal.find('.users-tag-input'), data);
 | 
			
		||||
			Chats.createAutoComplete(chatModal.find('[component="chat/input"]'));
 | 
			
		||||
 | 
			
		||||
			Chats.addScrollHandler(chatModal.attr('roomId'), data.uid, chatModal.find('.chat-content'));
 | 
			
		||||
			Chats.addScrollHandler(chatModal.attr('data-roomid'), data.uid, chatModal.find('.chat-content'));
 | 
			
		||||
 | 
			
		||||
			taskbar.push('chat', chatModal.attr('UUID'), {
 | 
			
		||||
				title: data.roomName || (data.users.length ? data.users[0].username : ''),
 | 
			
		||||
@@ -311,7 +316,7 @@ define('chat', [
 | 
			
		||||
		ChatsMessages.scrollToBottom(chatModal.find('.chat-content'));
 | 
			
		||||
		module.bringModalToTop(chatModal);
 | 
			
		||||
		module.focusInput(chatModal);
 | 
			
		||||
		socket.emit('modules.chats.markRead', chatModal.attr('roomId'));
 | 
			
		||||
		socket.emit('modules.chats.markRead', chatModal.attr('data-roomid'));
 | 
			
		||||
 | 
			
		||||
		var env = utils.findBootstrapEnvironment();
 | 
			
		||||
		if (env === 'xs' || env === 'sm') {
 | 
			
		||||
 
 | 
			
		||||
@@ -80,6 +80,7 @@ function renderRoute(name, req, res, next) {
 | 
			
		||||
 | 
			
		||||
		if (name === 'password') {
 | 
			
		||||
			userData.minimumPasswordLength = parseInt(meta.config.minimumPasswordLength, 10);
 | 
			
		||||
			userData.minimumPasswordStrength = parseInt(meta.config.minimumPasswordStrength || 0, 10);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		userData.title = '[[pages:account/edit/' + name + ', ' + userData.username + ']]';
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,11 @@ Controllers.home = function (req, res, next) {
 | 
			
		||||
		var hook = 'action:homepage.get:' + route;
 | 
			
		||||
 | 
			
		||||
		if (plugins.hasListeners(hook)) {
 | 
			
		||||
			return plugins.fireHook(hook, { req: req, res: res, next: next });
 | 
			
		||||
			return plugins.fireHook(hook, {
 | 
			
		||||
				req: req,
 | 
			
		||||
				res: res,
 | 
			
		||||
				next: next,
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (route === 'categories' || route === '/') {
 | 
			
		||||
@@ -85,7 +89,15 @@ Controllers.reset = function (req, res, next) {
 | 
			
		||||
				displayExpiryNotice: req.session.passwordExpired,
 | 
			
		||||
				code: req.params.code,
 | 
			
		||||
				minimumPasswordLength: parseInt(meta.config.minimumPasswordLength, 10),
 | 
			
		||||
				breadcrumbs: helpers.buildBreadcrumbs([{ text: '[[reset_password:reset_password]]', url: '/reset' }, { text: '[[reset_password:update_password]]' }]),
 | 
			
		||||
				breadcrumbs: helpers.buildBreadcrumbs([
 | 
			
		||||
					{
 | 
			
		||||
						text: '[[reset_password:reset_password]]',
 | 
			
		||||
						url: '/reset',
 | 
			
		||||
					},
 | 
			
		||||
					{
 | 
			
		||||
						text: '[[reset_password:update_password]]',
 | 
			
		||||
					},
 | 
			
		||||
				]),
 | 
			
		||||
				title: '[[pages:reset]]',
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
@@ -94,7 +106,9 @@ Controllers.reset = function (req, res, next) {
 | 
			
		||||
	} else {
 | 
			
		||||
		res.render('reset', {
 | 
			
		||||
			code: null,
 | 
			
		||||
			breadcrumbs: helpers.buildBreadcrumbs([{ text: '[[reset_password:reset_password]]' }]),
 | 
			
		||||
			breadcrumbs: helpers.buildBreadcrumbs([{
 | 
			
		||||
				text: '[[reset_password:reset_password]]',
 | 
			
		||||
			}]),
 | 
			
		||||
			title: '[[pages:reset]]',
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
@@ -124,7 +138,9 @@ Controllers.login = function (req, res, next) {
 | 
			
		||||
	data.allowLocalLogin = parseInt(meta.config.allowLocalLogin, 10) === 1 || parseInt(req.query.local, 10) === 1;
 | 
			
		||||
	data.allowRegistration = registrationType === 'normal' || registrationType === 'admin-approval' || registrationType === 'admin-approval-ip';
 | 
			
		||||
	data.allowLoginWith = '[[login:' + allowLoginWith + ']]';
 | 
			
		||||
	data.breadcrumbs = helpers.buildBreadcrumbs([{ text: '[[global:login]]' }]);
 | 
			
		||||
	data.breadcrumbs = helpers.buildBreadcrumbs([{
 | 
			
		||||
		text: '[[global:login]]',
 | 
			
		||||
	}]);
 | 
			
		||||
	data.error = req.flash('error')[0] || errorText;
 | 
			
		||||
	data.title = '[[pages:login]]';
 | 
			
		||||
 | 
			
		||||
@@ -171,7 +187,11 @@ Controllers.register = function (req, res, next) {
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		function (next) {
 | 
			
		||||
			plugins.fireHook('filter:parse.post', { postData: { content: meta.config.termsOfUse || '' } }, next);
 | 
			
		||||
			plugins.fireHook('filter:parse.post', {
 | 
			
		||||
				postData: {
 | 
			
		||||
					content: meta.config.termsOfUse || '',
 | 
			
		||||
				},
 | 
			
		||||
			}, next);
 | 
			
		||||
		},
 | 
			
		||||
	], function (err, termsOfUse) {
 | 
			
		||||
		if (err) {
 | 
			
		||||
@@ -188,8 +208,11 @@ Controllers.register = function (req, res, next) {
 | 
			
		||||
		data.minimumUsernameLength = parseInt(meta.config.minimumUsernameLength, 10);
 | 
			
		||||
		data.maximumUsernameLength = parseInt(meta.config.maximumUsernameLength, 10);
 | 
			
		||||
		data.minimumPasswordLength = parseInt(meta.config.minimumPasswordLength, 10);
 | 
			
		||||
		data.minimumPasswordStrength = parseInt(meta.config.minimumPasswordStrength || 0, 10);
 | 
			
		||||
		data.termsOfUse = termsOfUse.postData.content;
 | 
			
		||||
		data.breadcrumbs = helpers.buildBreadcrumbs([{ text: '[[register:register]]' }]);
 | 
			
		||||
		data.breadcrumbs = helpers.buildBreadcrumbs([{
 | 
			
		||||
			text: '[[register:register]]',
 | 
			
		||||
		}]);
 | 
			
		||||
		data.regFormEntry = [];
 | 
			
		||||
		data.error = req.flash('error')[0] || errorText;
 | 
			
		||||
		data.title = '[[pages:register]]';
 | 
			
		||||
@@ -333,7 +356,9 @@ Controllers.outgoing = function (req, res, next) {
 | 
			
		||||
	res.render('outgoing', {
 | 
			
		||||
		outgoing: validator.escape(String(url)),
 | 
			
		||||
		title: meta.config.title,
 | 
			
		||||
		breadcrumbs: helpers.buildBreadcrumbs([{ text: '[[notifications:outgoing_link]]' }]),
 | 
			
		||||
		breadcrumbs: helpers.buildBreadcrumbs([{
 | 
			
		||||
			text: '[[notifications:outgoing_link]]',
 | 
			
		||||
		}]),
 | 
			
		||||
	});
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -341,7 +366,9 @@ Controllers.termsOfUse = function (req, res, next) {
 | 
			
		||||
	if (!meta.config.termsOfUse) {
 | 
			
		||||
		return next();
 | 
			
		||||
	}
 | 
			
		||||
	res.render('tos', { termsOfUse: meta.config.termsOfUse });
 | 
			
		||||
	res.render('tos', {
 | 
			
		||||
		termsOfUse: meta.config.termsOfUse,
 | 
			
		||||
	});
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Controllers.ping = function (req, res) {
 | 
			
		||||
 
 | 
			
		||||
@@ -101,17 +101,22 @@ module.exports = function (Meta) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function updateConfig(config) {
 | 
			
		||||
		updateLocalConfig(config);
 | 
			
		||||
		pubsub.publish('config:update', config);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pubsub.on('config:update', function onConfigReceived(config) {
 | 
			
		||||
		if (typeof config === 'object' && Meta.config) {
 | 
			
		||||
	function updateLocalConfig(config) {
 | 
			
		||||
		for (var field in config) {
 | 
			
		||||
			if (config.hasOwnProperty(field)) {
 | 
			
		||||
				Meta.config[field] = config[field];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pubsub.on('config:update', function onConfigReceived(config) {
 | 
			
		||||
		if (typeof config === 'object' && Meta.config) {
 | 
			
		||||
			updateLocalConfig(config);
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	Meta.configs.setOnEmpty = function (values, callback) {
 | 
			
		||||
 
 | 
			
		||||
@@ -88,6 +88,7 @@ module.exports = function (Meta) {
 | 
			
		||||
				'mousetrap.js': './node_modules/mousetrap/mousetrap.min.js',
 | 
			
		||||
				'cropper.js': './node_modules/cropperjs/dist/cropper.min.js',
 | 
			
		||||
				'jqueryui.js': 'public/vendor/jquery/js/jquery-ui.js',
 | 
			
		||||
				'zxcvbn.js': './node_modules/zxcvbn/dist/zxcvbn.js',
 | 
			
		||||
				ace: './node_modules/ace-builds/src-min',
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -376,7 +377,9 @@ module.exports = function (Meta) {
 | 
			
		||||
			/**
 | 
			
		||||
			 * otherwise, just clean up --debug/--debug-brk options which are set up by default from the parent one
 | 
			
		||||
			 */
 | 
			
		||||
			forkProcessParams = { execArgv: [] };
 | 
			
		||||
			forkProcessParams = {
 | 
			
		||||
				execArgv: [],
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return forkProcessParams;
 | 
			
		||||
 
 | 
			
		||||
@@ -7,11 +7,14 @@ module.exports = function (middleware) {
 | 
			
		||||
		var headers = {
 | 
			
		||||
			'X-Powered-By': encodeURI(meta.config['powered-by'] || 'NodeBB'),
 | 
			
		||||
			'X-Frame-Options': meta.config['allow-from-uri'] ? 'ALLOW-FROM ' + encodeURI(meta.config['allow-from-uri']) : 'SAMEORIGIN',
 | 
			
		||||
			'Access-Control-Allow-Origin': encodeURI(meta.config['access-control-allow-origin'] || 'null'),
 | 
			
		||||
			'Access-Control-Allow-Methods': encodeURI(meta.config['access-control-allow-methods'] || ''),
 | 
			
		||||
			'Access-Control-Allow-Headers': encodeURI(meta.config['access-control-allow-headers'] || ''),
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		if (meta.config['access-control-allow-origin']) {
 | 
			
		||||
			headers['Access-Control-Allow-Origin'] = encodeURI(meta.config['access-control-allow-origin']);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (var key in headers) {
 | 
			
		||||
			if (headers.hasOwnProperty(key) && headers[key]) {
 | 
			
		||||
				res.setHeader(key, headers[key]);
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,7 @@ module.exports = function (Topics) {
 | 
			
		||||
			var uids = [];
 | 
			
		||||
 | 
			
		||||
			postData.forEach(function (postData) {
 | 
			
		||||
				if (postData && postData[field] && uids.indexOf(postData[field]) === -1) {
 | 
			
		||||
				if (postData && parseInt(postData[field], 10) >= 0 && uids.indexOf(postData[field]) === -1) {
 | 
			
		||||
					uids.push(postData[field]);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="form-group">
 | 
			
		||||
				<label for="access-control-allow-origin">[[admin/settings/advanced:headers.acao]]</label>
 | 
			
		||||
				<input class="form-control" id="access-control-allow-origin" type="text" placeholder="null" value="null" data-field="access-control-allow-origin" /><br />
 | 
			
		||||
				<input class="form-control" id="access-control-allow-origin" type="text" placeholder="" value="" data-field="access-control-allow-origin" /><br />
 | 
			
		||||
				<p class="help-block">
 | 
			
		||||
					[[admin/settings/advanced:headers.acao-help]]
 | 
			
		||||
				</p>
 | 
			
		||||
 
 | 
			
		||||
@@ -167,6 +167,16 @@
 | 
			
		||||
				<label>[[admin/settings/user:min-password-length]]</label>
 | 
			
		||||
				<input type="text" class="form-control" value="6" data-field="minimumPasswordLength">
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="form-group">
 | 
			
		||||
				<label>[[admin/settings/user:min-password-strength]]</label>
 | 
			
		||||
				<select class="form-control" data-field="minimumPasswordStrength">
 | 
			
		||||
					<option value="0">0 - too guessable: risky password</option>
 | 
			
		||||
					<option value="1">1 - very guessable</option>
 | 
			
		||||
					<option value="2">2 - somewhat guessable</option>
 | 
			
		||||
					<option value="3">3 - safely unguessable</option>
 | 
			
		||||
					<option value="4">4 - very unguessable</option>
 | 
			
		||||
				</select>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="form-group">
 | 
			
		||||
				<label>[[admin/settings/user:max-about-me-length]]</label>
 | 
			
		||||
				<input type="text" class="form-control" value="500" data-field="maximumAboutMeLength">
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user