Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
592b880b1c | ||
|
|
553dbd73ba | ||
|
|
6721d4151e | ||
|
|
64c0e1433b | ||
|
|
d142e7c86a | ||
|
|
5acf5acb3a | ||
|
|
830c59eb4f | ||
|
|
60ba66c0a3 | ||
|
|
470835e6f7 | ||
|
|
7b4d726c5d | ||
|
|
a49b774800 | ||
|
|
0569c27c88 | ||
|
|
4e1c26becb | ||
|
|
5aea87ade2 | ||
|
|
d93eba9f3b | ||
|
|
626def8b31 | ||
|
|
a10b5eade8 |
@@ -7,6 +7,7 @@ node_modules/
|
||||
logs/
|
||||
/public/templates
|
||||
/public/uploads
|
||||
/public/sounds
|
||||
/public/vendor
|
||||
/public/src/modules/string.js
|
||||
.idea/
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
// "comma-spacing": "off",
|
||||
// "no-trailing-spaces": "off",
|
||||
// "key-spacing": "off",
|
||||
"no-multiple-empty-lines": "off"
|
||||
// "no-multiple-empty-lines": "off",
|
||||
// "spaced-comment": "off",
|
||||
// "space-in-parens": "off",
|
||||
// "block-spacing": "off",
|
||||
|
||||
1
.github/ISSUE_TEMPLATE.md
vendored
@@ -9,7 +9,6 @@
|
||||
|
||||
- **NodeBB version:**
|
||||
- **NodeBB git hash:**
|
||||
- **NodeJS version:**
|
||||
<!-- (to find your git hash, execute `git rev-parse HEAD` from the main NodeBB directory) -->
|
||||
- **Installed NodeBB Plugins:**
|
||||
<!-- (to find installed plugins run ./nodebb plugins) -->
|
||||
|
||||
9
.github/SECURITY.md
vendored
@@ -1,9 +0,0 @@
|
||||
# Reporting a security vulnerability
|
||||
|
||||
NodeBB's security policy is based around a private bug bounty program. Users are invited to explore NodeBB for vulnerabilities, and report them to the NodeBB team so that they can be patched.
|
||||
|
||||
If you have found a security vulnerability, **do not post it onto our GitHub tracker**. Some security vulnerabilities are quite severe and discretion is recommended. Email the NodeBB Security Team at security@nodebb.org, instead.
|
||||
|
||||
# Bug Bounty Program
|
||||
|
||||
Security vulnerability reports may be eligible for a bounty based on severity and confirmation from NodeBB team members. For full details regarding our bug bounty program, including the bounty amounts, please consult the following page: https://blog.nodebb.org/bounty
|
||||
204
.github/workflows/test.yaml
vendored
@@ -1,204 +0,0 @@
|
||||
name: Lint and test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Lint and test
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
node: [10, 12, 14]
|
||||
database: [mongo-dev, mongo, redis, postgres]
|
||||
include:
|
||||
# only run coverage once
|
||||
- os: ubuntu-latest
|
||||
node: 14
|
||||
coverage: true
|
||||
# test under development once
|
||||
- database: mongo-dev
|
||||
test_env: development
|
||||
# only run eslint once
|
||||
- os: ubuntu-latest
|
||||
node: 14
|
||||
database: mongo-dev
|
||||
lint: true
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
TEST_ENV: ${{ matrix.test_env || 'production' }}
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: 'postgres:10-alpine'
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
# Set health checks to wait until postgres has started
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
# Maps port 5432 on service container to the host
|
||||
- 5432:5432
|
||||
|
||||
redis:
|
||||
image: 'redis:2.8.9'
|
||||
# Set health checks to wait until redis has started
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
# Maps port 6379 on service container to the host
|
||||
- 6379:6379
|
||||
|
||||
mongo:
|
||||
image: 'mongo:3.2'
|
||||
ports:
|
||||
# Maps port 27017 on service container to the host
|
||||
- 27017:27017
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- run: cp install/package.json package.json
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
|
||||
- name: NPM Install
|
||||
uses: bahmutov/npm-install@v1
|
||||
with:
|
||||
useLockFile: false
|
||||
|
||||
- name: Setup on MongoDB
|
||||
if: startsWith(matrix.database, 'mongo')
|
||||
env:
|
||||
SETUP: >-
|
||||
{
|
||||
"url": "http://127.0.0.1:4567",
|
||||
"secret": "abcdef",
|
||||
"admin:username": "admin",
|
||||
"admin:email": "test@example.org",
|
||||
"admin:password": "hAN3Eg8W",
|
||||
"admin:password:confirm": "hAN3Eg8W",
|
||||
|
||||
"database": "mongo",
|
||||
"mongo:host": "127.0.0.1",
|
||||
"mongo:port": 27017,
|
||||
"mongo:username": "",
|
||||
"mongo:password": "",
|
||||
"mongo:database": "nodebb"
|
||||
}
|
||||
CI: >-
|
||||
{
|
||||
"host": "127.0.0.1",
|
||||
"port": 27017,
|
||||
"database": "ci_test"
|
||||
}
|
||||
run: |
|
||||
node app --setup="${SETUP}" --ci="${CI}"
|
||||
|
||||
- name: Setup on PostgreSQL
|
||||
if: startsWith(matrix.database, 'postgres')
|
||||
env:
|
||||
SETUP: >-
|
||||
{
|
||||
"url": "http://127.0.0.1:4567",
|
||||
"secret": "abcdef",
|
||||
"admin:username": "admin",
|
||||
"admin:email": "test@example.org",
|
||||
"admin:password": "hAN3Eg8W",
|
||||
"admin:password:confirm": "hAN3Eg8W",
|
||||
|
||||
"database": "postgres",
|
||||
"postgres:host": "127.0.0.1",
|
||||
"postgres:port": 5432,
|
||||
"postgres:username": "postgres",
|
||||
"postgres:password": "postgres",
|
||||
"postgres:database": "nodebb"
|
||||
}
|
||||
CI: >-
|
||||
{
|
||||
"host": "127.0.0.1",
|
||||
"database": "ci_test",
|
||||
"port": 5432,
|
||||
"username": "postgres",
|
||||
"password": "postgres"
|
||||
}
|
||||
run: |
|
||||
node -e "const { Client } = require('pg'); const c = new Client({ host: '127.0.0.1', port: 5432, user: 'postgres', password: 'postgres' }); c.connect().then(() => c.query('CREATE DATABASE nodebb')).then(() => c.query('CREATE DATABASE ci_test')).then(() => c.end())"
|
||||
node app --setup="${SETUP}" --ci="${CI}"
|
||||
|
||||
- name: Setup on Redis
|
||||
if: startsWith(matrix.database, 'redis')
|
||||
env:
|
||||
SETUP: >-
|
||||
{
|
||||
"url": "http://127.0.0.1:4567/forum",
|
||||
"secret": "abcdef",
|
||||
"admin:username": "admin",
|
||||
"admin:email": "test@example.org",
|
||||
"admin:password": "hAN3Eg8W",
|
||||
"admin:password:confirm": "hAN3Eg8W",
|
||||
|
||||
"database": "redis",
|
||||
"redis:host": "127.0.0.1",
|
||||
"redis:port": 6379,
|
||||
"redis:password": "",
|
||||
"redis:database": 0
|
||||
}
|
||||
CI: >-
|
||||
{
|
||||
"host": "127.0.0.1",
|
||||
"database": 1,
|
||||
"port": 6379
|
||||
}
|
||||
run: |
|
||||
node app --setup="${SETUP}" --ci="${CI}"
|
||||
|
||||
- name: Run ESLint
|
||||
if: matrix.lint
|
||||
run: npm run lint
|
||||
|
||||
- name: Node tests
|
||||
run: npm test
|
||||
|
||||
- name: Extract coverage info
|
||||
run: npm run coverage
|
||||
|
||||
- name: Test coverage
|
||||
uses: coverallsapp/github-action@v1.1.2
|
||||
if: matrix.coverage
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
flag-name: ${{ matrix.os }}-node-${{ matrix.node }}-db-${{ matrix.database }}
|
||||
parallel: true
|
||||
|
||||
finish:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Coveralls Finished
|
||||
uses: coverallsapp/github-action@v1.1.2
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
parallel-finished: true
|
||||
5
.gitignore
vendored
@@ -28,6 +28,7 @@ pidfile
|
||||
# templates
|
||||
/public/templates
|
||||
|
||||
/public/sounds
|
||||
/public/uploads
|
||||
/test/uploads
|
||||
|
||||
@@ -40,7 +41,6 @@ pidfile
|
||||
/public/acp.min.js.map
|
||||
/public/installer.css
|
||||
/public/installer.min.js
|
||||
/public/bootstrap.min.css
|
||||
/public/logo.png
|
||||
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
|
||||
@@ -67,5 +67,4 @@ test/files/normalise.jpg.png
|
||||
test/files/normalise-resized.jpg
|
||||
package-lock.json
|
||||
/package.json
|
||||
*.mongodb
|
||||
link-plugins.sh
|
||||
*.mongodb
|
||||
47
.travis.yml
Normal file
@@ -0,0 +1,47 @@
|
||||
services:
|
||||
- mongodb
|
||||
- redis-server
|
||||
- postgresql
|
||||
before_install:
|
||||
- cp install/package.json package.json
|
||||
- sudo apt-get update
|
||||
- sudo apt-get --yes remove postgresql\*
|
||||
- sudo apt-get install -y postgresql-12 postgresql-client-12
|
||||
- sudo cp /etc/postgresql/{9.6,12}/main/pg_hba.conf
|
||||
- sudo service postgresql restart 12
|
||||
before_script:
|
||||
- sleep 15 # wait for mongodb to be ready
|
||||
- "mongo mydb_test --eval 'db.createUser({user:\"travis\", pwd: \"test\", roles: []});'"
|
||||
- sh -c "if [ '$DB' = 'mongodb' ]; then node app --setup=\"{\\\"url\\\":\\\"http://127.0.0.1:4567\\\",\\\"secret\\\":\\\"abcdef\\\",\\\"database\\\":\\\"mongo\\\",\\\"mongo:host\\\":\\\"127.0.0.1\\\",\\\"mongo:port\\\":27017,\\\"mongo:username\\\":\\\"\\\",\\\"mongo:password\\\":\\\"\\\",\\\"mongo:database\\\":0,\\\"admin:username\\\":\\\"admin\\\",\\\"admin:email\\\":\\\"test@example.org\\\",\\\"admin:password\\\":\\\"hAN3Eg8W\\\",\\\"admin:password:confirm\\\":\\\"hAN3Eg8W\\\"}\" --ci=\"{\\\"host\\\":\\\"127.0.0.1\\\",\\\"port\\\":27017,\\\"database\\\":\\\"travis_ci_test\\\"}\"; fi"
|
||||
- sh -c "if [ '$DB' = 'redis' ]; then node app --setup=\"{\\\"url\\\":\\\"http://127.0.0.1:4567/forum\\\",\\\"secret\\\":\\\"abcdef\\\",\\\"database\\\":\\\"redis\\\",\\\"redis:host\\\":\\\"127.0.0.1\\\",\\\"redis:port\\\":6379,\\\"redis:password\\\":\\\"\\\",\\\"redis:database\\\":0,\\\"admin:username\\\":\\\"admin\\\",\\\"admin:email\\\":\\\"test@example.org\\\",\\\"admin:password\\\":\\\"hAN3Eg8W\\\",\\\"admin:password:confirm\\\":\\\"hAN3Eg8W\\\"}\" --ci=\"{\\\"host\\\":\\\"127.0.0.1\\\",\\\"port\\\":6379,\\\"database\\\":1}\"; fi"
|
||||
- sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'create database nodebb;' -U postgres; psql -c 'create database travis_ci_test;' -U postgres; node app --setup=\"{\\\"url\\\":\\\"http://127.0.0.1:4567\\\",\\\"secret\\\":\\\"abcdef\\\",\\\"database\\\":\\\"postgres\\\",\\\"postgres:host\\\":\\\"127.0.0.1\\\",\\\"postgres:port\\\":5433,\\\"postgres:password\\\":\\\"\\\",\\\"postgres:database\\\":\\\"nodebb\\\",\\\"admin:username\\\":\\\"admin\\\",\\\"admin:email\\\":\\\"test@example.org\\\",\\\"admin:password\\\":\\\"hAN3Eg8W\\\",\\\"admin:password:confirm\\\":\\\"hAN3Eg8W\\\"}\" --ci=\"{\\\"host\\\":\\\"127.0.0.1\\\",\\\"port\\\":5433,\\\"username\\\":\\\"postgres\\\",\\\"database\\\":\\\"travis_ci_test\\\"}\"; fi"
|
||||
after_success:
|
||||
- "npm run coveralls"
|
||||
language: node_js
|
||||
sudo: false
|
||||
dist: xenial
|
||||
env:
|
||||
global:
|
||||
- PGUSER=postgres
|
||||
- PGPORT=5433
|
||||
- CXX=g++-4.8
|
||||
jobs:
|
||||
- "DB=mongodb TEST_ENV=production"
|
||||
- "DB=mongodb TEST_ENV=development"
|
||||
- "DB=redis TEST_ENV=production"
|
||||
- "DB=postgres TEST_ENV=production"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- mongodb-4.0-xenial
|
||||
packages:
|
||||
- g++-4.8
|
||||
- mongodb-org-server
|
||||
node_js:
|
||||
- "12"
|
||||
- "10"
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
250
.tx/config
@@ -251,106 +251,6 @@ trans.zh_CN = public/language/zh-CN/modules.json
|
||||
trans.zh_TW = public/language/zh-TW/modules.json
|
||||
type = KEYVALUEJSON
|
||||
|
||||
[nodebb.post-queue]
|
||||
file_filter = public/language/<lang>/post-queue.json
|
||||
source_file = public/language/en-GB/post-queue.json
|
||||
source_lang = en_GB
|
||||
trans.ar = public/language/ar/post-queue.json
|
||||
trans.bg = public/language/bg/post-queue.json
|
||||
trans.bn = public/language/bn/post-queue.json
|
||||
trans.cs = public/language/cs/post-queue.json
|
||||
trans.da = public/language/da/post-queue.json
|
||||
trans.de = public/language/de/post-queue.json
|
||||
trans.el = public/language/el/post-queue.json
|
||||
trans.en@pirate = public/language/en-x-pirate/post-queue.json
|
||||
trans.en_US = public/language/en-US/post-queue.json
|
||||
trans.es = public/language/es/post-queue.json
|
||||
trans.et = public/language/et/post-queue.json
|
||||
trans.fa_IR = public/language/fa-IR/post-queue.json
|
||||
trans.fi = public/language/fi/post-queue.json
|
||||
trans.fr = public/language/fr/post-queue.json
|
||||
trans.gl = public/language/gl/post-queue.json
|
||||
trans.he = public/language/he/post-queue.json
|
||||
trans.hr = public/language/hr/post-queue.json
|
||||
trans.hu = public/language/hu/post-queue.json
|
||||
trans.id = public/language/id/post-queue.json
|
||||
trans.it = public/language/it/post-queue.json
|
||||
trans.ja = public/language/ja/post-queue.json
|
||||
trans.ko = public/language/ko/post-queue.json
|
||||
trans.lt = public/language/lt/post-queue.json
|
||||
trans.lv = public/language/lv/post-queue.json
|
||||
trans.ms = public/language/ms/post-queue.json
|
||||
trans.nb = public/language/nb/post-queue.json
|
||||
trans.nl = public/language/nl/post-queue.json
|
||||
trans.pl = public/language/pl/post-queue.json
|
||||
trans.pt_BR = public/language/pt-BR/post-queue.json
|
||||
trans.pt_PT = public/language/pt-PT/post-queue.json
|
||||
trans.ro = public/language/ro/post-queue.json
|
||||
trans.ru = public/language/ru/post-queue.json
|
||||
trans.rw = public/language/rw/post-queue.json
|
||||
trans.sc = public/language/sc/post-queue.json
|
||||
trans.sk = public/language/sk/post-queue.json
|
||||
trans.sl = public/language/sl/post-queue.json
|
||||
trans.sr = public/language/sr/post-queue.json
|
||||
trans.sv = public/language/sv/post-queue.json
|
||||
trans.th = public/language/th/post-queue.json
|
||||
trans.tr = public/language/tr/post-queue.json
|
||||
trans.uk = public/language/uk/post-queue.json
|
||||
trans.vi = public/language/vi/post-queue.json
|
||||
trans.zh_CN = public/language/zh-CN/post-queue.json
|
||||
trans.zh_TW = public/language/zh-TW/post-queue.json
|
||||
type = KEYVALUEJSON
|
||||
|
||||
[nodebb.ip-blacklist]
|
||||
file_filter = public/language/<lang>/ip-blacklist.json
|
||||
source_file = public/language/en-GB/ip-blacklist.json
|
||||
source_lang = en_GB
|
||||
trans.ar = public/language/ar/ip-blacklist.json
|
||||
trans.bg = public/language/bg/ip-blacklist.json
|
||||
trans.bn = public/language/bn/ip-blacklist.json
|
||||
trans.cs = public/language/cs/ip-blacklist.json
|
||||
trans.da = public/language/da/ip-blacklist.json
|
||||
trans.de = public/language/de/ip-blacklist.json
|
||||
trans.el = public/language/el/ip-blacklist.json
|
||||
trans.en@pirate = public/language/en-x-pirate/ip-blacklist.json
|
||||
trans.en_US = public/language/en-US/ip-blacklist.json
|
||||
trans.es = public/language/es/ip-blacklist.json
|
||||
trans.et = public/language/et/ip-blacklist.json
|
||||
trans.fa_IR = public/language/fa-IR/ip-blacklist.json
|
||||
trans.fi = public/language/fi/ip-blacklist.json
|
||||
trans.fr = public/language/fr/ip-blacklist.json
|
||||
trans.gl = public/language/gl/ip-blacklist.json
|
||||
trans.he = public/language/he/ip-blacklist.json
|
||||
trans.hr = public/language/hr/ip-blacklist.json
|
||||
trans.hu = public/language/hu/ip-blacklist.json
|
||||
trans.id = public/language/id/ip-blacklist.json
|
||||
trans.it = public/language/it/ip-blacklist.json
|
||||
trans.ja = public/language/ja/ip-blacklist.json
|
||||
trans.ko = public/language/ko/ip-blacklist.json
|
||||
trans.lt = public/language/lt/ip-blacklist.json
|
||||
trans.lv = public/language/lv/ip-blacklist.json
|
||||
trans.ms = public/language/ms/ip-blacklist.json
|
||||
trans.nb = public/language/nb/ip-blacklist.json
|
||||
trans.nl = public/language/nl/ip-blacklist.json
|
||||
trans.pl = public/language/pl/ip-blacklist.json
|
||||
trans.pt_BR = public/language/pt-BR/ip-blacklist.json
|
||||
trans.pt_PT = public/language/pt-PT/ip-blacklist.json
|
||||
trans.ro = public/language/ro/ip-blacklist.json
|
||||
trans.ru = public/language/ru/ip-blacklist.json
|
||||
trans.rw = public/language/rw/ip-blacklist.json
|
||||
trans.sc = public/language/sc/ip-blacklist.json
|
||||
trans.sk = public/language/sk/ip-blacklist.json
|
||||
trans.sl = public/language/sl/ip-blacklist.json
|
||||
trans.sr = public/language/sr/ip-blacklist.json
|
||||
trans.sv = public/language/sv/ip-blacklist.json
|
||||
trans.th = public/language/th/ip-blacklist.json
|
||||
trans.tr = public/language/tr/ip-blacklist.json
|
||||
trans.uk = public/language/uk/ip-blacklist.json
|
||||
trans.vi = public/language/vi/ip-blacklist.json
|
||||
trans.zh_CN = public/language/zh-CN/ip-blacklist.json
|
||||
trans.zh_TW = public/language/zh-TW/ip-blacklist.json
|
||||
type = KEYVALUEJSON
|
||||
|
||||
[nodebb.register]
|
||||
file_filter = public/language/<lang>/register.json
|
||||
source_file = public/language/en-GB/register.json
|
||||
@@ -2400,6 +2300,56 @@ trans.zh_CN = public/language/zh-CN/admin/manage/groups.json
|
||||
trans.zh_TW = public/language/zh-TW/admin/manage/groups.json
|
||||
type = KEYVALUEJSON
|
||||
|
||||
[nodebb.admin-manage-ip-blacklist]
|
||||
file_filter = public/language/<lang>/admin/manage/ip-blacklist.json
|
||||
source_file = public/language/en-GB/admin/manage/ip-blacklist.json
|
||||
source_lang = en_GB
|
||||
trans.ar = public/language/ar/admin/manage/ip-blacklist.json
|
||||
trans.bg = public/language/bg/admin/manage/ip-blacklist.json
|
||||
trans.bn = public/language/bn/admin/manage/ip-blacklist.json
|
||||
trans.cs = public/language/cs/admin/manage/ip-blacklist.json
|
||||
trans.da = public/language/da/admin/manage/ip-blacklist.json
|
||||
trans.de = public/language/de/admin/manage/ip-blacklist.json
|
||||
trans.el = public/language/el/admin/manage/ip-blacklist.json
|
||||
trans.en@pirate = public/language/en-x-pirate/admin/manage/ip-blacklist.json
|
||||
trans.en_US = public/language/en-US/admin/manage/ip-blacklist.json
|
||||
trans.es = public/language/es/admin/manage/ip-blacklist.json
|
||||
trans.et = public/language/et/admin/manage/ip-blacklist.json
|
||||
trans.fa_IR = public/language/fa-IR/admin/manage/ip-blacklist.json
|
||||
trans.fi = public/language/fi/admin/manage/ip-blacklist.json
|
||||
trans.fr = public/language/fr/admin/manage/ip-blacklist.json
|
||||
trans.gl = public/language/gl/admin/manage/ip-blacklist.json
|
||||
trans.he = public/language/he/admin/manage/ip-blacklist.json
|
||||
trans.hr = public/language/hr/admin/manage/ip-blacklist.json
|
||||
trans.hu = public/language/hu/admin/manage/ip-blacklist.json
|
||||
trans.id = public/language/id/admin/manage/ip-blacklist.json
|
||||
trans.it = public/language/it/admin/manage/ip-blacklist.json
|
||||
trans.ja = public/language/ja/admin/manage/ip-blacklist.json
|
||||
trans.ko = public/language/ko/admin/manage/ip-blacklist.json
|
||||
trans.lt = public/language/lt/admin/manage/ip-blacklist.json
|
||||
trans.lv = public/language/lv/admin/manage/ip-blacklist.json
|
||||
trans.ms = public/language/ms/admin/manage/ip-blacklist.json
|
||||
trans.nb = public/language/nb/admin/manage/ip-blacklist.json
|
||||
trans.nl = public/language/nl/admin/manage/ip-blacklist.json
|
||||
trans.pl = public/language/pl/admin/manage/ip-blacklist.json
|
||||
trans.pt_BR = public/language/pt-BR/admin/manage/ip-blacklist.json
|
||||
trans.pt_PT = public/language/pt-PT/admin/manage/ip-blacklist.json
|
||||
trans.ro = public/language/ro/admin/manage/ip-blacklist.json
|
||||
trans.ru = public/language/ru/admin/manage/ip-blacklist.json
|
||||
trans.rw = public/language/rw/admin/manage/ip-blacklist.json
|
||||
trans.sc = public/language/sc/admin/manage/ip-blacklist.json
|
||||
trans.sk = public/language/sk/admin/manage/ip-blacklist.json
|
||||
trans.sl = public/language/sl/admin/manage/ip-blacklist.json
|
||||
trans.sr = public/language/sr/admin/manage/ip-blacklist.json
|
||||
trans.sv = public/language/sv/admin/manage/ip-blacklist.json
|
||||
trans.th = public/language/th/admin/manage/ip-blacklist.json
|
||||
trans.tr = public/language/tr/admin/manage/ip-blacklist.json
|
||||
trans.uk = public/language/uk/admin/manage/ip-blacklist.json
|
||||
trans.vi = public/language/vi/admin/manage/ip-blacklist.json
|
||||
trans.zh_CN = public/language/zh-CN/admin/manage/ip-blacklist.json
|
||||
trans.zh_TW = public/language/zh-TW/admin/manage/ip-blacklist.json
|
||||
type = KEYVALUEJSON
|
||||
|
||||
[nodebb.admin-manage-privileges]
|
||||
file_filter = public/language/<lang>/admin/manage/privileges.json
|
||||
source_file = public/language/en-GB/admin/manage/privileges.json
|
||||
@@ -2450,6 +2400,56 @@ trans.zh_CN = public/language/zh-CN/admin/manage/privileges.json
|
||||
trans.zh_TW = public/language/zh-TW/admin/manage/privileges.json
|
||||
type = KEYVALUEJSON
|
||||
|
||||
[nodebb.admin-manage-post-queue]
|
||||
file_filter = public/language/<lang>/admin/manage/post-queue.json
|
||||
source_file = public/language/en-GB/admin/manage/post-queue.json
|
||||
source_lang = en_GB
|
||||
trans.ar = public/language/ar/admin/manage/post-queue.json
|
||||
trans.bg = public/language/bg/admin/manage/post-queue.json
|
||||
trans.bn = public/language/bn/admin/manage/post-queue.json
|
||||
trans.cs = public/language/cs/admin/manage/post-queue.json
|
||||
trans.da = public/language/da/admin/manage/post-queue.json
|
||||
trans.de = public/language/de/admin/manage/post-queue.json
|
||||
trans.el = public/language/el/admin/manage/post-queue.json
|
||||
trans.en@pirate = public/language/en-x-pirate/admin/manage/post-queue.json
|
||||
trans.en_US = public/language/en-US/admin/manage/post-queue.json
|
||||
trans.es = public/language/es/admin/manage/post-queue.json
|
||||
trans.et = public/language/et/admin/manage/post-queue.json
|
||||
trans.fa_IR = public/language/fa-IR/admin/manage/post-queue.json
|
||||
trans.fi = public/language/fi/admin/manage/post-queue.json
|
||||
trans.fr = public/language/fr/admin/manage/post-queue.json
|
||||
trans.gl = public/language/gl/admin/manage/post-queue.json
|
||||
trans.he = public/language/he/admin/manage/post-queue.json
|
||||
trans.hr = public/language/hr/admin/manage/post-queue.json
|
||||
trans.hu = public/language/hu/admin/manage/post-queue.json
|
||||
trans.id = public/language/id/admin/manage/post-queue.json
|
||||
trans.it = public/language/it/admin/manage/post-queue.json
|
||||
trans.ja = public/language/ja/admin/manage/post-queue.json
|
||||
trans.ko = public/language/ko/admin/manage/post-queue.json
|
||||
trans.lt = public/language/lt/admin/manage/post-queue.json
|
||||
trans.lv = public/language/lv/admin/manage/post-queue.json
|
||||
trans.ms = public/language/ms/admin/manage/post-queue.json
|
||||
trans.nb = public/language/nb/admin/manage/post-queue.json
|
||||
trans.nl = public/language/nl/admin/manage/post-queue.json
|
||||
trans.pl = public/language/pl/admin/manage/post-queue.json
|
||||
trans.pt_BR = public/language/pt-BR/admin/manage/post-queue.json
|
||||
trans.pt_PT = public/language/pt-PT/admin/manage/post-queue.json
|
||||
trans.ro = public/language/ro/admin/manage/post-queue.json
|
||||
trans.ru = public/language/ru/admin/manage/post-queue.json
|
||||
trans.rw = public/language/rw/admin/manage/post-queue.json
|
||||
trans.sc = public/language/sc/admin/manage/post-queue.json
|
||||
trans.sk = public/language/sk/admin/manage/post-queue.json
|
||||
trans.sl = public/language/sl/admin/manage/post-queue.json
|
||||
trans.sr = public/language/sr/admin/manage/post-queue.json
|
||||
trans.sv = public/language/sv/admin/manage/post-queue.json
|
||||
trans.th = public/language/th/admin/manage/post-queue.json
|
||||
trans.tr = public/language/tr/admin/manage/post-queue.json
|
||||
trans.uk = public/language/uk/admin/manage/post-queue.json
|
||||
trans.vi = public/language/vi/admin/manage/post-queue.json
|
||||
trans.zh_CN = public/language/zh-CN/admin/manage/post-queue.json
|
||||
trans.zh_TW = public/language/zh-TW/admin/manage/post-queue.json
|
||||
type = KEYVALUEJSON
|
||||
|
||||
[nodebb.admin-manage-registration]
|
||||
file_filter = public/language/<lang>/admin/manage/registration.json
|
||||
source_file = public/language/en-GB/admin/manage/registration.json
|
||||
@@ -3300,56 +3300,6 @@ trans.zh_CN = public/language/zh-CN/admin/settings/notifications.json
|
||||
trans.zh_TW = public/language/zh-TW/admin/settings/notifications.json
|
||||
type = KEYVALUEJSON
|
||||
|
||||
[nodebb.admin-settings-api]
|
||||
file_filter = public/language/<lang>/admin/settings/api.json
|
||||
source_file = public/language/en-GB/admin/settings/api.json
|
||||
source_lang = en_GB
|
||||
trans.ar = public/language/ar/admin/settings/api.json
|
||||
trans.bg = public/language/bg/admin/settings/api.json
|
||||
trans.bn = public/language/bn/admin/settings/api.json
|
||||
trans.cs = public/language/cs/admin/settings/api.json
|
||||
trans.da = public/language/da/admin/settings/api.json
|
||||
trans.de = public/language/de/admin/settings/api.json
|
||||
trans.el = public/language/el/admin/settings/api.json
|
||||
trans.en@pirate = public/language/en-x-pirate/admin/settings/api.json
|
||||
trans.en_US = public/language/en-US/admin/settings/api.json
|
||||
trans.es = public/language/es/admin/settings/api.json
|
||||
trans.et = public/language/et/admin/settings/api.json
|
||||
trans.fa_IR = public/language/fa-IR/admin/settings/api.json
|
||||
trans.fi = public/language/fi/admin/settings/api.json
|
||||
trans.fr = public/language/fr/admin/settings/api.json
|
||||
trans.gl = public/language/gl/admin/settings/api.json
|
||||
trans.he = public/language/he/admin/settings/api.json
|
||||
trans.hr = public/language/hr/admin/settings/api.json
|
||||
trans.hu = public/language/hu/admin/settings/api.json
|
||||
trans.id = public/language/id/admin/settings/api.json
|
||||
trans.it = public/language/it/admin/settings/api.json
|
||||
trans.ja = public/language/ja/admin/settings/api.json
|
||||
trans.ko = public/language/ko/admin/settings/api.json
|
||||
trans.lt = public/language/lt/admin/settings/api.json
|
||||
trans.lv = public/language/lv/admin/settings/api.json
|
||||
trans.ms = public/language/ms/admin/settings/api.json
|
||||
trans.nb = public/language/nb/admin/settings/api.json
|
||||
trans.nl = public/language/nl/admin/settings/api.json
|
||||
trans.pl = public/language/pl/admin/settings/api.json
|
||||
trans.pt_BR = public/language/pt-BR/admin/settings/api.json
|
||||
trans.pt_PT = public/language/pt-PT/admin/settings/api.json
|
||||
trans.ro = public/language/ro/admin/settings/api.json
|
||||
trans.ru = public/language/ru/admin/settings/api.json
|
||||
trans.rw = public/language/rw/admin/settings/api.json
|
||||
trans.sc = public/language/sc/admin/settings/api.json
|
||||
trans.sk = public/language/sk/admin/settings/api.json
|
||||
trans.sl = public/language/sl/admin/settings/api.json
|
||||
trans.sr = public/language/sr/admin/settings/api.json
|
||||
trans.sv = public/language/sv/admin/settings/api.json
|
||||
trans.th = public/language/th/admin/settings/api.json
|
||||
trans.tr = public/language/tr/admin/settings/api.json
|
||||
trans.uk = public/language/uk/admin/settings/api.json
|
||||
trans.vi = public/language/vi/admin/settings/api.json
|
||||
trans.zh_CN = public/language/zh-CN/admin/settings/api.json
|
||||
trans.zh_TW = public/language/zh-TW/admin/settings/api.json
|
||||
type = KEYVALUEJSON
|
||||
|
||||
[nodebb.admin-settings-post]
|
||||
file_filter = public/language/<lang>/admin/settings/post.json
|
||||
source_file = public/language/en-GB/admin/settings/post.json
|
||||
|
||||
1652
CHANGELOG.md
12
Gruntfile.js
@@ -89,7 +89,6 @@ module.exports = function (grunt) {
|
||||
clientUpdated: {
|
||||
files: [
|
||||
'public/src/**/*.js',
|
||||
'public/vendor/**/*.js',
|
||||
...clientUpdated,
|
||||
'node_modules/benchpressjs/build/benchpress.js',
|
||||
],
|
||||
@@ -144,17 +143,8 @@ module.exports = function (grunt) {
|
||||
if (worker) {
|
||||
worker.kill();
|
||||
}
|
||||
|
||||
const execArgv = [];
|
||||
const inspect = process.argv.find(a => a.startsWith('--inspect'));
|
||||
|
||||
if (inspect) {
|
||||
execArgv.push(inspect);
|
||||
}
|
||||
|
||||
worker = fork('app.js', args, {
|
||||
env,
|
||||
execArgv,
|
||||
env: env,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
11
README.md
@@ -1,16 +1,15 @@
|
||||
# 
|
||||
# <img alt="NodeBB" src="http://i.imgur.com/mYxPPtB.png" />
|
||||
|
||||
[](https://travis-ci.org/NodeBB/NodeBB)
|
||||
[](https://coveralls.io/github/NodeBB/NodeBB?branch=master)
|
||||
[](https://david-dm.org/nodebb/nodebb?path=install)
|
||||
[](https://codeclimate.com/github/NodeBB/NodeBB)
|
||||
|
||||
[**NodeBB Forum Software**](https://nodebb.org) is powered by Node.js and supports either Redis, MongoDB, or a PostgreSQL database. It utilizes web sockets for instant interactions and real-time notifications. NodeBB has many modern features out of the box such as social network integration and streaming discussions, while still making sure to be compatible with older browsers.
|
||||
[**NodeBB Forum Software**](https://nodebb.org) is powered by Node.js and built on either a Redis or MongoDB database. It utilizes web sockets for instant interactions and real-time notifications. NodeBB has many modern features out of the box such as social network integration and streaming discussions, while still making sure to be compatible with older browsers.
|
||||
|
||||
Additional functionality is enabled through the use of third-party plugins.
|
||||
|
||||
* [Demo](https://try.nodebb.org)
|
||||
* [Developer Community](http://community.nodebb.org)
|
||||
* [Demo & Meta Discussion](http://community.nodebb.org)
|
||||
* [Documentation & Installation Instructions](http://docs.nodebb.org)
|
||||
* [Help translate NodeBB](https://www.transifex.com/projects/p/nodebb/)
|
||||
* [NodeBB Blog](http://blog.nodebb.org)
|
||||
@@ -49,8 +48,8 @@ Our minimalist "Persona" theme gets you going right away, no coding experience r
|
||||
|
||||
NodeBB requires the following software to be installed:
|
||||
|
||||
* A version of Node.js at least 12 or greater ([installation/upgrade instructions](https://github.com/nodesource/distributions))
|
||||
* MongoDB, version 2.6 or greater **or** Redis, version 2.8.9 or greater
|
||||
* A version of Node.js at least 8 or greater ([installation/upgrade instructions](https://github.com/nodesource/distributions))
|
||||
* Redis, version 2.8.9 or greater **or** MongoDB, version 2.6 or greater
|
||||
* nginx, version 1.3.13 or greater (**only if** intending to use nginx to proxy requests to a NodeBB)
|
||||
|
||||
## Installation
|
||||
|
||||
2
app.js
@@ -35,7 +35,7 @@ process.env.NODE_ENV = process.env.NODE_ENV || 'production';
|
||||
global.env = process.env.NODE_ENV || 'production';
|
||||
|
||||
// Alternate configuration file support
|
||||
const configFile = path.resolve(__dirname, nconf.any(['config', 'CONFIG']) || 'config.json');
|
||||
const configFile = path.resolve(__dirname, nconf.any(['config', 'CONFIG']) || 'config.json');
|
||||
|
||||
const configExists = file.existsSync(configFile) || (nconf.get('url') && nconf.get('secret') && nconf.get('database'));
|
||||
|
||||
|
||||
@@ -1,26 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
extends: ['@commitlint/config-angular'],
|
||||
rules: {
|
||||
'header-max-length': [1, 'always', 72],
|
||||
'type-enum': [
|
||||
2,
|
||||
'always',
|
||||
[
|
||||
'breaking',
|
||||
'build',
|
||||
'chore',
|
||||
'ci',
|
||||
'docs',
|
||||
'feat',
|
||||
'fix',
|
||||
'perf',
|
||||
'refactor',
|
||||
'revert',
|
||||
'style',
|
||||
'test',
|
||||
],
|
||||
],
|
||||
},
|
||||
};
|
||||
module.exports = { extends: ['@commitlint/config-angular'] };
|
||||
|
||||
@@ -70,8 +70,6 @@
|
||||
"reputation:disabled": 0,
|
||||
"downvote:disabled": 0,
|
||||
"disableSignatures": 0,
|
||||
"downvotesPerDay": 10,
|
||||
"downvotesPerUserPerDay": 3,
|
||||
"min:rep:downvote": 0,
|
||||
"min:rep:flag": 0,
|
||||
"min:rep:profile-picture": 0,
|
||||
@@ -79,14 +77,12 @@
|
||||
"min:rep:website": 0,
|
||||
"min:rep:aboutme": 0,
|
||||
"min:rep:signature": 0,
|
||||
"flags:limitPerTarget": 0,
|
||||
"notificationType_upvote": "notification",
|
||||
"notificationType_new-topic": "notification",
|
||||
"notificationType_new-reply": "notification",
|
||||
"notificationType_post-edit": "notification",
|
||||
"notificationType_follow": "notification",
|
||||
"notificationType_new-chat": "notification",
|
||||
"notificationType_new-group-chat": "notification",
|
||||
"notificationType_group-invite": "notification",
|
||||
"notificationType_group-request-membership": "notification",
|
||||
"notificationType_mention": "notification",
|
||||
@@ -111,20 +107,15 @@
|
||||
"maximumInvites": 0,
|
||||
"username:disableEdit": 0,
|
||||
"email:disableEdit": 0,
|
||||
"email:smtpTransport:pool": false,
|
||||
"email:sendmail:rateLimit": 2,
|
||||
"email:sendmail:rateDelta": 1000,
|
||||
"hideFullname": 0,
|
||||
"hideEmail": 0,
|
||||
"showFullnameAsDisplayName": 0,
|
||||
"allowGuestHandles": 0,
|
||||
"guestsIncrementTopicViews": 1,
|
||||
"allowGuestReplyNotifications": 1,
|
||||
"incrementTopicViewsInterval": 60,
|
||||
"recentMaxTopics": 200,
|
||||
"disableRecentCategoryFilter": 0,
|
||||
"maximumRelatedTopics": 0,
|
||||
"disableEmailSubscriptions": 0,
|
||||
"emailConfirmInterval": 10,
|
||||
"removeEmailNotificationImages": 0,
|
||||
"inviteExpiration": 7,
|
||||
"digestHour": 17,
|
||||
"passwordExpiryDays": 0,
|
||||
@@ -139,10 +130,5 @@
|
||||
"timeagoCutoff": 30,
|
||||
"necroThreshold": 7,
|
||||
"categoryWatchState": "watching",
|
||||
"submitPluginUsage": 1,
|
||||
"showAverageApprovalTime": true,
|
||||
"autoApproveTime": 0,
|
||||
"maxUserSessions": 10,
|
||||
"useCompression": 0,
|
||||
"updateUrlWithPostIndex": 1
|
||||
"submitPluginUsage": 1
|
||||
}
|
||||
@@ -1,51 +1,58 @@
|
||||
'use strict';
|
||||
|
||||
const prompt = require('prompt');
|
||||
const winston = require('winston');
|
||||
var async = require('async');
|
||||
var prompt = require('prompt');
|
||||
var winston = require('winston');
|
||||
|
||||
const util = require('util');
|
||||
|
||||
const promptGet = util.promisify((schema, callback) => prompt.get(schema, callback));
|
||||
|
||||
const questions = {
|
||||
var questions = {
|
||||
redis: require('../src/database/redis').questions,
|
||||
mongo: require('../src/database/mongo').questions,
|
||||
postgres: require('../src/database/postgres').questions,
|
||||
};
|
||||
|
||||
module.exports = async function (config) {
|
||||
winston.info('\nNow configuring ' + config.database + ' database:');
|
||||
const databaseConfig = await getDatabaseConfig(config);
|
||||
return saveDatabaseConfig(config, databaseConfig);
|
||||
module.exports = function (config, callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
winston.info('\nNow configuring ' + config.database + ' database:');
|
||||
getDatabaseConfig(config, next);
|
||||
},
|
||||
function (databaseConfig, next) {
|
||||
saveDatabaseConfig(config, databaseConfig, next);
|
||||
},
|
||||
], callback);
|
||||
};
|
||||
|
||||
async function getDatabaseConfig(config) {
|
||||
function getDatabaseConfig(config, callback) {
|
||||
if (!config) {
|
||||
throw new Error('invalid config, aborted');
|
||||
return callback(new Error('aborted'));
|
||||
}
|
||||
|
||||
if (config.database === 'redis') {
|
||||
if (config['redis:host'] && config['redis:port']) {
|
||||
return config;
|
||||
callback(null, config);
|
||||
} else {
|
||||
prompt.get(questions.redis, callback);
|
||||
}
|
||||
return await promptGet(questions.redis);
|
||||
} else if (config.database === 'mongo') {
|
||||
if ((config['mongo:host'] && config['mongo:port']) || config['mongo:uri']) {
|
||||
return config;
|
||||
callback(null, config);
|
||||
} else {
|
||||
prompt.get(questions.mongo, callback);
|
||||
}
|
||||
return await promptGet(questions.mongo);
|
||||
} else if (config.database === 'postgres') {
|
||||
if (config['postgres:host'] && config['postgres:port']) {
|
||||
return config;
|
||||
callback(null, config);
|
||||
} else {
|
||||
prompt.get(questions.postgres, callback);
|
||||
}
|
||||
return await promptGet(questions.postgres);
|
||||
} else {
|
||||
return callback(new Error('unknown database : ' + config.database));
|
||||
}
|
||||
throw new Error('unknown database : ' + config.database);
|
||||
}
|
||||
|
||||
function saveDatabaseConfig(config, databaseConfig) {
|
||||
function saveDatabaseConfig(config, databaseConfig, callback) {
|
||||
if (!databaseConfig) {
|
||||
throw new Error('invalid config, aborted');
|
||||
return callback(new Error('aborted'));
|
||||
}
|
||||
|
||||
// Translate redis properties into redis object
|
||||
@@ -79,13 +86,13 @@ function saveDatabaseConfig(config, databaseConfig) {
|
||||
ssl: databaseConfig['postgres:ssl'],
|
||||
};
|
||||
} else {
|
||||
throw new Error('unknown database : ' + config.database);
|
||||
return callback(new Error('unknown database : ' + config.database));
|
||||
}
|
||||
|
||||
const allQuestions = questions.redis.concat(questions.mongo).concat(questions.postgres);
|
||||
var allQuestions = questions.redis.concat(questions.mongo).concat(questions.postgres);
|
||||
for (var x = 0; x < allQuestions.length; x += 1) {
|
||||
delete config[allQuestions[x].name];
|
||||
}
|
||||
|
||||
return config;
|
||||
callback(null, config);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "nodebb",
|
||||
"license": "GPL-3.0",
|
||||
"description": "NodeBB Forum",
|
||||
"version": "1.15.3",
|
||||
"version": "1.14.0-8",
|
||||
"homepage": "http://www.nodebb.org",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -11,21 +11,15 @@
|
||||
"main": "app.js",
|
||||
"scripts": {
|
||||
"start": "node loader.js",
|
||||
"lint": "npx eslint --cache ./nodebb .",
|
||||
"test": "npx nyc --reporter=html --reporter=text-summary npx mocha",
|
||||
"coverage": "nyc report --reporter=text-lcov > ./coverage/lcov.info",
|
||||
"lint": "eslint --cache ./nodebb .",
|
||||
"pretest": "npm run lint",
|
||||
"test": "nyc --reporter=html --reporter=text-summary mocha",
|
||||
"coveralls": "nyc report --reporter=text-lcov | coveralls && rm -r coverage"
|
||||
},
|
||||
"nyc": {
|
||||
"exclude": [
|
||||
"src/upgrades/*",
|
||||
"test/*"
|
||||
]
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "npx lint-staged",
|
||||
"commit-msg": "npx commitlint -E HUSKY_GIT_PARAMS"
|
||||
"pre-commit": "lint-staged",
|
||||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
@@ -35,146 +29,131 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@adactive/bootstrap-tagsinput": "^0.8.2",
|
||||
"ace-builds": "^1.4.9",
|
||||
"archiver": "^5.0.0",
|
||||
"archiver": "^4.0.0",
|
||||
"async": "^3.2.0",
|
||||
"autoprefixer": "10.0.2",
|
||||
"autoprefixer": "^9.7.6",
|
||||
"bcryptjs": "2.4.3",
|
||||
"benchpressjs": "2.2.2",
|
||||
"benchpressjs": "^2.0.2",
|
||||
"body-parser": "^1.19.0",
|
||||
"bootbox": "4.4.0",
|
||||
"bootstrap": "^3.4.1",
|
||||
"bootswatch": "git://github.com/thomaspark/bootswatch.git#c41a8f066feb8950c6f9c6bcf5a3c37d1085404e",
|
||||
"chart.js": "^2.9.3",
|
||||
"cli-graph": "^3.2.2",
|
||||
"clipboard": "^2.0.6",
|
||||
"colors": "^1.4.0",
|
||||
"commander": "^6.0.0",
|
||||
"compare-versions": "3.6.0",
|
||||
"commander": "^5.0.0",
|
||||
"compression": "^1.7.4",
|
||||
"connect-ensure-login": "^0.1.1",
|
||||
"connect-flash": "^0.1.1",
|
||||
"connect-mongo": "3.2.0",
|
||||
"connect-multiparty": "^2.2.0",
|
||||
"connect-pg-simple": "^6.1.0",
|
||||
"connect-redis": "5.0.0",
|
||||
"connect-redis": "4.0.4",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"cron": "^1.8.2",
|
||||
"cropperjs": "^1.5.6",
|
||||
"csurf": "^1.11.0",
|
||||
"daemon": "^1.1.0",
|
||||
"diff": "^5.0.0",
|
||||
"diff": "^4.0.2",
|
||||
"express": "^4.17.1",
|
||||
"express-session": "^1.17.0",
|
||||
"express-useragent": "^1.0.13",
|
||||
"graceful-fs": "^4.2.3",
|
||||
"helmet": "^4.0.0",
|
||||
"helmet": "^3.22.0",
|
||||
"html-to-text": "^5.1.1",
|
||||
"ipaddr.js": "^2.0.0",
|
||||
"ipaddr.js": "^1.9.1",
|
||||
"jquery": "3.5.1",
|
||||
"jquery-deserialize": "2.0.0-rc1",
|
||||
"jquery-form": "4.3.0",
|
||||
"jquery-serializeobject": "1.0.0",
|
||||
"jquery-ui": "1.12.1",
|
||||
"jsesc": "3.0.2",
|
||||
"json2csv": "5.0.5",
|
||||
"jsesc": "3.0.1",
|
||||
"json2csv": "5.0.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"less": "^3.11.1",
|
||||
"lodash": "^4.17.15",
|
||||
"logrotate-stream": "^0.2.6",
|
||||
"lru-cache": "6.0.0",
|
||||
"lru-cache": "5.1.1",
|
||||
"material-design-lite": "^1.3.0",
|
||||
"mime": "^2.4.4",
|
||||
"mkdirp": "^1.0.4",
|
||||
"mongodb": "3.6.3",
|
||||
"mongodb": "3.5.9",
|
||||
"morgan": "^1.10.0",
|
||||
"mousetrap": "^1.6.5",
|
||||
"@nodebb/bootswatch": "3.4.2",
|
||||
"@nodebb/mubsub": "1.7.1",
|
||||
"@nodebb/socket.io-adapter-mongo": "3.1.1",
|
||||
"nconf": "^0.11.0",
|
||||
"nodebb-plugin-composer-default": "6.4.7",
|
||||
"nodebb-plugin-dbsearch": "4.1.2",
|
||||
"@nodebb/mubsub": "^1.6.0",
|
||||
"@nodebb/socket.io-adapter-mongo": "3.0.0",
|
||||
"nconf": "^0.10.0",
|
||||
"nodebb-plugin-composer-default": "6.3.43",
|
||||
"nodebb-plugin-dbsearch": "4.0.7",
|
||||
"nodebb-plugin-emoji": "^3.3.0",
|
||||
"nodebb-plugin-emoji-android": "2.0.0",
|
||||
"nodebb-plugin-markdown": "8.12.1",
|
||||
"nodebb-plugin-mentions": "2.13.5",
|
||||
"nodebb-plugin-markdown": "8.11.2",
|
||||
"nodebb-plugin-mentions": "2.7.4",
|
||||
"nodebb-plugin-soundpack-default": "1.0.0",
|
||||
"nodebb-plugin-spam-be-gone": "0.7.6",
|
||||
"nodebb-rewards-essentials": "0.1.4",
|
||||
"nodebb-theme-lavender": "5.0.14",
|
||||
"nodebb-theme-persona": "10.2.88",
|
||||
"nodebb-theme-slick": "1.3.3",
|
||||
"nodebb-theme-vanilla": "11.3.4",
|
||||
"nodebb-widget-essentials": "4.1.2",
|
||||
"nodebb-plugin-spam-be-gone": "0.7.1",
|
||||
"nodebb-rewards-essentials": "0.1.3",
|
||||
"nodebb-theme-lavender": "5.0.11",
|
||||
"nodebb-theme-persona": "10.1.53",
|
||||
"nodebb-theme-slick": "1.2.29",
|
||||
"nodebb-theme-vanilla": "11.1.28",
|
||||
"nodebb-widget-essentials": "4.1.0",
|
||||
"nodemailer": "^6.4.6",
|
||||
"nprogress": "0.2.0",
|
||||
"passport": "^0.4.1",
|
||||
"passport-http-bearer": "^1.0.1",
|
||||
"passport-local": "1.0.0",
|
||||
"pg": "^8.0.2",
|
||||
"pg-cursor": "^2.1.9",
|
||||
"postcss": "8.1.10",
|
||||
"postcss": "7.0.32",
|
||||
"postcss-clean": "1.1.0",
|
||||
"promise-polyfill": "^8.1.3",
|
||||
"prompt": "^1.0.0",
|
||||
"redis": "3.0.2",
|
||||
"request": "2.88.2",
|
||||
"request-promise-native": "^1.0.8",
|
||||
"requirejs": "2.3.6",
|
||||
"rimraf": "3.0.2",
|
||||
"rss": "^1.2.2",
|
||||
"sanitize-html": "^2.0.0",
|
||||
"sanitize-html": "^1.23.0",
|
||||
"semver": "^7.2.1",
|
||||
"serve-favicon": "^2.5.0",
|
||||
"sharp": "0.26.3",
|
||||
"sharp": "0.25.4",
|
||||
"sitemap": "^6.1.0",
|
||||
"slideout": "1.0.1",
|
||||
"socket.io": "2.3.0",
|
||||
"socket.io-adapter-cluster": "^1.0.1",
|
||||
"socket.io-adapter-postgres": "^1.2.1",
|
||||
"socket.io-client": "2.3.1",
|
||||
"socket.io-redis": "5.4.0",
|
||||
"socket.io-client": "2.3.0",
|
||||
"socket.io-redis": "5.3.0",
|
||||
"socketio-wildcard": "2.0.0",
|
||||
"sortablejs": "1.10.2",
|
||||
"spdx-license-list": "^6.1.0",
|
||||
"spider-detector": "2.0.0",
|
||||
"textcomplete": "^0.17.1",
|
||||
"textcomplete.contenteditable": "^0.1.1",
|
||||
"timeago": "^1.6.7",
|
||||
"tinycon": "0.6.8",
|
||||
"toobusy-js": "^0.5.1",
|
||||
"uglify-es": "^3.3.9",
|
||||
"validator": "13.1.17",
|
||||
"visibilityjs": "2.0.2",
|
||||
"winston": "3.3.3",
|
||||
"validator": "13.1.1",
|
||||
"winston": "3.2.1",
|
||||
"xml": "^1.0.1",
|
||||
"xregexp": "^4.3.0",
|
||||
"zxcvbn": "^4.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@apidevtools/swagger-parser": "10.0.2",
|
||||
"@commitlint/cli": "11.0.0",
|
||||
"@commitlint/config-angular": "11.0.0",
|
||||
"@apidevtools/swagger-parser": "9.0.1",
|
||||
"@commitlint/cli": "8.3.5",
|
||||
"@commitlint/config-angular": "8.3.4",
|
||||
"coveralls": "3.1.0",
|
||||
"eslint": "7.14.0",
|
||||
"eslint-config-airbnb-base": "14.2.1",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"grunt": "1.3.0",
|
||||
"eslint": "7.2.0",
|
||||
"eslint-config-airbnb-base": "14.1.0",
|
||||
"eslint-plugin-import": "2.21.1",
|
||||
"grunt": "1.1.0",
|
||||
"grunt-contrib-watch": "1.1.0",
|
||||
"husky": "4.3.0",
|
||||
"jsdom": "16.4.0",
|
||||
"lint-staged": "10.5.2",
|
||||
"mocha": "8.2.1",
|
||||
"husky": "4.2.5",
|
||||
"jsdom": "16.2.2",
|
||||
"lint-staged": "10.2.10",
|
||||
"mocha": "8.0.1",
|
||||
"mocha-lcov-reporter": "1.3.0",
|
||||
"nyc": "15.1.0",
|
||||
"smtp-server": "3.8.0"
|
||||
"nyc": "15.0.1",
|
||||
"smtp-server": "3.6.0"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/NodeBB/NodeBB/issues"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
"node": ">=8"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
|
||||
287
install/web.js
@@ -1,27 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
const winston = require('winston');
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const childProcess = require('child_process');
|
||||
const less = require('less');
|
||||
const util = require('util');
|
||||
const lessRenderAsync = util.promisify(
|
||||
(style, opts, cb) => less.render(String(style), opts, cb)
|
||||
);
|
||||
const uglify = require('uglify-es');
|
||||
const nconf = require('nconf');
|
||||
var winston = require('winston');
|
||||
var express = require('express');
|
||||
var bodyParser = require('body-parser');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var childProcess = require('child_process');
|
||||
var less = require('less');
|
||||
var async = require('async');
|
||||
var uglify = require('uglify-es');
|
||||
var nconf = require('nconf');
|
||||
var Benchpress = require('benchpressjs');
|
||||
|
||||
const Benchpress = require('benchpressjs');
|
||||
const mkdirp = require('mkdirp');
|
||||
const { paths } = require('../src/constants');
|
||||
var app = express();
|
||||
var server;
|
||||
|
||||
const app = express();
|
||||
let server;
|
||||
|
||||
const formats = [
|
||||
var formats = [
|
||||
winston.format.colorize(),
|
||||
];
|
||||
|
||||
@@ -48,52 +42,50 @@ winston.configure({
|
||||
],
|
||||
});
|
||||
|
||||
const web = module.exports;
|
||||
var web = module.exports;
|
||||
|
||||
const scripts = [
|
||||
var scripts = [
|
||||
'node_modules/jquery/dist/jquery.js',
|
||||
'node_modules/xregexp/xregexp-all.js',
|
||||
'public/src/modules/slugify.js',
|
||||
'public/vendor/xregexp/xregexp.js',
|
||||
'public/vendor/xregexp/unicode/unicode-base.js',
|
||||
'public/src/utils.js',
|
||||
'public/src/installer/install.js',
|
||||
'node_modules/zxcvbn/dist/zxcvbn.js',
|
||||
];
|
||||
|
||||
let installing = false;
|
||||
let success = false;
|
||||
let error = false;
|
||||
let launchUrl;
|
||||
var installing = false;
|
||||
var success = false;
|
||||
var error = false;
|
||||
var launchUrl;
|
||||
|
||||
const viewsDir = path.join(paths.baseDir, 'build/public/templates');
|
||||
|
||||
web.install = async function (port) {
|
||||
web.install = function (port) {
|
||||
port = port || 4567;
|
||||
winston.info('Launching web installer on port ' + port);
|
||||
|
||||
app.use(express.static('public', {}));
|
||||
app.engine('tpl', function (filepath, options, callback) {
|
||||
filepath = filepath.replace(/\.tpl$/, '.js');
|
||||
|
||||
Benchpress.__express(filepath, options, callback);
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
fs.readFile(filepath, 'utf-8', next);
|
||||
},
|
||||
function (buffer, next) {
|
||||
Benchpress.compileParse(buffer.toString(), options, next);
|
||||
},
|
||||
], callback);
|
||||
});
|
||||
app.set('view engine', 'tpl');
|
||||
app.set('views', viewsDir);
|
||||
app.set('views', path.join(__dirname, '../src/views'));
|
||||
app.use(bodyParser.urlencoded({
|
||||
extended: true,
|
||||
}));
|
||||
try {
|
||||
await Promise.all([
|
||||
compileTemplate(),
|
||||
compileLess(),
|
||||
compileJS(),
|
||||
copyCSS(),
|
||||
loadDefaults(),
|
||||
]);
|
||||
|
||||
async.parallel([compileLess, compileJS, copyCSS, loadDefaults], function (err) {
|
||||
if (err) {
|
||||
winston.error(err);
|
||||
}
|
||||
setupRoutes();
|
||||
launchExpress(port);
|
||||
} catch (err) {
|
||||
winston.error(err.stack);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -188,116 +180,117 @@ function install(req, res) {
|
||||
});
|
||||
}
|
||||
|
||||
async function launch(req, res) {
|
||||
try {
|
||||
res.json({});
|
||||
server.close();
|
||||
req.setTimeout(0);
|
||||
var child;
|
||||
function launch(req, res) {
|
||||
res.json({});
|
||||
server.close();
|
||||
req.setTimeout(0);
|
||||
var child;
|
||||
|
||||
if (!nconf.get('launchCmd')) {
|
||||
child = childProcess.spawn('node', ['loader.js'], {
|
||||
detached: true,
|
||||
stdio: ['ignore', 'ignore', 'ignore'],
|
||||
});
|
||||
if (!nconf.get('launchCmd')) {
|
||||
child = childProcess.spawn('node', ['loader.js'], {
|
||||
detached: true,
|
||||
stdio: ['ignore', 'ignore', 'ignore'],
|
||||
});
|
||||
|
||||
console.log('\nStarting NodeBB');
|
||||
console.log(' "./nodebb stop" to stop the NodeBB server');
|
||||
console.log(' "./nodebb log" to view server output');
|
||||
console.log(' "./nodebb restart" to restart NodeBB');
|
||||
} else {
|
||||
// Use launchCmd instead, if specified
|
||||
child = childProcess.exec(nconf.get('launchCmd'), {
|
||||
detached: true,
|
||||
stdio: ['ignore', 'ignore', 'ignore'],
|
||||
});
|
||||
console.log('\nStarting NodeBB');
|
||||
console.log(' "./nodebb stop" to stop the NodeBB server');
|
||||
console.log(' "./nodebb log" to view server output');
|
||||
console.log(' "./nodebb restart" to restart NodeBB');
|
||||
} else {
|
||||
// Use launchCmd instead, if specified
|
||||
child = childProcess.exec(nconf.get('launchCmd'), {
|
||||
detached: true,
|
||||
stdio: ['ignore', 'ignore', 'ignore'],
|
||||
});
|
||||
}
|
||||
|
||||
var filesToDelete = [
|
||||
'installer.css',
|
||||
'installer.min.js',
|
||||
'bootstrap.min.css',
|
||||
];
|
||||
|
||||
async.each(filesToDelete, function (filename, next) {
|
||||
fs.unlink(path.join(__dirname, '../public', filename), next);
|
||||
}, function (err) {
|
||||
if (err) {
|
||||
winston.warn('Unable to remove installer files');
|
||||
}
|
||||
|
||||
const filesToDelete = [
|
||||
'installer.css',
|
||||
'installer.min.js',
|
||||
'bootstrap.min.css',
|
||||
];
|
||||
await Promise.all(
|
||||
filesToDelete.map(
|
||||
filename => fs.promises.unlink(path.join(__dirname, '../public', filename))
|
||||
)
|
||||
);
|
||||
child.unref();
|
||||
process.exit(0);
|
||||
} catch (err) {
|
||||
winston.error(err.stack);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
// this is necessary because otherwise the compiled templates won't be available on a clean install
|
||||
async function compileTemplate() {
|
||||
const sourceFile = path.join(__dirname, '../src/views/install/index.tpl');
|
||||
const destTpl = path.join(viewsDir, 'install/index.tpl');
|
||||
const destJs = path.join(viewsDir, 'install/index.js');
|
||||
|
||||
const source = await fs.promises.readFile(sourceFile, 'utf8');
|
||||
|
||||
const [compiled] = await Promise.all([
|
||||
Benchpress.precompile(source, { filename: 'install/index.tpl' }),
|
||||
mkdirp(path.dirname(destJs)),
|
||||
]);
|
||||
|
||||
await Promise.all([
|
||||
fs.promises.writeFile(destJs, compiled),
|
||||
fs.promises.writeFile(destTpl, source),
|
||||
]);
|
||||
}
|
||||
|
||||
async function compileLess() {
|
||||
try {
|
||||
const installSrc = path.join(__dirname, '../public/less/install.less');
|
||||
const style = await fs.promises.readFile(installSrc);
|
||||
const css = await lessRenderAsync(style, { filename: path.resolve(installSrc) });
|
||||
await fs.promises.writeFile(path.join(__dirname, '../public/installer.css'), css.css);
|
||||
} catch (err) {
|
||||
winston.error('Unable to compile LESS: \n' + err.stack);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async function compileJS() {
|
||||
let code = '';
|
||||
|
||||
for (const srcPath of scripts) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const buffer = await fs.promises.readFile(path.join(__dirname, '..', srcPath));
|
||||
code += buffer.toString();
|
||||
}
|
||||
const minified = uglify.minify(code, {
|
||||
compress: false,
|
||||
});
|
||||
if (!minified.code) {
|
||||
throw new Error('[[error:failed-to-minify]]');
|
||||
}
|
||||
await fs.promises.writeFile(path.join(__dirname, '../public/installer.min.js'), minified.code);
|
||||
}
|
||||
|
||||
async function copyCSS() {
|
||||
const src = await fs.promises.readFile(
|
||||
path.join(__dirname, '../node_modules/bootstrap/dist/css/bootstrap.min.css'), 'utf8'
|
||||
);
|
||||
await fs.promises.writeFile(path.join(__dirname, '../public/bootstrap.min.css'), src);
|
||||
}
|
||||
|
||||
async function loadDefaults() {
|
||||
const setupDefaultsPath = path.join(__dirname, '../setup.json');
|
||||
try {
|
||||
await fs.promises.access(setupDefaultsPath, fs.constants.F_OK | fs.constants.R_OK);
|
||||
} catch (err) {
|
||||
// setup.json not found or inaccessible, proceed with no defaults
|
||||
if (err.code !== 'ENOENT') {
|
||||
throw err;
|
||||
function compileLess(callback) {
|
||||
fs.readFile(path.join(__dirname, '../public/less/install.less'), function (err, style) {
|
||||
if (err) {
|
||||
return winston.error('Unable to read LESS install file: ', err);
|
||||
}
|
||||
}
|
||||
winston.info('[installer] Found setup.json, populating default values');
|
||||
nconf.file({
|
||||
file: setupDefaultsPath,
|
||||
|
||||
less.render(style.toString(), function (err, css) {
|
||||
if (err) {
|
||||
return winston.error('Unable to compile LESS: ', err);
|
||||
}
|
||||
|
||||
fs.writeFile(path.join(__dirname, '../public/installer.css'), css.css, callback);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function compileJS(callback) {
|
||||
var code = '';
|
||||
async.eachSeries(scripts, function (srcPath, next) {
|
||||
fs.readFile(path.join(__dirname, '..', srcPath), function (err, buffer) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
code += buffer.toString();
|
||||
next();
|
||||
});
|
||||
}, function (err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
try {
|
||||
var minified = uglify.minify(code, {
|
||||
compress: false,
|
||||
});
|
||||
if (!minified.code) {
|
||||
return callback(new Error('[[error:failed-to-minify]]'));
|
||||
}
|
||||
fs.writeFile(path.join(__dirname, '../public/installer.min.js'), minified.code, callback);
|
||||
} catch (e) {
|
||||
callback(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function copyCSS(next) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
fs.readFile(path.join(__dirname, '../node_modules/bootstrap/dist/css/bootstrap.min.css'), 'utf8', next);
|
||||
},
|
||||
function (src, next) {
|
||||
fs.writeFile(path.join(__dirname, '../public/bootstrap.min.css'), src, next);
|
||||
},
|
||||
], next);
|
||||
}
|
||||
|
||||
function loadDefaults(next) {
|
||||
var setupDefaultsPath = path.join(__dirname, '../setup.json');
|
||||
fs.access(setupDefaultsPath, fs.constants.F_OK | fs.constants.R_OK, function (err) {
|
||||
if (err) {
|
||||
// setup.json not found or inaccessible, proceed with no defaults
|
||||
return setImmediate(next);
|
||||
}
|
||||
|
||||
winston.info('[installer] Found setup.json, populating default values');
|
||||
nconf.file({
|
||||
file: setupDefaultsPath,
|
||||
});
|
||||
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
var nconf = require('nconf');
|
||||
var nconf = require('nconf');
|
||||
var fs = require('fs');
|
||||
var url = require('url');
|
||||
var path = require('path');
|
||||
@@ -18,7 +18,7 @@ nconf.argv().env().file({
|
||||
file: pathToConfig,
|
||||
});
|
||||
|
||||
var pidFilePath = path.join(__dirname, 'pidfile');
|
||||
var pidFilePath = path.join(__dirname, 'pidfile');
|
||||
|
||||
var outputLogFilePath = path.join(__dirname, nconf.get('logFile') || 'logs/output.log');
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"socket": true,
|
||||
"ajaxify": true,
|
||||
"config": true,
|
||||
"RELATIVE_PATH": true,
|
||||
"utils": true,
|
||||
"overrides": true,
|
||||
"componentHandler": true,
|
||||
@@ -17,24 +18,24 @@
|
||||
"jquery": true,
|
||||
"amd": true,
|
||||
"browser": true,
|
||||
"es6": true
|
||||
"es6": false
|
||||
},
|
||||
"rules": {
|
||||
"block-scoped-var": "off",
|
||||
"no-dupe-class-members": "off",
|
||||
"no-var": "off",
|
||||
"object-shorthand": "off",
|
||||
"prefer-arrow-callback": "off",
|
||||
"prefer-spread": "off",
|
||||
"prefer-object-spread": "off",
|
||||
"prefer-reflect": "off",
|
||||
"prefer-template": "off"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"ecmaVersion": 5,
|
||||
"ecmaFeatures": {
|
||||
"arrowFunctions": false,
|
||||
"classes": false,
|
||||
"defaultParams": false,
|
||||
"destructuring": false,
|
||||
"experimentalObjectRestSpread": false,
|
||||
"blockBindings": false,
|
||||
"forOf": false,
|
||||
@@ -48,7 +49,9 @@
|
||||
"objectLiteralShorthandProperties": false,
|
||||
"impliedStrict": false,
|
||||
"restParams": false,
|
||||
"superInFunctions": false
|
||||
"spread": false,
|
||||
"superInFunctions": false,
|
||||
"templateStrings": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
"socket": true,
|
||||
"ajaxify": true,
|
||||
"config": true,
|
||||
"RELATIVE_PATH": true,
|
||||
"utils": true,
|
||||
"overrides": true,
|
||||
"componentHandler": true,
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 5.9 KiB |
@@ -1,16 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="321" height="75" viewBox="0 0 321 75">
|
||||
<defs>
|
||||
<radialGradient id="nodebb-a" cx="65.599%" cy="0%" r="169.036%" fx="65.599%" fy="0%" gradientTransform="matrix(-.5183 .5916 -.38031 -.80624 .996 -.388)">
|
||||
<stop offset="0%" stop-color="#2A6CBE"/>
|
||||
<stop offset="38.688%" stop-color="#2062BC"/>
|
||||
<stop offset="49.182%" stop-color="#1F5FBC"/>
|
||||
<stop offset="66.583%" stop-color="#1C5ABD"/>
|
||||
<stop offset="85.354%" stop-color="#1956BC"/>
|
||||
<stop offset="100%" stop-color="#1851BE"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g fill="none" transform="translate(1 1)">
|
||||
<path fill="#000306" stroke="#000306" stroke-width=".275" d="M195.810017,20 C210.691849,20 221.256813,28.7272272 221.484017,45.845679 C221.490864,46.3615394 221.461776,47.1194739 221.396754,48.1194827 C221.328352,49.1714504 220.455158,49.9897119 219.400969,49.9897119 L179.110557,49.9897119 C179.110557,56.6336943 182.723978,64.2757202 196.378026,64.2757202 C204.088827,64.2757202 211.625406,61.928339 218.987763,57.2335766 L219.553745,56.8677968 C220.246813,56.4139645 221.17656,56.6079034 221.630392,57.3009716 C221.757029,57.4943637 221.837254,57.7144077 221.864806,57.943925 C222.131013,60.1615294 222.004084,61.5832211 221.484017,62.2089999 C220.452051,63.4507301 210.901843,73 196.378026,73 C180.58738,73 169,61.8765432 169,46.3909465 C169,31.3415638 180.019372,20 195.810017,20 Z M162.92733,0 C164.031899,-4.2495073e-16 164.92733,0.8954305 164.92733,2 L164.928075,44.1266361 C164.975781,44.8118124 165,45.5058194 165,46.2079256 C165,61.5334332 153.460581,73 138,73 C122.427386,73 111,61.5334332 111,46.2079256 C111,30.882418 122.427386,19.4158511 138,19.4158511 C144.981278,19.4158511 151.163029,21.7538895 155.843826,25.7295173 L155.843557,4.54188628 C155.843557,2.03347175 157.877029,4.60788274e-16 160.385444,0 L162.92733,0 Z M81,20 C96.4605809,20 108,31.3415638 108,46.5 C108,61.6584362 96.4605809,73 81,73 C65.4273859,73 54,61.6584362 54,46.5 C54,31.3415638 65.4273859,20 81,20 Z M27.324263,20 C41.6099773,20 50,29.1649049 50,41.7801268 L50,67.5 C50,69.4329966 48.4329966,71 46.5,71 L42.2494331,71 C41.1448636,71 40.2494331,70.1045695 40.2494331,69 L40.2494331,42.5348837 C40.2494331,34.3403805 35.8276644,28.6257928 26.3038549,28.6257928 C10.0816327,28.6257928 9.75718821,35.7795705 9.75069932,44.6831843 L9.75056689,71 L2,71 C0.8954305,71 1.3527075e-16,70.1045695 0,69 L0,35.2932975 L0,35.2932975 C0,24.3935718 19.1609977,20 27.324263,20 Z M81,28.7242798 C70.8049793,28.7242798 63.6348548,36.4670782 63.6348548,46.5 C63.6348548,56.3148148 70.8049793,64.2757202 81,64.2757202 C91.1950207,64.2757202 98.3651452,56.3148148 98.3651452,46.5 C98.3651452,36.4670782 91.1950207,28.7242798 81,28.7242798 Z M138,28.2362872 C127.804979,28.2362872 120.634855,36.0644241 120.634855,46.2079256 C120.634855,56.1309161 127.804979,64.179564 138,64.179564 C148.195021,64.179564 155.365145,56.1309161 155.365145,46.2079256 C155.365145,36.0644241 148.195021,28.2362872 138,28.2362872 Z M195.810017,28.7242798 C186.721876,28.7242798 180.473779,33.9588477 179.224159,41.8106996 L211.259858,41.8106996 C210.010238,33.9588477 204.443752,28.7242798 195.810017,28.7242798 Z"/>
|
||||
<path fill="url(#nodebb-a)" d="M277,19 L276.999615,57.7303365 C276.99251,64.180962 276.88949,68.6242617 276.88949,73 L276.88949,73 L255.649055,73 C242.962262,73 236,67.06 236,57.7257143 C236,51.4771429 239.558488,46.9257143 245.1283,45.0742857 C240.564149,43.1457143 237.779243,38.8257143 237.779243,33.5028571 C237.779243,24.8628571 244.664149,19 256.732074,19 L256.732074,19 L277,19 Z M299.267926,19 C311.335851,19 318.220757,24.8628571 318.220757,33.5028571 C318.220757,38.8257143 315.435851,43.1457143 310.8717,45.0742857 C316.441512,46.9257143 320,51.4771429 320,57.7257143 C320,67.06 313.037738,73 300.350945,73 L279.11051,73 L279.11051,73 C279.11051,68.6242617 279.00749,64.180962 279.000385,57.7303365 L279,19 L299.267926,19 Z M266.092452,49.8571429 L256.499999,49.8571429 C250.156602,49.8571429 246.984904,52.2485714 246.984904,56.9542857 C246.984904,61.8914286 249.924527,64.36 255.726414,64.36 L255.726414,64.36 L260.754716,64.36 C264.777358,64.36 266.092452,62.4314286 266.092452,56.5685714 L266.092452,56.5685714 L266.092452,49.8571429 Z M299.500001,49.8571429 L289.907548,49.8571429 L289.907548,56.5685714 C289.907548,62.4314286 291.222642,64.36 295.245284,64.36 L300.273586,64.36 C306.075473,64.36 309.015096,61.8914286 309.015096,56.9542857 C309.015096,52.2485714 305.843398,49.8571429 299.500001,49.8571429 Z M266.169811,27.64 L257.350942,27.64 C251.703772,27.64 248.764149,30.1857143 248.764149,34.5057143 C248.764149,38.8257143 251.703772,41.3714286 257.350942,41.3714286 L257.350942,41.3714286 L266.169811,41.3714286 L266.169811,27.64 Z M298.649058,27.64 L289.830189,27.64 L289.830189,41.3714286 L298.649058,41.3714286 C304.296228,41.3714286 307.235851,38.8257143 307.235851,34.5057143 C307.235851,30.1857143 304.296228,27.64 298.649058,27.64 Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 86 B |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
3
public/js-enabled.css
Normal file
@@ -0,0 +1,3 @@
|
||||
/*
|
||||
The following stylesheet is only included on pages that can execute javascript
|
||||
*/
|
||||
@@ -1,6 +1,11 @@
|
||||
{
|
||||
"post-cache": "التخزين المؤقت للمشاركات",
|
||||
"posts-in-cache": "المشاركات المخزنة مؤقتاً",
|
||||
"average-post-size": "متوسط حجم المشاركة",
|
||||
"length-to-max": "الطول / أقصى حد",
|
||||
"percent-full": "1% كاملة",
|
||||
"post-cache-size": "حجم التخزين المؤقت للمشاركات",
|
||||
"items-in-cache": "العناصر في التخزين المؤقت"
|
||||
"items-in-cache": "العناصر في التخزين المؤقت",
|
||||
"control-panel": "لوحة التحكم",
|
||||
"update-settings": "تحديث إعدادات التخزين المؤقت"
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"trending": "Trending",
|
||||
"installed": "منصبة",
|
||||
"active": "مفعلة",
|
||||
"inactive": "معطلة",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"available": "Available Widgets",
|
||||
"explanation": "Select a widget from the dropdown menu and then drag and drop it into a template's widget area on the left.",
|
||||
"none-installed": "No widgets found! Activate the widget essentials plugin in the <a href=\"%1\">plugins</a> control panel.",
|
||||
"none-installed": "No widgets found! Activate the essential widgets plugin in the <a href=\"%1\">plugins</a> control panel.",
|
||||
"clone-from": "Clone widgets from",
|
||||
"containers.available": "Available Containers",
|
||||
"containers.explanation": "Drag and drop on top of any active widget",
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"num-recent-replies": "# of Recent Replies",
|
||||
"ext-link": "External Link",
|
||||
"is-section": "Treat this category as a section",
|
||||
"tag-whitelist": "Tag Whitelist",
|
||||
"upload-image": "Upload Image",
|
||||
"delete-image": "Remove",
|
||||
"category-image": "Category Image",
|
||||
@@ -27,8 +26,6 @@
|
||||
"enable": "Enable",
|
||||
"disable": "Disable",
|
||||
"edit": "Edit",
|
||||
"analytics": "Analytics",
|
||||
"view-category": "View category",
|
||||
|
||||
"select-category": "Select Category",
|
||||
"set-parent-category": "Set Parent Category",
|
||||
@@ -66,6 +63,7 @@
|
||||
"alert.create-success": "Category successfully created!",
|
||||
"alert.none-active": "You have no active categories.",
|
||||
"alert.create": "Create a Category",
|
||||
"alert.confirm-moderate": "<strong>Are you sure you wish to grant the moderation privilege to this user group?</strong> This group is public, and any users can join at will.",
|
||||
"alert.confirm-purge": "<p class=\"lead\">Do you really want to purge this category \"%1\"?</p><h5><strong class=\"text-danger\">Warning!</strong> All topics and posts in this category will be purged!</h5> <p class=\"help-block\">Purging a category will remove all topics and posts, and delete the category from the database. If you want to remove a category <em>temporarily</em>, you'll want to \"disable\" the category instead.</p>",
|
||||
"alert.purge-success": "Category purged!",
|
||||
"alert.copy-success": "Settings Copied!",
|
||||
@@ -77,9 +75,7 @@
|
||||
"alert.user-search": "Search for a user here...",
|
||||
"alert.find-group": "Find a Group",
|
||||
"alert.group-search": "Search for a group here...",
|
||||
"alert.not-enough-whitelisted-tags": "Whitelisted tags are less than minimum tags, you need to create more whitelisted tags!",
|
||||
"collapse-all": "Collapse All",
|
||||
"expand-all": "Expand All",
|
||||
"disable-on-create": "Disable on create",
|
||||
"no-matches": "No matches"
|
||||
"disable-on-create": "Disable on create"
|
||||
}
|
||||
@@ -8,9 +8,6 @@
|
||||
"hidden": "Hidden",
|
||||
"private": "Private",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"privileges": "Privileges",
|
||||
"download-csv": "CSV",
|
||||
"search-placeholder": "Search",
|
||||
"create": "Create Group",
|
||||
"description-placeholder": "A short description about your group",
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
{
|
||||
"global": "Global",
|
||||
"global.no-users": "No user-specific global privileges.",
|
||||
"admin": "Admin",
|
||||
"group-privileges": "Group Privileges",
|
||||
"user-privileges": "User Privileges",
|
||||
"edit-privileges": "Edit Privileges",
|
||||
"chat": "Chat",
|
||||
"upload-images": "Upload Images",
|
||||
"upload-files": "Upload Files",
|
||||
"signature": "Signature",
|
||||
"ban": "Ban",
|
||||
"invite": "Invite",
|
||||
"search-content": "Search Content",
|
||||
"search-users": "Search Users",
|
||||
"search-tags": "Search Tags",
|
||||
@@ -34,21 +33,10 @@
|
||||
"delete-topics": "Delete Topics",
|
||||
"purge": "Purge",
|
||||
"moderate": "Moderate",
|
||||
|
||||
"admin-dashboard": "Dashboard",
|
||||
"admin-categories": "Categories",
|
||||
"admin-privileges": "Privileges",
|
||||
"admin-users": "Users",
|
||||
"admin-settings": "Settings",
|
||||
|
||||
"alert.confirm-moderate": "<strong>Are you sure you wish to grant the moderation privilege to this user group?</strong> This group is public, and any users can join at will.",
|
||||
"alert.confirm-save": "Please confirm your intention to save these privileges",
|
||||
"alert.saved": "Privilege changes saved and applied",
|
||||
"alert.confirm-discard": "Are you sure you wish to discard your privilege changes?",
|
||||
"alert.discarded": "Privilege changes discarded",
|
||||
"alert.confirm-copyToAll": "Are you sure you wish to apply this privilege set to <strong>all categories</strong>?",
|
||||
"alert.confirm-copyToAllGroup": "Are you sure you wish to apply this group's privilege set to <strong>all categories</strong>?",
|
||||
"alert.confirm-copyToChildren": "Are you sure you wish to apply this privilege set to <strong>all descendant (child) categories</strong>?",
|
||||
"alert.confirm-copyToChildrenGroup": "Are you sure you wish to apply this group's privilege set to <strong>all descendant (child) categories</strong>?",
|
||||
"alert.no-undo": "<em>This action cannot be undone.</em>",
|
||||
"alert.admin-warning": "Administrators implicitly get all privileges"
|
||||
"admin-settings": "Settings"
|
||||
}
|
||||
@@ -20,10 +20,16 @@
|
||||
"add-group": "Add Group",
|
||||
"invite": "Invite",
|
||||
"new": "New User",
|
||||
"filter-by": "Filter by",
|
||||
|
||||
"pills.latest": "Latest Users",
|
||||
"pills.unvalidated": "Not Validated",
|
||||
"pills.validated": "Validated",
|
||||
"pills.no-posts": "No Posts",
|
||||
"pills.top-posters": "Top Posters",
|
||||
"pills.top-rep": "Most Reputation",
|
||||
"pills.inactive": "Inactive",
|
||||
"pills.flagged": "Most Flagged",
|
||||
"pills.banned": "Banned",
|
||||
"pills.search": "User Search",
|
||||
|
||||
"50-per-page": "50 per page",
|
||||
"100-per-page": "100 per page",
|
||||
@@ -102,5 +108,5 @@
|
||||
|
||||
"alerts.prompt-email": "Emails: ",
|
||||
"alerts.email-sent-to": "An invitation email has been sent to %1",
|
||||
"alerts.x-users-found": "%1 user(s) found, (%2 seconds)"
|
||||
"alerts.x-users-found": "%1 user(s) found! Search took %2 ms."
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
"settings/general": "عامة",
|
||||
"settings/homepage": "Home Page",
|
||||
"settings/navigation": "Navigation",
|
||||
"settings/reputation": "Reputation & Flags",
|
||||
"settings/reputation": "السمعة",
|
||||
"settings/email": "البريد الإلكتروني",
|
||||
"settings/user": "Users",
|
||||
"settings/group": "Groups",
|
||||
@@ -31,7 +31,6 @@
|
||||
"settings/pagination": "ترقيم الصفحات",
|
||||
"settings/tags": "الكلمات المفتاحية",
|
||||
"settings/notifications": "التنبيهات",
|
||||
"settings/api": "API Access",
|
||||
"settings/sounds": "Sounds",
|
||||
"settings/social": "Social",
|
||||
"settings/cookies": "Cookies",
|
||||
@@ -71,7 +70,7 @@
|
||||
"logout": "Log out",
|
||||
"view-forum": "View Forum",
|
||||
|
||||
"search.placeholder": "Press "/" to search for settings",
|
||||
"search.placeholder": "Search for settings",
|
||||
"search.no-results": "No results...",
|
||||
"search.search-forum": "Search the forum for <strong></strong>",
|
||||
"search.keep-typing": "Type more to see results...",
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
"maintenance-mode.message": "Maintenance Message",
|
||||
"headers": "Headers",
|
||||
"headers.allow-from": "Set ALLOW-FROM to Place NodeBB in an iFrame",
|
||||
"headers.csp-frame-ancestors": "Set Content-Security-Policy frame-ancestors header to Place NodeBB in an iFrame",
|
||||
"headers.csp-frame-ancestors-help": "'none', 'self'(default) or list of URIs to allow.",
|
||||
"headers.powered-by": "Customise the \"Powered By\" header sent by NodeBB",
|
||||
"headers.acao": "Access-Control-Allow-Origin",
|
||||
"headers.acao-regex": "Access-Control-Allow-Origin Regular Expression",
|
||||
@@ -32,12 +30,5 @@
|
||||
"sockets.settings": "WebSocket Settings",
|
||||
"sockets.max-attempts": "Max Reconnection Attempts",
|
||||
"sockets.default-placeholder": "Default: %1",
|
||||
"sockets.delay": "Reconnection Delay",
|
||||
|
||||
"analytics.settings": "Analytics Settings",
|
||||
"analytics.max-cache": "Analytics Cache Max Value",
|
||||
"analytics.max-cache-help": "On high-traffic installs, the cache could be exhausted continuously if there are more concurrent active users than the Max Cache value. (Restart required)",
|
||||
"compression.settings": "Compression Settings",
|
||||
"compression.enable": "Enable Compression",
|
||||
"compression.help": "This setting enables gzip compression. For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level. You can enable it here for testing purposes."
|
||||
"sockets.delay": "Reconnection Delay"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"tokens": "Tokens",
|
||||
"settings": "Settings",
|
||||
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
|
||||
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
|
||||
"docs": "Click here to access the full API specification",
|
||||
|
||||
"require-https": "Require API usage via HTTPS only",
|
||||
"require-https-caveat": "<strong>Note</strong>: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
|
||||
|
||||
"uid": "User ID",
|
||||
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is <code>0</code>, it will be considered a <em>master</em> token, which can assume the identity of other users based on the <code>_uid</code> parameter",
|
||||
"description": "Description",
|
||||
"no-description": "No description specified.",
|
||||
"token-on-save": "Token will be generated once form is saved"
|
||||
}
|
||||
@@ -6,7 +6,6 @@
|
||||
"max-length": "Maximum length of chat messages",
|
||||
"max-room-size": "Maximum number of users in chat rooms",
|
||||
"delay": "Time between chat messages in milliseconds",
|
||||
"notification-delay": "Notification delay for chat messages. (0 for no delay)",
|
||||
"restrictions.seconds-edit-after": "Number of seconds a chat message will remain editable. (0 disabled)",
|
||||
"restrictions.seconds-delete-after": "Number of seconds a chat message will remain deletable. (0 disabled)"
|
||||
}
|
||||
@@ -8,6 +8,5 @@
|
||||
"consent.blank-localised-default": "Leave blank to use NodeBB localised defaults",
|
||||
"settings": "Settings",
|
||||
"cookie-domain": "Session cookie domain",
|
||||
"max-user-sessions": "Max active sessions per user",
|
||||
"blank-default": "Leave blank for default"
|
||||
}
|
||||
@@ -4,6 +4,9 @@
|
||||
"address-help": "The following email address refers to the email that the recipient will see in the \"From\" and \"Reply To\" fields.",
|
||||
"from": "From Name",
|
||||
"from-help": "The from name to display in the email.",
|
||||
"sendmail-rate-limit": "Send <em>X</em> emails...",
|
||||
"sendmail-rate-delta": "... every <em>X</em> milliseconds",
|
||||
"sendmail-rate-help": "Instructs the NodeBB mailer to limit the number of messages sent at once in order to not overwhelm email receiving services. These options do not apply if SMTP Transport is enabled (below).",
|
||||
|
||||
"smtp-transport": "SMTP Transport",
|
||||
"smtp-transport.enabled": "Use an external email server to send emails",
|
||||
@@ -22,8 +25,6 @@
|
||||
"smtp-transport.username": "Username",
|
||||
"smtp-transport.username-help": "<b>For the Gmail service,</b> enter the full email address here, especially if you are using a Google Apps managed domain.",
|
||||
"smtp-transport.password": "Password",
|
||||
"smtp-transport.pool": "Enable pooled connections",
|
||||
"smtp-transport.pool-help": "Pooling connections prevents NodeBB from creating a new connection for every email. This option only applies if SMTP Transport is enabled.",
|
||||
|
||||
"template": "Edit Email Template",
|
||||
"template.select": "Select Email Template",
|
||||
@@ -35,7 +36,5 @@
|
||||
"subscriptions": "Email Digests",
|
||||
"subscriptions.disable": "Disable email digests",
|
||||
"subscriptions.hour": "Digest Hour",
|
||||
"subscriptions.hour-help": "Please enter a number representing the hour to send scheduled email digests (e.g. <code>0</code> for midnight, <code>17</code> for 5:00pm). Keep in mind that this is the hour according to the server itself, and may not exactly match your system clock.<br /> The approximate server time is: <span id=\"serverTime\"></span><br /> The next daily digest is scheduled to be sent <span id=\"nextDigestTime\"></span>",
|
||||
"notifications.settings": "Email notification settings",
|
||||
"notifications.remove-images": "Remove images from email notifications"
|
||||
"subscriptions.hour-help": "Please enter a number representing the hour to send scheduled email digests (e.g. <code>0</code> for midnight, <code>17</code> for 5:00pm). Keep in mind that this is the hour according to the server itself, and may not exactly match your system clock.<br /> The approximate server time is: <span id=\"serverTime\"></span><br /> The next daily digest is scheduled to be sent <span id=\"nextDigestTime\"></span>"
|
||||
}
|
||||
@@ -27,12 +27,9 @@
|
||||
"log.alt-text-placeholder": "Alternative text for accessibility",
|
||||
"favicon": "صورة المفضله",
|
||||
"favicon.upload": "رفع",
|
||||
"pwa": "Progressive Web App",
|
||||
"touch-icon": "Touch Icon",
|
||||
"touch-icon": "Homescreen/Touch Icon",
|
||||
"touch-icon.upload": "رفع",
|
||||
"touch-icon.help": "Recommended size and format: 512x512, PNG format only. If no touch icon is specified, NodeBB will fall back to using the favicon.",
|
||||
"maskable-icon": "Maskable (Homescreen) Icon",
|
||||
"maskable-icon.help": "Recommended size and format: 512x512, PNG format only. If no maskable icon is specified, NodeBB will fall back to the Touch Icon.",
|
||||
"touch-icon.help": "Recommended size and format: 192x192, PNG format only. If no touch icon is specified, NodeBB will fall back to using the favicon.",
|
||||
"outgoing-links": "Outgoing Links",
|
||||
"outgoing-links.warning-page": "Use Outgoing Links Warning Page",
|
||||
"search-default-sort-by": "الترتيب الافتراضي للبحث",
|
||||
@@ -41,4 +38,4 @@
|
||||
"theme-color": "لون الثيم",
|
||||
"background-color": "لون الخلفية",
|
||||
"background-color-help": "Color used for splash screen background when website is installed as a PWA"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"settings": "Settings",
|
||||
"handles": "Guest Handles",
|
||||
"handles.enabled": "Allow guest handles",
|
||||
"handles.enabled-help": "This option exposes a new field that allows guests to pick a name to associate with each post they make. If disabled, they will simply be called \"Guest\"",
|
||||
"topic-views.enabled": "Allow guests to increase topic view counts",
|
||||
"reply-notifications.enabled": "Allow guests to generate reply notifications"
|
||||
"handles.enabled-help": "This option exposes a new field that allows guests to pick a name to associate with each post they make. If disabled, they will simply be called \"Guest\""
|
||||
}
|
||||
@@ -2,5 +2,6 @@
|
||||
"notifications": "Notifications",
|
||||
"welcome-notification": "Welcome Notification",
|
||||
"welcome-notification-link": "Welcome Notification Link",
|
||||
"welcome-notification-uid": "Welcome Notification User (UID)"
|
||||
"welcome-notification-uid": "Welcome Notification User (UID)",
|
||||
"notification-alert-timeout": "Notification Alert Timeout"
|
||||
}
|
||||
@@ -34,8 +34,6 @@
|
||||
"timestamp.cut-off-help": "Dates & times will be shown in a relative manner (e.g. \"3 hours ago\" / \"5 days ago\"), and localised into various\n\t\t\t\t\tlanguages. After a certain point, this text can be switched to display the localised date itself\n\t\t\t\t\t(e.g. 5 Nov 2016 15:30).<br /><em>(Default: <code>30</code>, or one month). Set to 0 to always display dates, leave blank to always display relative times.</em>",
|
||||
"timestamp.necro-threshold": "Necro Threshold (in days)",
|
||||
"timestamp.necro-threshold-help": "A message will be shown between posts if the time between them is longer than the necro threshold. (Default: <code>7</code>, or one week). Set to 0 to disable.</em>",
|
||||
"timestamp.topic-views-interval": "Increment topic views interval (in minutes)",
|
||||
"timestamp.topic-views-interval-help": "Topic views will only increment once every X minutes as defined by this setting.",
|
||||
"teaser": "Teaser Post",
|
||||
"teaser.last-post": "Last – Show the latest post, including the original post, if no replies",
|
||||
"teaser.last-reply": "Last – Show the latest reply, or a \"No replies\" placeholder if no replies",
|
||||
@@ -44,7 +42,6 @@
|
||||
"unread.cutoff": "Unread cutoff days",
|
||||
"unread.min-track-last": "Minimum posts in topic before tracking last read",
|
||||
"recent": "Recent Settings",
|
||||
"recent.max-topics": "Maximum topics on /recent",
|
||||
"recent.categoryFilter.disable": "Disable filtering of topics in ignored categories on the /recent page",
|
||||
"signature": "Signature Settings",
|
||||
"signature.disable": "Disable signatures",
|
||||
|
||||
@@ -5,16 +5,10 @@
|
||||
"votes-are-public": "All Votes Are Public",
|
||||
"thresholds": "Activity Thresholds",
|
||||
"min-rep-downvote": "Minimum reputation to downvote posts",
|
||||
"downvotes-per-day": "Downvotes per day (set to 0 for unlimited downvotes)",
|
||||
"downvotes-per-user-per-day": "Downvotes per user per day (set to 0 for unlimited downvotes)",
|
||||
"min-rep-flag": "Minimum reputation to flag posts",
|
||||
"min-rep-website": "Minimum reputation to add \"Website\" to user profile",
|
||||
"min-rep-aboutme": "Minimum reputation to add \"About me\" to user profile",
|
||||
"min-rep-signature": "Minimum reputation to add \"Signature\" to user profile",
|
||||
"min-rep-profile-picture": "Minimum reputation to add \"Profile Picture\" to user profile",
|
||||
"min-rep-cover-picture": "Minimum reputation to add \"Cover Picture\" to user profile",
|
||||
|
||||
"flags": "Flag Settings",
|
||||
"flags.limit-per-target": "Maximum number of times something can be flagged",
|
||||
"flags.limit-per-target-placeholder": "Default: 0"
|
||||
"min-rep-cover-picture": "Minimum reputation to add \"Cover Picture\" to user profile"
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
"allow-account-deletion": "السماح بحذف الحساب",
|
||||
"hide-fullname": "إخفاء الإسم الكامل عن المستخدمين",
|
||||
"hide-email": "إخفاء البريد الإلكتروني عن المستخدمين",
|
||||
"show-fullname-as-displayname": "Show user's full name as their display name if available",
|
||||
"themes": "القوالب",
|
||||
"disable-user-skins": "منع المستخدمين من اختيار سمة مخصص",
|
||||
"account-protection": "حماية الحساب",
|
||||
@@ -44,9 +43,6 @@
|
||||
"registration-type.disabled": "لا يوجد تسجيل",
|
||||
"registration-type.help": "Normal - Users can register from the /register page.<br/>\nInvite Only - Users can invite others from the <a href=\"%1/users\" target=\"_blank\">users</a> page.<br/>\nAdmin Invite Only - Only administrators can invite others from <a href=\"%1/users\" target=\"_blank\">users</a> and <a href=\"%1/admin/manage/users\">admin/manage/users</a> pages.<br/>\nNo registration - No user registration.<br/>",
|
||||
"registration-approval-type.help": "Normal - Users are registered immediately.<br/>\nAdmin Approval - User registrations are placed in an <a href=\"%1/admin/manage/registration\">approval queue</a> for administrators.<br/>\nAdmin Approval for IPs - Normal for new users, Admin Approval for IP addresses that already have an account.<br/>",
|
||||
"registration-queue-auto-approve-time": "Automatic Approval Time",
|
||||
"registration-queue-auto-approve-time-help": "Hours before user is approved automatically. 0 to disable.",
|
||||
"registration-queue-show-average-time": "Show users average time it takes to approve a new user",
|
||||
"registration.max-invites": "الحد الأقصى للدعوات لكل عضو",
|
||||
"max-invites": "الحد الأقصى للدعوات لكل عضو",
|
||||
"max-invites-help": "0 لعدم تحديد قيود، الإدارة تحصل على دعوات لامحدودة <br> هذا الخيار يعمل فقط عند تحديد خيار \"بالدعوات فقط\"",
|
||||
@@ -66,7 +62,6 @@
|
||||
"restrict-chat": "السماح فقط برسائل الدردشة من المستخدمين الذين أتبعهم",
|
||||
"outgoing-new-tab": "Open outgoing links in new tab",
|
||||
"topic-search": "Enable In-Topic Searching",
|
||||
"update-url-with-post-index": "Update url with post index while browsing topics",
|
||||
"digest-freq": "Subscribe to Digest",
|
||||
"digest-freq.off": "Off",
|
||||
"digest-freq.daily": "Daily",
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
"reset.notify.text1": "نحيطك علما أن كلمة مرورك قد تم تغييرها في %1",
|
||||
"reset.notify.text2": "إن لم يكن لديك علم بهذا، المرجو إشعار مدبر النظام بأسرع مايمكن.",
|
||||
"digest.latest_topics": "آخر المستجدات من %1",
|
||||
"digest.top-topics": "Top topics from %1",
|
||||
"digest.popular-topics": "Popular topics from %1",
|
||||
"digest.cta": "انقر هنا لمشاهدة %1",
|
||||
"digest.unsub.info": "تم إرسال هذا الإشعار بآخر المستجدات وفقا لخيارات تسجيلكم.",
|
||||
"digest.day": "يوم",
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
"invalid-tid": "موضوع غير متواجد",
|
||||
"invalid-pid": "رد غير موجود",
|
||||
"invalid-uid": "مستخدم غير موجود",
|
||||
"invalid-date": "A valid date must be provided",
|
||||
"invalid-username": "اسم المستخدم غير مقبول",
|
||||
"invalid-email": "البريد الاكتروني غير مقبول",
|
||||
"invalid-fullname": "Invalid Fullname",
|
||||
@@ -27,7 +26,6 @@
|
||||
"invalid-pagination-value": "رقم الصفحة غير صحيح ، يجب أن يكون بين %1 و %2 .",
|
||||
"username-taken": "اسم المستخدم مأخوذ",
|
||||
"email-taken": "البريد الالكتروني مأخوذ",
|
||||
"email-invited": "Email was already invited",
|
||||
"email-not-confirmed": "You are unable to post until your email is confirmed, please click here to confirm your email.",
|
||||
"email-not-confirmed-chat": "لا يمكنك الدردشة حتى تقوم بتأكيد بريدك الإلكتروني، الرجاء إضغط هنا لتأكيد بريدك اﻹلكتروني.",
|
||||
"email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email. You won't be able to post or chat until your email is confirmed.",
|
||||
@@ -140,13 +138,8 @@
|
||||
"not-enough-reputation-min-rep-signature": "You do not have enough reputation to add a signature",
|
||||
"not-enough-reputation-min-rep-profile-picture": "You do not have enough reputation to add a profile picture",
|
||||
"not-enough-reputation-min-rep-cover-picture": "You do not have enough reputation to add a cover picture",
|
||||
"post-already-flagged": "You have already flagged this post",
|
||||
"user-already-flagged": "You have already flagged this user",
|
||||
"post-flagged-too-many-times": "This post has been flagged by others already",
|
||||
"user-flagged-too-many-times": "This user has been flagged by others already",
|
||||
"already-flagged": "لقد بلغت عن هذه المشاركة من قبل.",
|
||||
"self-vote": "You cannot vote on your own post",
|
||||
"too-many-downvotes-today": "You can only downvote %1 times a day",
|
||||
"too-many-downvotes-today-user": "You can only downvote a user %1 times a day",
|
||||
"reload-failed": "المنتدى واجه مشكلة أثناء إعادة التحميل: \"%1\". سيواصل المنتدى خدمة العملاء السابقين لكن يجب عليك إلغاء أي تغيير قمت به قبل إعادة التحميل.",
|
||||
"registration-error": "حدث خطأ أثناء التسجيل",
|
||||
"parse-error": "حدث خطأ ما أثناء تحليل استجابة الخادم",
|
||||
@@ -164,12 +157,10 @@
|
||||
"invalid-session-text": "يبدو أن فترة التسجيل لم تعد قائمة او هي غير مطابقة مع الخادم. يرجى إعادة تحميل هذه الصفحة.",
|
||||
"no-topics-selected": "No topics selected!",
|
||||
"cant-move-to-same-topic": "Can't move post to same topic!",
|
||||
"cant-move-topic-to-same-category": "Can't move topic to the same category!",
|
||||
"cannot-block-self": "You cannot block yourself!",
|
||||
"cannot-block-privileged": "You cannot block administrators or global moderators",
|
||||
"cannot-block-guest": "Guest are not able to block other users",
|
||||
"already-blocked": "This user is already blocked",
|
||||
"already-unblocked": "This user is already unblocked",
|
||||
"no-connection": "There seems to be a problem with your internet connection",
|
||||
"plugin-not-whitelisted": "Unable to install plugin – only plugins whitelisted by the NodeBB Package Manager can be installed via the ACP"
|
||||
"no-connection": "There seems to be a problem with your internet connection"
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"state": "الحالة",
|
||||
"reports": "Reports",
|
||||
"first-reported": "First Reported",
|
||||
"reporter": "المُبلغ",
|
||||
"reported-at": "وقت التبليغ",
|
||||
"description": "الوصف",
|
||||
"no-flags": "Hooray! No flags found.",
|
||||
"assignee": "المحال إليه",
|
||||
"update": "تحديث",
|
||||
@@ -25,7 +26,6 @@
|
||||
"filter-quick-mine": "Assigned to me",
|
||||
"filter-cid-all": "All categories",
|
||||
"apply-filters": "Apply Filters",
|
||||
"more-filters": "More Filters",
|
||||
|
||||
"quick-actions": "اجراءات سريعه",
|
||||
"flagged-user": "Flagged User",
|
||||
@@ -43,11 +43,9 @@
|
||||
"notes": "Flag Notes",
|
||||
"add-note": "اضافة ملاحظة",
|
||||
"no-notes": "No shared notes.",
|
||||
"delete-note-confirm": "Are you sure you want to delete this flag note?",
|
||||
"note-added": "Note Added",
|
||||
"note-deleted": "Note Deleted",
|
||||
|
||||
"history": "Account & Flag History",
|
||||
"back": "Back to Flags List",
|
||||
"no-history": "No flag history.",
|
||||
|
||||
"state-all": "All states",
|
||||
@@ -56,18 +54,9 @@
|
||||
"state-resolved": "تم حلها",
|
||||
"state-rejected": "تم رفضها",
|
||||
"no-assignee": "Not Assigned",
|
||||
"note-added": "Note Added",
|
||||
|
||||
"sort": "Sort by",
|
||||
"sort-newest": "Newest first",
|
||||
"sort-oldest": "Oldest first",
|
||||
"sort-reports": "Most reports",
|
||||
"sort-all": "All flag types...",
|
||||
"sort-posts-only": "Posts only...",
|
||||
"sort-downvotes": "Most downvotes",
|
||||
"sort-upvotes": "Most upvotes",
|
||||
"sort-replies": "Most replies",
|
||||
|
||||
"modal-title": "Report Content",
|
||||
"modal-title": "Report Inappropriate Content",
|
||||
"modal-body": "Please specify your reason for flagging %1 %2 for review. Alternatively, use one of the quick report buttons if applicable.",
|
||||
"modal-reason-spam": "Spam",
|
||||
"modal-reason-offensive": "Offensive",
|
||||
@@ -77,9 +66,5 @@
|
||||
"modal-submit-success": "Content has been flagged for moderation.",
|
||||
"modal-submit-confirm": "Confirm Submission",
|
||||
"modal-submit-confirm-text": "You have a custom reason specified already. Are you sure you wish to submit via quick-report?",
|
||||
"modal-submit-confirm-text-help": "Submitting a quick report will overwrite any custom reasons defined.",
|
||||
|
||||
"bulk-actions": "Bulk Actions",
|
||||
"bulk-resolve": "Resolve Flag(s)",
|
||||
"bulk-success": "%1 flags updated"
|
||||
"modal-submit-confirm-text-help": "Submitting a quick report will overwrite any custom reasons defined."
|
||||
}
|
||||
@@ -52,17 +52,14 @@
|
||||
"users": "الأعضاء",
|
||||
"topics": "المواضيع",
|
||||
"posts": "المشاركات",
|
||||
"x-posts": "%1 posts",
|
||||
"best": "الأفضل",
|
||||
"votes": "Votes",
|
||||
"x-votes": "%1 votes",
|
||||
"voters": "Voters",
|
||||
"upvoters": "الموافقين",
|
||||
"upvoted": "مصوت بالموجب",
|
||||
"downvoters": "مصوتين بالسالب",
|
||||
"downvoted": "مصوت بالسالب",
|
||||
"views": "المشاهدات",
|
||||
"posters": "Posters",
|
||||
"reputation": "السمعة",
|
||||
"lastpost": "Last post",
|
||||
"firstpost": "First post",
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
"details.member_count": "عدد اﻷعضاء",
|
||||
"details.creation_date": "تاريخ الإنشاء",
|
||||
"details.description": "الوصف",
|
||||
"details.member-post-cids": "Categories to display posts from",
|
||||
"details.member-post-cids-help": "<strong>Note</strong>: Selecting no categories will assume all categories are included. Use <code>ctrl</code> and <code>shift</code> to select multiple options.",
|
||||
"details.badge_preview": "معاينة الوسام",
|
||||
"details.change_icon": "تغيير الأيقونة",
|
||||
"details.change_label_colour": "Change Label Colour",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"chat.chatting_with": "Chat with",
|
||||
"chat.placeholder": "أكتب رسالة دردشة هنا، اضغط ENTER للإرسال",
|
||||
"chat.scroll-up-alert": "You are looking at older messages, click here to go to most recent message.",
|
||||
"chat.send": "أرسل",
|
||||
"chat.no_active": "لا يوجد لديك دردشات نشطة.",
|
||||
"chat.user_typing": "%1 يكتب رسالة...",
|
||||
@@ -59,7 +58,6 @@
|
||||
"composer.upload-file": "Upload File",
|
||||
"composer.zen_mode": "Zen Mode",
|
||||
"composer.select_category": "Select a category",
|
||||
"composer.textarea.placeholder": "Enter your post content here, drag and drop images",
|
||||
"bootbox.ok": "OK",
|
||||
"bootbox.cancel": "إلغاء",
|
||||
"bootbox.confirm": "تأكيد",
|
||||
|
||||
@@ -43,9 +43,6 @@
|
||||
"new_register_multiple": "There are <strong>%1</strong> registration requests awaiting review.",
|
||||
"flag_assigned_to_you": "تم تخصيص العلامة 1% لك",
|
||||
"post_awaiting_review": "Post awaiting review",
|
||||
"profile-exported": "<strong>%1</strong> profile exported, click to download",
|
||||
"posts-exported": "<strong>%1</strong> posts exported, click to download",
|
||||
"uploads-exported": "<strong>%1</strong> uploads exported, click to download",
|
||||
"email-confirmed": "تم التحقق من عنوان البريد الإلكتروني",
|
||||
"email-confirmed-message": "شكرًا على إثبات صحة عنوان بريدك الإلكتروني. صار حسابك مفعلًا بالكامل.",
|
||||
"email-confirm-error-message": "حدث خطأ أثناء التحقق من عنوان بريدك الإلكتروني. ربما رمز التفعيل خاطئ أو انتهت صلاحيته.",
|
||||
@@ -60,7 +57,6 @@
|
||||
"notificationType_post-edit": "When a post is edited in a topic you are watching",
|
||||
"notificationType_follow": "When someone starts following you",
|
||||
"notificationType_new-chat": "When you receive a chat message",
|
||||
"notificationType_new-group-chat": "When you receive a group chat message",
|
||||
"notificationType_group-invite": "When you receive a group invite",
|
||||
"notificationType_group-request-membership": "When someone requests to join a group you own",
|
||||
"notificationType_new-register": "When someone gets added to registration queue",
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
"agree_to_terms_of_use": "أوافق على شروط الاستخدام",
|
||||
"terms_of_use_error": "يجب عليك الموافقة على شروط الاستخدام",
|
||||
"registration-added-to-queue": "تمت إضافتك في قائمة الإنتضار. ستتلقى رسالة إلكترونية عند الموافقة على تسجيلك من قبل الإدارة.",
|
||||
"registration-queue-average-time": "Our average time for approving memberships is %1 hours %2 minutes.",
|
||||
"registration-queue-auto-approve-time": "Your membership to this forum will be fully activated in up to %1 hours.",
|
||||
"interstitial.intro": "نحتاج إلى بعض المعلومات الإضافية قبل أن نتمكن من إنشاء حسابك.",
|
||||
"interstitial.errors-found": "تعذر علينا إتمام عملية التسجيل:",
|
||||
"gdpr_agree_data": "I consent to the collection and processing of my personal information on this website.",
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
"wrong_reset_code.message": "رمز إعادة التعين غير صحيح، يرجى المحاولة مرة أخرى أو <a href='/reset'>اطلب رمزا جديدا</a>",
|
||||
"new_password": "كلمة المرور الجديدة",
|
||||
"repeat_password": "تأكيد كلمة المرور",
|
||||
"changing_password": "Changing Password",
|
||||
"enter_email": "يرجى إدخال <strong>عنوان البريد الإلكتروني</strong> الخاص بك وسوف نرسل لك رسالة بالبريد الالكتروني مع تعليمات حول كيفية إستعادة حسابك.",
|
||||
"enter_email_address": "ادخل عنوان البريد الإلكتروني",
|
||||
"password_reset_sent": "If the specified address corresponds to an existing user account, a password reset email was sent. Please note that only one email will be sent per minute.",
|
||||
|
||||
@@ -44,6 +44,5 @@
|
||||
"search-preferences-saved": "تم حفظ تفضيلات البحث",
|
||||
"search-preferences-cleared": "تم ازالة تفضيلات البحث",
|
||||
"show-results-as": "عرض النتائج كـ",
|
||||
"see-more-results": "See more results (%1)",
|
||||
"search-in-category": "Search in \"%1\""
|
||||
"see-more-results": "See more results (%1)"
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"topic": "موضوع",
|
||||
"topic_id": "معرف الموضوع",
|
||||
"topic_id_placeholder": "أدخل معرف الموضوع",
|
||||
"no_topics_found": "لا توجد مواضيع !",
|
||||
"no_posts_found": "لا توجد مشاركات!",
|
||||
"post_is_deleted": "هذه المشاركة محذوفة!",
|
||||
@@ -30,16 +32,12 @@
|
||||
"locked": "مقفل",
|
||||
"pinned": "مثبت",
|
||||
"moved": "منقول",
|
||||
"moved-from": "Moved from %1",
|
||||
"copy-ip": "Copy IP",
|
||||
"ban-ip": "Ban IP",
|
||||
"view-history": "Edit History",
|
||||
"bookmark_instructions": "اضغط هنا للعودة لأخر مشاركة مقروءة في الموضوع",
|
||||
"flag-post": "Flag this post",
|
||||
"flag-user": "Flag this user",
|
||||
"already-flagged": "Already Flagged",
|
||||
"view-flag-report": "View Flag Report",
|
||||
"merged_message": "This topic has been merged into <a href=\"%1\">%2</a>",
|
||||
"flag_title": "إشعار بمشاركة مخلة.",
|
||||
"merged_message": "This topic has been merged into <a href=\"/topic/%1\">%2</a>",
|
||||
"deleted_message": "هذه المشاركة محذوفة. فقط من لهم صلاحية الإشراف على ا لمشاركات يمكنهم معاينتها.",
|
||||
"following_topic.message": "ستستلم تنبيها عند كل مشاركة جديدة في هذا الموضوع.",
|
||||
"not_following_topic.message": "You will see this topic in the unread topics list, but you will not receive notifications when somebody posts to this topic.",
|
||||
@@ -80,17 +78,10 @@
|
||||
"thread_tools.purge_confirm": "هل أنت متأكد أنك تريد تطهير هذا الموضوع؟",
|
||||
"thread_tools.merge_topics": "Merge Topics",
|
||||
"thread_tools.merge": "Merge",
|
||||
"topic_move_success": "This topic will be moved to \"%1\" shortly. Click here to undo.",
|
||||
"topic_move_multiple_success": "These topics will be moved to \"%1\" shortly. Click here to undo.",
|
||||
"topic_move_all_success": "All topics will be moved to \"%1\" shortly. Click here to undo.",
|
||||
"topic_move_undone": "Topic move undone",
|
||||
"topic_move_posts_success": "Posts will be moved shortly. Click here to undo.",
|
||||
"topic_move_posts_undone": "Post move undone",
|
||||
"topic_move_success": "تم نقل هذا الموضوع إلى %1 بنجاح",
|
||||
"post_delete_confirm": "هل أنت متأكد أنك تريد حذف هذه المشاركة؟",
|
||||
"post_restore_confirm": "هل أنت متأكد أنك تريد استعادة هذه المشاركة؟",
|
||||
"post_purge_confirm": "هل أنت متأكد أنك تريد تطهير هذه المشاركة؟",
|
||||
"pin-modal-expiry": "Expiration Date",
|
||||
"pin-modal-help": "You can optionally set an expiration date for the pinned topic(s) here. Alternatively, you can leave this field blank to have the topic stay pinned until it is manually unpinned.",
|
||||
"load_categories": "تحميل الفئات",
|
||||
"confirm_move": "انقل",
|
||||
"confirm_fork": "فرع",
|
||||
@@ -105,9 +96,6 @@
|
||||
"fork_topic": "فرع الموضوع",
|
||||
"fork_topic_instruction": "إضغط على المشاركات التي تريد تفريعها",
|
||||
"fork_no_pids": "لم تختر أي مشاركة",
|
||||
"no-posts-selected": "No posts selected!",
|
||||
"x-posts-selected": "%1 post(s) selected",
|
||||
"x-posts-will-be-moved-to-y": "%1 post(s) will be moved to \"%2\"",
|
||||
"fork_pid_count": "1% مشاركة محددة",
|
||||
"fork_success": "تم إنشاء فرع للموضوع بنجاح! إضغط هنا لمعاينة الفرع.",
|
||||
"delete_posts_instruction": "Click the posts you want to delete/purge",
|
||||
@@ -116,7 +104,7 @@
|
||||
"merge-options": "Merge options",
|
||||
"merge-select-main-topic": "Select the main topic",
|
||||
"merge-new-title-for-topic": "New title for topic",
|
||||
"move_posts_instruction": "Click the posts you want to move then go to target topic and click move.",
|
||||
"move_posts_instruction": "Click the posts you want to move",
|
||||
"change_owner_instruction": "Click the posts you want to assign to another user",
|
||||
"composer.title_placeholder": "أدخل عنوان موضوعك هنا...",
|
||||
"composer.handle_placeholder": "Enter your name/handle here",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"banned": "محظور",
|
||||
"offline": "غير متصل",
|
||||
"deleted": "محذوف",
|
||||
"deleted": "Deleted",
|
||||
"username": "إسم المستخدم",
|
||||
"joindate": "تاريخ الإنضمام",
|
||||
"postcount": "عدد المشاركات",
|
||||
@@ -111,7 +111,12 @@
|
||||
"posts_per_page": "الردود في كل صفحة",
|
||||
"max_items_per_page": "أقصى %1",
|
||||
"acp_language": "Admin Page Language",
|
||||
"notifications": "Notifications",
|
||||
"notification_sounds": "تشغيل صوت عند تلقي تنبيه",
|
||||
"notifications_and_sounds": "التنبيهات والأصوات",
|
||||
"incoming-message-sound": "صوت الرسالة الواردة",
|
||||
"outgoing-message-sound": "صوت الرسائل الصادرة",
|
||||
"notification-sound": "صوت التنبيهات",
|
||||
"no-sound": "بدون صوت",
|
||||
"upvote-notif-freq": "معدل تكرار تنبيهات التصويت للأعلى",
|
||||
"upvote-notif-freq.all": "كل التصويتات للأعلى",
|
||||
"upvote-notif-freq.first": "First Per Post",
|
||||
@@ -123,7 +128,6 @@
|
||||
"open_links_in_new_tab": "فتح الروابط الخارجية في نافدة جديدة",
|
||||
"enable_topic_searching": "تفعيل خاصية البحث داخل المواضيع",
|
||||
"topic_search_help": "إذا قمت بتفعيل ميزة البحث في-الموضوع، سيتم تجاوز الخيار الافتراضي للمتصفح مما يؤدي للبحث بكامل الموضوع بدلا عن البحث في الجزء الظاهر في الشاشة.",
|
||||
"update_url_with_post_index": "Update url with post index while browsing topics",
|
||||
"scroll_to_my_post": "بعد اضافة رد على المشاركة, قم بإظهار المشاركة",
|
||||
"follow_topics_you_reply_to": "متابعة المواضيع التي تقوم بالرد عليها",
|
||||
"follow_topics_you_create": "متابعة المواضيع التي تقوم بإنشائها",
|
||||
@@ -175,9 +179,6 @@
|
||||
"consent.right_to_data_portability": "You have the Right to Data Portability",
|
||||
"consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.",
|
||||
"consent.export_profile": "Export Profile (.json)",
|
||||
"consent.export-profile-success": "Exporting profile, you will get a notification when it is complete.",
|
||||
"consent.export_uploads": "Export Uploaded Content (.zip)",
|
||||
"consent.export-uploads-success": "Exporting uploads, you will get a notification when it is complete.",
|
||||
"consent.export_posts": "Export Posts (.csv)",
|
||||
"consent.export-posts-success": "Exporting posts, you will get a notification when it is complete."
|
||||
"consent.export_posts": "Export Posts (.csv)"
|
||||
}
|
||||
@@ -11,7 +11,6 @@
|
||||
"online-only": "المتصلون فقط",
|
||||
"invite": "دعوة",
|
||||
"prompt-email": "Emails:",
|
||||
"groups-to-join": "Groups to be joined when invite is accepted:",
|
||||
"invitation-email-sent": "تم إرسال دعوة بالبريد الإلكتروني إلى %1",
|
||||
"user_list": "قائمة اﻷعضاء",
|
||||
"recent_topics": "أحدث المواضيع",
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
{
|
||||
"post-cache": "Кеш за публикации",
|
||||
"posts-in-cache": "Публикации в кеша",
|
||||
"average-post-size": "Среден обем на публикация",
|
||||
"length-to-max": "Дължина / максимум",
|
||||
"percent-full": "Запълненост: %1%",
|
||||
"post-cache-size": "Размер на кеша за публикации",
|
||||
"items-in-cache": "Елементи в кеша"
|
||||
"items-in-cache": "Елементи в кеша",
|
||||
"control-panel": "Контролен панел",
|
||||
"update-settings": "Обновяване на настройките на кеша"
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 възела отговориха в рамките на %2мсек!",
|
||||
"host": "сървър",
|
||||
"primary": "основен / изпълнение на задачите",
|
||||
"pid": "ид. на процеса",
|
||||
"nodejs": "nodejs",
|
||||
"online": "на линия",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"trending": "Популярни",
|
||||
"installed": "Инсталирани",
|
||||
"active": "Включени",
|
||||
"inactive": "Изключени",
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"num-recent-replies": "Брой на скорошните отговори",
|
||||
"ext-link": "Външна връзка",
|
||||
"is-section": "Използване на тази категория като раздел",
|
||||
"tag-whitelist": "Списък от разрешени етикети",
|
||||
"upload-image": "Качване на изображение",
|
||||
"delete-image": "Премахване",
|
||||
"category-image": "Изображение на категорията",
|
||||
@@ -27,8 +26,6 @@
|
||||
"enable": "Включване",
|
||||
"disable": "Изключване",
|
||||
"edit": "Редактиране",
|
||||
"analytics": "Анализи",
|
||||
"view-category": "Преглед на категорията",
|
||||
|
||||
"select-category": "Изберете категория",
|
||||
"set-parent-category": "Задайте базова категория",
|
||||
@@ -66,6 +63,7 @@
|
||||
"alert.create-success": "Категорията е създадена успешно!",
|
||||
"alert.none-active": "Нямате активни категории.",
|
||||
"alert.create": "Създаване на категория",
|
||||
"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": "Настройките са копирани!",
|
||||
@@ -77,9 +75,7 @@
|
||||
"alert.user-search": "Потърсете потребител тук…",
|
||||
"alert.find-group": "Търсене на група",
|
||||
"alert.group-search": "Потърсете група тук…",
|
||||
"alert.not-enough-whitelisted-tags": "Разрешените етикети са по-малко от минимума. Трябва да създадете още разрешени етикети!",
|
||||
"collapse-all": "Свиване на всички",
|
||||
"expand-all": "Разгъване на всички",
|
||||
"disable-on-create": "Изключване при създаване",
|
||||
"no-matches": "Няма съвпадения"
|
||||
"disable-on-create": "Изключване при създаване"
|
||||
}
|
||||
@@ -8,9 +8,6 @@
|
||||
"hidden": "Скрита",
|
||||
"private": "Частна",
|
||||
"edit": "Редактиране",
|
||||
"delete": "Изтриване",
|
||||
"privileges": "Правомощия",
|
||||
"download-csv": "CSV",
|
||||
"search-placeholder": "Търсене",
|
||||
"create": "Създаване на група",
|
||||
"description-placeholder": "Кратко описание на групата",
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
{
|
||||
"global": "Глобални",
|
||||
"global.no-users": "Няма глобални правомощия за отделни потребители.",
|
||||
"admin": "Администратор",
|
||||
"group-privileges": "Правомощия за групите",
|
||||
"user-privileges": "Правомощия за потребителите",
|
||||
"edit-privileges": "Редактиране на правомощията",
|
||||
"chat": "Разговор",
|
||||
"upload-images": "Качване на изображения",
|
||||
"upload-files": "Качване на файлове",
|
||||
"signature": "Подпис",
|
||||
"ban": "Блокиране",
|
||||
"invite": "Пращане на покана",
|
||||
"search-content": "Търсене на съдържание",
|
||||
"search-users": "Търсене на потребители",
|
||||
"search-tags": "Търсене на етикети",
|
||||
@@ -34,21 +33,10 @@
|
||||
"delete-topics": "Изтриване на теми",
|
||||
"purge": "Изчистване",
|
||||
"moderate": "Модериране",
|
||||
|
||||
"admin-dashboard": "Табло",
|
||||
"admin-categories": "Категории",
|
||||
"admin-privileges": "Правомощия",
|
||||
"admin-users": "Потребители",
|
||||
"admin-settings": "Настройки",
|
||||
|
||||
"alert.confirm-moderate": "<strong>Наистина ли искате да дадете правомощието за модериране на тази потребителска група?</strong> Тази група е публична и всеки може свободно да се присъедини към нея.",
|
||||
"alert.confirm-save": "Моля, потвърдете желанието си да запазите тези правомощия",
|
||||
"alert.saved": "Промените по правомощията са запазени и приложени",
|
||||
"alert.confirm-discard": "Наистина ли искате да отхвърлите промените по правомощията?",
|
||||
"alert.discarded": "Промените по правомощията са отхвърлени",
|
||||
"alert.confirm-copyToAll": "Наистина ли искате да приложите този набор от правомощия към <strong>всички категории</strong>?",
|
||||
"alert.confirm-copyToAllGroup": "Наистина ли искате да приложите набора от правомощия на таи група към <strong>всички категории</strong>?",
|
||||
"alert.confirm-copyToChildren": "Наистина ли искате да приложите този набор от правомощия към <strong>всички по-долни (дъщерни) категории</strong>?",
|
||||
"alert.confirm-copyToChildrenGroup": "Наистина ли искате да приложите набора от правомощия на таи група към <strong>всички по-долни (дъщерни) категории</strong>?",
|
||||
"alert.no-undo": "<em>Това действие е необратимо.</em>",
|
||||
"alert.admin-warning": "Администраторите имат всички правомощия по подразбиране"
|
||||
"admin-settings": "Настройки"
|
||||
}
|
||||
@@ -20,10 +20,16 @@
|
||||
"add-group": "Добавяне на група",
|
||||
"invite": "Покана",
|
||||
"new": "Нов потребител",
|
||||
"filter-by": "Филтриране по",
|
||||
|
||||
"pills.latest": "Последни потребители",
|
||||
"pills.unvalidated": "Няма потвърдена е-поща",
|
||||
"pills.validated": "Потвърдена",
|
||||
"pills.no-posts": "Няма публикации",
|
||||
"pills.top-posters": "С най-много публикации",
|
||||
"pills.top-rep": "С най-много репутация",
|
||||
"pills.inactive": "Недеен",
|
||||
"pills.flagged": "С най-много доклади",
|
||||
"pills.banned": "Блокиран",
|
||||
"pills.search": "Търсене на потребители",
|
||||
|
||||
"50-per-page": "50 на страница",
|
||||
"100-per-page": "100 на страница",
|
||||
@@ -102,5 +108,5 @@
|
||||
|
||||
"alerts.prompt-email": "Е-пощи: ",
|
||||
"alerts.email-sent-to": "Беше изпратено е-писмо за потвърждение до %1",
|
||||
"alerts.x-users-found": "Намерени потребители: %1 (%2 секунди)"
|
||||
"alerts.x-users-found": "Намерени потребители: %1! Търсенето отне %2 милисекунди."
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
"settings/general": "Общи",
|
||||
"settings/homepage": "Начална страница",
|
||||
"settings/navigation": "Навигация",
|
||||
"settings/reputation": "Репутация и доклади",
|
||||
"settings/reputation": "Репутация",
|
||||
"settings/email": "Е-поща",
|
||||
"settings/user": "Потребители",
|
||||
"settings/group": "Групи",
|
||||
@@ -31,7 +31,6 @@
|
||||
"settings/pagination": "Странициране",
|
||||
"settings/tags": "Етикети",
|
||||
"settings/notifications": "Известия",
|
||||
"settings/api": "Достъп чрез ППИ",
|
||||
"settings/sounds": "Звуци",
|
||||
"settings/social": "Обществени",
|
||||
"settings/cookies": "Бисквитки",
|
||||
@@ -71,7 +70,7 @@
|
||||
"logout": "Изход",
|
||||
"view-forum": "Преглед на форума",
|
||||
|
||||
"search.placeholder": "Натиснете „/“ за търсене на настройки",
|
||||
"search.placeholder": "Търсене на настройки",
|
||||
"search.no-results": "Няма резултати…",
|
||||
"search.search-forum": "Търсене във форума за <strong></strong>",
|
||||
"search.keep-typing": "Продължете да пишете, за да видите още резултати…",
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
"maintenance-mode.message": "Съобщение за профилактиката",
|
||||
"headers": "Заглавни части",
|
||||
"headers.allow-from": "Задайте „ALLOW-FROM“, за да поставите NodeBB в „iFrame“",
|
||||
"headers.csp-frame-ancestors": "Задайте заглавката „Content-Security-Policy frame-ancestors“ за да поставите NodeBB „iFrame“",
|
||||
"headers.csp-frame-ancestors-help": "„none“ (нищо), „self“ (себе си – по подразбиране) или списък от позволени адреси.",
|
||||
"headers.powered-by": "Персонализиране на заглавната част „Захранван от“, която се изпраща от NodeBB",
|
||||
"headers.acao": "Произход за разрешаване на управлението на достъпа",
|
||||
"headers.acao-regex": "Регулярен израз за произхода за разрешаване на управлението на достъпа",
|
||||
@@ -32,12 +30,5 @@
|
||||
"sockets.settings": "Настройки за WebSocket",
|
||||
"sockets.max-attempts": "Максимален брой опити за повторно свързване",
|
||||
"sockets.default-placeholder": "По подразбиране: %1",
|
||||
"sockets.delay": "Забавяне при повторно свързване",
|
||||
|
||||
"analytics.settings": "Настройки за анализите",
|
||||
"analytics.max-cache": "Макс. стойност на кеша за анализите",
|
||||
"analytics.max-cache-help": "При инсталации с натоварен трафик, кешът може да бъде изразходен, ако има повече едновременни потребители, от колкото е максималната стойност на кеша. (Изисква рестартиране)",
|
||||
"compression.settings": "Настройки за компресирането",
|
||||
"compression.enable": "Включване на компресирането",
|
||||
"compression.help": "Тази настройка включва компресирането чрез „gzip“. За натоварени уеб сайтове най-добрият начин за използване на компресия е тя да се случва на нивото на обратния сървър-посредник (reverse proxy). Но с цел тестване, можете да го включите и тук."
|
||||
"sockets.delay": "Забавяне при повторно свързване"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"tokens": "Кодове",
|
||||
"settings": "Settings",
|
||||
"lead-text": "На тази страница можете да настроите достъпа до ППИ за писане в NodeBB.",
|
||||
"intro": "По подразбиране ППИ за писане удостоверява потребителите чрез бисквитката им за сесията, но NodeBB поддържа и удостоверяване чрез метода „Bearer“, използвайки кодовете от тази страница.",
|
||||
"docs": "Щракнете тук за достъп до пълната документация на ППИ",
|
||||
|
||||
"require-https": "Require API usage via HTTPS only",
|
||||
"require-https-caveat": "<strong>Note</strong>: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
|
||||
|
||||
"uid": "Потребителски ИД",
|
||||
"uid-help-text": "Посочете потребителски ИД, който да бъде свързан с този код. Ако ИД е <code>0</code>, това ще се счита за <em>главен</em> код, който може да приема идентичността на всеки от другите потребители чрез параметъра <code>_uid</code>",
|
||||
"description": "Описание",
|
||||
"no-description": "Няма описание.",
|
||||
"token-on-save": "Кодът ще бъде създаден след като данните бъдат запазени"
|
||||
}
|
||||
@@ -5,8 +5,7 @@
|
||||
"disable-editing-help": "Това ограничение не засяга администраторите и глобалните модератори",
|
||||
"max-length": "Максимална дължина на съобщенията в разговорите",
|
||||
"max-room-size": "Максимален брой потребители в стая за разговор",
|
||||
"delay": "Време между съобщенията в разговорите (в милисекунди)",
|
||||
"notification-delay": "Забавяне преди известяване за съобщения в разговорите. (0 – без забавяне)",
|
||||
"delay": "Време между съобщеният в разговорите (в милисекунди)",
|
||||
"restrictions.seconds-edit-after": "Брой секунди, през които съобщенията в разговор могат да бъдат редактирани. (0 = изключено)",
|
||||
"restrictions.seconds-delete-after": "Брой секунди, през които съобщенията в разговор могат да бъдат изтривани. (0 = изключено)"
|
||||
}
|
||||
@@ -8,6 +8,5 @@
|
||||
"consent.blank-localised-default": "Оставете това празно, за да използвате данните по подразбиране на NodeBB, които са преведени",
|
||||
"settings": "Настройки",
|
||||
"cookie-domain": "Домейн на бисквитката за сесията",
|
||||
"max-user-sessions": "Максимален брой активни сесии за потребител",
|
||||
"blank-default": "Оставете празно, за да използвате стойността по подразбиране"
|
||||
}
|
||||
@@ -4,6 +4,9 @@
|
||||
"address-help": "Следният адрес на е-поща е този, който получателят ще види в полетата „От“ и “Отговор до“.",
|
||||
"from": "Име за полето „От“",
|
||||
"from-help": "Името на изпращача, което да бъде показано в е-писмото.",
|
||||
"sendmail-rate-limit": "Изпращане на <em>X</em> е-писма…",
|
||||
"sendmail-rate-delta": "…на всеки <em>X</em> милисекунди",
|
||||
"sendmail-rate-help": "Задава на програмата за изпращане на е-писма на NodeBB да ограничи броя едновременно изпращани съобщения, за да не се претоварват пощенските сървъри. Тези настройки не се вземат предвид, ако е включена настройката „Транспорт чрез SMTP“ (по-долу).",
|
||||
|
||||
"smtp-transport": "Транспорт чрез SMTP",
|
||||
"smtp-transport.enabled": "Използване на външен сървър за е-поща за изпращане на е-писма",
|
||||
@@ -22,8 +25,6 @@
|
||||
"smtp-transport.username": "Потребителско име",
|
||||
"smtp-transport.username-help": "<b>За услугата на Gmail</b>, въведете пълния адрес на е-пощата тук, особено ако използвате управляван домейн на „Google Apps“.",
|
||||
"smtp-transport.password": "Парола",
|
||||
"smtp-transport.pool": "Включване на групираните връзки",
|
||||
"smtp-transport.pool-help": "Групирането на връзките предотвратява създаването на нова връзка за всяко е-писмо. Тази настройка има ефект, само ако е включено „Транспорт чрез SMTP“.",
|
||||
|
||||
"template": "Редактирана не шаблона за е-писма",
|
||||
"template.select": "Изберете шаблон за е-писма",
|
||||
@@ -35,7 +36,5 @@
|
||||
"subscriptions": "Резюмета по е-поща",
|
||||
"subscriptions.disable": "Изключване на резюметата по е-пощата",
|
||||
"subscriptions.hour": "Време за разпращане",
|
||||
"subscriptions.hour-help": "Моля, въведете число, представляващо часа, в който да се разпращат е-писма с подготвеното резюме (напр.. <code>0</code> за полунощ, <code>17</code> за 5 следобед). Имайте предвид, че този час е според часовата зона на сървъра и може да не съвпада с часовника на системата Ви.<br /> Приблизителното време на сървъра е: <span id=\"serverTime\"></span><br /> Изпращането на следващия ежедневен бюлетин е планирано за <span id=\"nextDigestTime\"></span>",
|
||||
"notifications.settings": "Настройки за известията по е-поща",
|
||||
"notifications.remove-images": "Премахване на изображенията от известията по е-поща"
|
||||
"subscriptions.hour-help": "Моля, въведете число, представляващо часа, в който да се разпращат е-писма с подготвеното резюме (напр.. <code>0</code> за полунощ, <code>17</code> за 5 следобед). Имайте предвид, че този час е според часовата зона на сървъра и може да не съвпада с часовника на системата Ви.<br /> Приблизителното време на сървъра е: <span id=\"serverTime\"></span><br /> Изпращането на следващия ежедневен бюлетин е планирано за <span id=\"nextDigestTime\"></span>"
|
||||
}
|
||||
@@ -27,12 +27,9 @@
|
||||
"log.alt-text-placeholder": "Алтернативен текст за достъпност",
|
||||
"favicon": "Иконка на уеб сайта",
|
||||
"favicon.upload": "Качване",
|
||||
"pwa": "Прогресивно уеб-приложение",
|
||||
"touch-icon": "Иконка за сензорен екран",
|
||||
"touch-icon": "Иконка за начален екран (мобилно устройство)",
|
||||
"touch-icon.upload": "Качване",
|
||||
"touch-icon.help": "Препоръчителен размер и формат: 512x512, само във формат „PNG“. Ако не е посочена иконка за сензорен екран, NodeBB ще използва иконката на уеб сайта.",
|
||||
"maskable-icon": "Маскируема иконка (за начален екран)",
|
||||
"maskable-icon.help": "Препоръчителен размер и формат: 512x512, само във формат „PNG“. Ако не е посочена маскируема иконка, NodeBB ще използва иконката за сензорен екран.",
|
||||
"touch-icon.help": "Препоръчителен размер и формат: 192x192, само във формат „PNG“. Ако не е посочена иконка за начален екран на мобилно устройство, NodeBB ще използва иконката на уеб сайта.",
|
||||
"outgoing-links": "Изходящи връзки",
|
||||
"outgoing-links.warning-page": "Показване на предупредителна страница при щракване върху външни връзки",
|
||||
"search-default-sort-by": "Подредба по подразбиране при търсене",
|
||||
@@ -41,4 +38,4 @@
|
||||
"theme-color": "Цвят на темата",
|
||||
"background-color": "Фонов цвят",
|
||||
"background-color-help": "Цвят, който да се използва като фон за началния екран, когато уеб сайтът е инсталиран като приложение"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"settings": "Настройки",
|
||||
"handles": "Имена за гостите",
|
||||
"handles.enabled": "Позволяване на имената за гостите",
|
||||
"handles.enabled-help": "Тази възможност предоставя ново поле, което позволява на гостите да си изберат име, което да се използва за всяка публикация, която правят. Ако е изключено, всички те просто ще имат името „Гост“.",
|
||||
"topic-views.enabled": "Гостите да допринасят за броя на преглеждания на темите",
|
||||
"reply-notifications.enabled": "Гостите да могат да предизвикват изпращането на известия за отговорите си"
|
||||
"handles.enabled-help": "Тази възможност предоставя ново поле, което позволява на гостите да си изберат име, което да се използва за всяка публикация, която правят. Ако е изключено, всички те просто ще имат името „Гост“."
|
||||
}
|
||||
@@ -2,5 +2,6 @@
|
||||
"notifications": "Известия",
|
||||
"welcome-notification": "Приветствено известие",
|
||||
"welcome-notification-link": "Връзка за приветственото известие",
|
||||
"welcome-notification-uid": "Потр. ид. за приветственото известие"
|
||||
"welcome-notification-uid": "Потр. ид. за приветственото известие",
|
||||
"notification-alert-timeout": "Време за изчакване преди премахване на уведомяването за известие"
|
||||
}
|
||||
@@ -34,8 +34,6 @@
|
||||
"timestamp.cut-off-help": "Датите и времената ще бъдат показвани относително (напр. „преди 3 часа“ или „преди 5 дни“), и преведени на множество\n\\t\\t\\t\\t\\tезици. След определено време, този текст ще започне да показва самите дата и час, според езика на потребителя\n\\t\\t\\t\\t\\t(напр. „5 ноември 2016 15:30“).<br /><em>(По подразбиране: <code>30</code>, тоест един месец). Ако зададете 0, винаги ще се изписват дати, а ако оставите полето празно, времето ще бъде винаги относително.</em>",
|
||||
"timestamp.necro-threshold": "Мъртва граница (в дни)",
|
||||
"timestamp.necro-threshold-help": "Между публикациите ще бъде показано съобщение, ако времето между тях е по-дълго от мъртвата граница. (По подразбиране: <code>7</code>, или една седмица). Задайте 0 за изключване.</em>",
|
||||
"timestamp.topic-views-interval": "Интервал за увеличаване на броя на преглеждания на темите (в минути)",
|
||||
"timestamp.topic-views-interval-help": "Броят на преглеждания на темите ще се увеличава веднъж на всеки Х минути, според тази настройка.",
|
||||
"teaser": "Представителна публикация",
|
||||
"teaser.last-post": "Последната – Показване на последната публикация, или първоначалната такава, ако няма отговори.",
|
||||
"teaser.last-reply": "Последната – Показване на последния отговор, или „Няма отговори“, ако все още няма такива.",
|
||||
@@ -44,7 +42,6 @@
|
||||
"unread.cutoff": "Възраст на публикациите, след която те не се показват в непрочетените (в брой дни)",
|
||||
"unread.min-track-last": "Минимален брой публикации в темата, след което да започва следене на последно прочетената",
|
||||
"recent": "Настройки за скорошните",
|
||||
"recent.max-topics": "Максимален брой теми в скорошните",
|
||||
"recent.categoryFilter.disable": "Изключване на филтрирането на темите в пренебрегваните категории на страницата /recent",
|
||||
"signature": "Настройки за подписите",
|
||||
"signature.disable": "Забраняване на подписите",
|
||||
|
||||
@@ -5,16 +5,10 @@
|
||||
"votes-are-public": "Всички гласувания са публични",
|
||||
"thresholds": "Ограничения на дейността",
|
||||
"min-rep-downvote": "Минимална репутация, необходима за отрицателно гласуване за публикации",
|
||||
"downvotes-per-day": "Отрицателни гласувания за ден (задайте 0 за неограничен брой)",
|
||||
"downvotes-per-user-per-day": "Отрицателни гласувания за потребител за ден (задайте 0 за неограничен брой)",
|
||||
"min-rep-flag": "Минимална репутация, необходима за докладване на публикации",
|
||||
"min-rep-website": "Минимална репутация, необходима за добавяне на полето „Уебсайт“ към профила на потребителя",
|
||||
"min-rep-aboutme": "Минимална репутация, необходима за добавяне на полето „За мен“ към профила на потребителя",
|
||||
"min-rep-signature": "Минимална репутация, необходима за добавяне на полето „Подпис“ към профила на потребителя",
|
||||
"min-rep-profile-picture": "Минимална репутация, необходима за добавяне на профилна снимка към профила на потребителя",
|
||||
"min-rep-cover-picture": "Минимална репутация, необходима за добавяне на снимка на корицата към профила на потребителя",
|
||||
|
||||
"flags": "Настройки за докладите",
|
||||
"flags.limit-per-target": "Максимален брой докладвания на едно и също нещо",
|
||||
"flags.limit-per-target-placeholder": "По подразбиране: 0"
|
||||
"min-rep-cover-picture": "Минимална репутация, необходима за добавяне на снимка на корицата към профила на потребителя"
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
"allow-account-deletion": "Позволяване на изтриването на профила",
|
||||
"hide-fullname": "Скриване на пълното име от потребителите",
|
||||
"hide-email": "Скриване на е-пощата от потребителите",
|
||||
"show-fullname-as-displayname": "Показване на цялото име на потребителя, ако е налично",
|
||||
"themes": "Теми",
|
||||
"disable-user-skins": "Потребителите да не могат да избират собствен облик",
|
||||
"account-protection": "Защита на акаунта",
|
||||
@@ -44,9 +43,6 @@
|
||||
"registration-type.disabled": "Без регистриране",
|
||||
"registration-type.help": "Обикновена — Потребителите могат да се регистрират от страницата /register.<br/>\nСамо с покана — Потребителите могат да поканят други от страницата с <a href=\"%1/users\" target=\"_blank\">потребителите</a>.<br/>\nСамо с покана от администратор — Само администратори могат да канят други от страницата с <a href=\"%1/users\" target=\"_blank\">потребителите</a> и от страниците за <a href=\"%1/admin/manage/users\">управление на потребителите</a>.<br/>\nБез регистриране — Потребителите не се регистрират.<br/>",
|
||||
"registration-approval-type.help": "Обикновена — Потребителите се регистрират на момента.<br/>\nОдобрена от администратор — Потребителските регистрации се поставят в <a href=\"%1/admin/manage/registration\">опашка за одобрение</a>, която администраторите преглеждат.<br/>\nОдобрена от администратор по IP адрес — Новите потребители се регистрират по обикновения начин, а онези, от чиито IP адрес вече са се регистрирали други акаунти, се нуждаят от одобрението на администратор.<br/>",
|
||||
"registration-queue-auto-approve-time": "Време за автоматично одобрение",
|
||||
"registration-queue-auto-approve-time-help": "Брой часове преди потребител да бъде одобрен автоматично. 0 = изключено.",
|
||||
"registration-queue-show-average-time": "Средното време за одобрение на нов потребител да се показва на потребителите",
|
||||
"registration.max-invites": "Максимален брой покани на потребител",
|
||||
"max-invites": "Максимален брой покани на потребител",
|
||||
"max-invites-help": "0 = няма ограничение. Администраторите могат да разпращат неограничен брой покани.<br>Тази стойност се използва, само ако е избран режимът „Само с покана“.",
|
||||
@@ -66,7 +62,6 @@
|
||||
"restrict-chat": "Разрешаване на съобщенията само от потребители, които следвам",
|
||||
"outgoing-new-tab": "Отваряне на външните връзки в нов подпрозорец",
|
||||
"topic-search": "Включване на търсенето в темите",
|
||||
"update-url-with-post-index": "Обновяване на адресната лента с номера на публикацията по време на разглеждане на темите",
|
||||
"digest-freq": "Абониране за резюмета",
|
||||
"digest-freq.off": "Изключено",
|
||||
"digest-freq.daily": "Ежедневно",
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
"reset.notify.text1": "Известяваме Ви, че на %1, Вашата парола беше променена успешно.",
|
||||
"reset.notify.text2": "Ако не сте поискали това, моля, свържете се незабавно с администратор.",
|
||||
"digest.latest_topics": "Последни теми от %1",
|
||||
"digest.top-topics": "Най-интересните теми от %1",
|
||||
"digest.popular-topics": "Популярни теми от %1",
|
||||
"digest.cta": "Натиснете тук, за да посетите %1",
|
||||
"digest.unsub.info": "Това резюме беше изпратено до Вас поради настройките Ви за абонаментите.",
|
||||
"digest.day": "ден",
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
"invalid-tid": "Грешен идентификатор на тема",
|
||||
"invalid-pid": "Грешен идентификатор на публикация",
|
||||
"invalid-uid": "Грешен идентификатор на потребител",
|
||||
"invalid-date": "Трябва да бъде посочена правилна дата",
|
||||
"invalid-username": "Грешно потребителско име",
|
||||
"invalid-email": "Грешна е-поща",
|
||||
"invalid-fullname": "Грешно пълно име",
|
||||
@@ -27,7 +26,6 @@
|
||||
"invalid-pagination-value": "Грешен номер на странициране, трябва да бъде между %1 и %2",
|
||||
"username-taken": "Потребителското име е заето",
|
||||
"email-taken": "Е-пощата е заета",
|
||||
"email-invited": "На тази е-поща вече е била изпратена покана",
|
||||
"email-not-confirmed": "Няма да можете да публикувате съобщения, докато е-пощата Ви не бъде потвърдена. Моля, натиснете тук, за да потвърдите е-пощата си.",
|
||||
"email-not-confirmed-chat": "Няма да можете да пишете в разговори, докато е-пощата Ви не бъде потвърдена. Моля, натиснете тук, за да потвърдите е-пощата си.",
|
||||
"email-not-confirmed-email-sent": "Вашата е-поща все още не е потвърдена. Моля, проверете входящата си кутия за писмото за потвърждение. Няма да можете да публикувате съобщения или да пишете в разговори, докато е-пощата Ви не бъде потвърдена.",
|
||||
@@ -140,13 +138,8 @@
|
||||
"not-enough-reputation-min-rep-signature": "Нямате достатъчно репутация, за да добавите подпис",
|
||||
"not-enough-reputation-min-rep-profile-picture": "Нямате достатъчно репутация, за да добавите снимка на профила си",
|
||||
"not-enough-reputation-min-rep-cover-picture": "Нямате достатъчно репутация, за да добавите снимка на корицата",
|
||||
"post-already-flagged": "Вече сте докладвали тази публикация",
|
||||
"user-already-flagged": "Вече сте докладвали този потребител",
|
||||
"post-flagged-too-many-times": "Тази публикация вече е докладвана от други хора",
|
||||
"user-flagged-too-many-times": "Този потребител вече е докладван от други хора",
|
||||
"already-flagged": "Вече сте докладвали тази публикация",
|
||||
"self-vote": "Не можете да гласувате за собствената си публикация",
|
||||
"too-many-downvotes-today": "Можете да гласувате отрицателно не повече от %1 пъти на ден",
|
||||
"too-many-downvotes-today-user": "Можете да гласувате отрицателно за потребител не повече от %1 пъти на ден",
|
||||
"reload-failed": "NodeBB срещна проблем при презареждането: „%1“. NodeBB ще продължи да поддържа съществуващите клиентски ресурси, но Вие трябва да отмените последните си действия преди презареждането.",
|
||||
"registration-error": "Грешка при регистрацията",
|
||||
"parse-error": "Нещо се обърка при прочитането на отговора на сървъра",
|
||||
@@ -164,12 +157,10 @@
|
||||
"invalid-session-text": "Изглежда сесията Ви на вписване вече е изтекла или не съответства на сървъра. Моля, опреснете страницата.",
|
||||
"no-topics-selected": "Няма избрани теми!",
|
||||
"cant-move-to-same-topic": "Публикацията не може да бъде преместена в същата тема!",
|
||||
"cant-move-topic-to-same-category": "Темата не може да бъде преместена в същата категория!",
|
||||
"cannot-block-self": "Не можете да блокирате себе си!",
|
||||
"cannot-block-privileged": "Не можете да блокирате администратори и глобални модератори",
|
||||
"cannot-block-guest": "Гостите не могат да блокират други потребители",
|
||||
"already-blocked": "Този потребител вече е блокиран",
|
||||
"already-unblocked": "Този потребител вече е отблокиран",
|
||||
"no-connection": "Изглежда има проблем с връзката Ви с Интернет",
|
||||
"plugin-not-whitelisted": "Добавката не може да бъде инсталирана – само добавки, одобрени от пакетния мениджър на NodeBB могат да бъдат инсталирани чрез ACP"
|
||||
"no-connection": "Изглежда има проблем с връзката Ви с Интернет"
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"state": "Състояние",
|
||||
"reports": "Доклади",
|
||||
"first-reported": "Първо докладване",
|
||||
"reporter": "Докладвал",
|
||||
"reported-at": "Докладвано на",
|
||||
"description": "Описание",
|
||||
"no-flags": "Ура! Няма намерени доклади.",
|
||||
"assignee": "Назначен",
|
||||
"update": "Обновяване",
|
||||
@@ -25,7 +26,6 @@
|
||||
"filter-quick-mine": "Назначени на мен",
|
||||
"filter-cid-all": "Всички категории",
|
||||
"apply-filters": "Прилагане на филтрите",
|
||||
"more-filters": "Още филтри",
|
||||
|
||||
"quick-actions": "Бързи действия",
|
||||
"flagged-user": "Докладван потребител",
|
||||
@@ -43,11 +43,9 @@
|
||||
"notes": "Бележки към доклада",
|
||||
"add-note": "Добавяне на бележка",
|
||||
"no-notes": "Няма споделени бележки.",
|
||||
"delete-note-confirm": "Наистина ли искате да изтриете тази бележка към доклада?",
|
||||
"note-added": "Бележката е добавена",
|
||||
"note-deleted": "Бележката е изтрита",
|
||||
|
||||
"history": "Акаунт и история на докладванията",
|
||||
"back": "Обратно към списъка с доклади",
|
||||
"no-history": "Няма история на доклада.",
|
||||
|
||||
"state-all": "Всички състояния",
|
||||
@@ -56,18 +54,9 @@
|
||||
"state-resolved": "Разрешен",
|
||||
"state-rejected": "Отхвърлен",
|
||||
"no-assignee": "Без назначение",
|
||||
"note-added": "Бележката е добавена",
|
||||
|
||||
"sort": "Подреждане по",
|
||||
"sort-newest": "Първо най-новите",
|
||||
"sort-oldest": "Първо най-старите",
|
||||
"sort-reports": "Първо тези с най-много доклади",
|
||||
"sort-all": "Всички видове доклади…",
|
||||
"sort-posts-only": "Само публикации…",
|
||||
"sort-downvotes": "Най-много отрицателни гласове",
|
||||
"sort-upvotes": "Най-много положителни гласове",
|
||||
"sort-replies": "Най-много отговори",
|
||||
|
||||
"modal-title": "Докладване на съдържанието",
|
||||
"modal-title": "Докладване на неуместно съдържание",
|
||||
"modal-body": "Моля, посочете причината за докладването на %1 %2 за преглед. Или използвайте някой от бутоните за бързо докладване, ако са приложими.",
|
||||
"modal-reason-spam": "Спам",
|
||||
"modal-reason-offensive": "Обидно",
|
||||
@@ -77,9 +66,5 @@
|
||||
"modal-submit-success": "Съдържанието беше докладвано на модераторите.",
|
||||
"modal-submit-confirm": "Потвърждаване на докладването",
|
||||
"modal-submit-confirm-text": "Вече сте описали специалната си причина. Наистина ли искате да изпратите доклада си по бързата процедура?",
|
||||
"modal-submit-confirm-text-help": "Изпращането на доклад по бързата процедура ще премахне описаната от Вас специалната причина.",
|
||||
|
||||
"bulk-actions": "Групови действия",
|
||||
"bulk-resolve": "Разрешаване на доклад(и)",
|
||||
"bulk-success": "%1 доклада са обновени"
|
||||
"modal-submit-confirm-text-help": "Изпращането на доклад по бързата процедура ще премахне описаната от Вас специалната причина."
|
||||
}
|
||||
@@ -52,17 +52,14 @@
|
||||
"users": "Потребители",
|
||||
"topics": "Теми",
|
||||
"posts": "Публ.",
|
||||
"x-posts": "%1 публикации",
|
||||
"best": "Най-добри",
|
||||
"votes": "Гласове",
|
||||
"x-votes": "%1 гласа",
|
||||
"voters": "Гласували",
|
||||
"upvoters": "Гласували положително",
|
||||
"upvoted": "С положителни гласове",
|
||||
"downvoters": "Гласували отрицателно",
|
||||
"downvoted": "С отрицателни гласове",
|
||||
"views": "Прегл.",
|
||||
"posters": "Участници",
|
||||
"reputation": "Репутация",
|
||||
"lastpost": "Последна публикация",
|
||||
"firstpost": "Първа публикация",
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
"details.member_count": "Брой на членовете",
|
||||
"details.creation_date": "Дата на създаване",
|
||||
"details.description": "Описание",
|
||||
"details.member-post-cids": "Категории, от които да се показват публикации",
|
||||
"details.member-post-cids-help": "<strong>Забележка</strong>: Ако не изберете нито една категория, ще се смята, че са включени всички категории. Използвайте <code>CTRL</code> и <code>SHIFT</code>, за да изберете няколко възможности.",
|
||||
"details.badge_preview": "Преглед на емблемата",
|
||||
"details.change_icon": "Промяна на иконката",
|
||||
"details.change_label_colour": "Промяна на цвета на етикета",
|
||||
|
||||